LabHub
배우기 러닝패스 코스

CBA — Backstage認定アソシエイト

エンティティと関係 — 所有権がカタログの心臓である理由

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

카탈로그는 서비스 목록이 아니라 관계 그래프 입니다. 엔티티 종류를 외우는 것보다, 각 종류가 어떤 질문에 답하기 위해 존재하는지를 이해하는 편이 시험과 실무 모두에 유용합니다.

概念マップ: 관계 그래프・의존 관계・소유권・묶음(System/Domain)

왜 이게 필요했나

"서비스 목록"만 있으면 이런 질문에 답할 수 없습니다.

그래서 Backstage 는 엔티티를 여러 종류로 나누고 그 사이의 관계를 저장합니다.

어떻게 동작하나

엔티티 여덟 종류

kind 답하는 질문 대표 필드
Component 우리가 만들고 배포하는 소프트웨어 조각 spec.type(service/website/library), spec.lifecycle, spec.owner, spec.system
API 컴포넌트가 노출하거나 소비하는 인터페이스 spec.type(openapi/asyncapi/graphql/grpc), spec.definition
Resource 컴포넌트가 필요로 하는 인프라 spec.type(database/s3-bucket/queue)
System 함께 동작하는 엔티티들의 묶음 spec.owner, spec.domain
Domain 여러 시스템을 아우르는 사업 영역 spec.owner
Group 팀·조직 단위 spec.type(team), spec.children, spec.profile
User 사람 spec.memberOf
Location 다른 엔티티가 있는 위치를 가리키는 표지판 spec.type, spec.targets

여기에 Template(스캐폴더용)이 더해집니다. 그리고 spec.lifecycle 은 자유 문자열이지만 관례적으로 experimental / production / deprecated 를 씁니다 — 폐기 예정 서비스를 목록에서 걸러 내는 데 쓰입니다.

관계(relations)는 계산되는 것이다

중요한 포인트입니다. catalog-info.yaml 에 쓰는 것은 spec.owner, spec.system, spec.providesApis 같은 선언 이고, 카탈로그가 이를 읽어 양방향 관계 를 계산해 저장합니다.

spec.owner: group:team-checkout      →  ownedBy / ownerOf
spec.system: commerce                →  partOf / hasPart
spec.providesApis: [checkout-api]    →  providesApi / apiProvidedBy
spec.consumesApis: [payments-api]    →  consumesApi / apiConsumedBy
spec.dependsOn: [resource:checkout-db] →  dependsOn / dependencyOf

그래서 providesApis 를 한쪽에만 써도 API 엔티티 페이지에서 "이 API 를 제공하는 컴포넌트"가 보입니다. 반대 방향을 손으로 쓸 필요가 없습니다. 시험에서 "관계를 양쪽 파일에 모두 적어야 하는가?" 를 물으면 답은 아니오입니다.

엔티티 참조 형식

관계를 쓸 때 다른 엔티티를 가리키는 문자열 형식이 정해져 있습니다.

[<kind>:][<namespace>/]<name>

세 부분 중 kind 와 namespace 는 생략 가능하고, 생략하면 문맥에 따른 기본값이 적용됩니다. namespace 의 기본값은 default 입니다.

쓴 것 해석
team-checkout 문맥의 기본 kind + default 네임스페이스
group:team-checkout group:default/team-checkout
group:payments/team-checkout 네임스페이스까지 명시

spec.owner 같은 필드는 기본 kind 가 정해져 있어 team-checkout 만 써도 동작하지만, 명시적으로 group: 을 붙이는 편이 리뷰에서 훨씬 안전합니다. 사람이 읽을 때 그것이 팀인지 개인인지 바로 보이기 때문입니다.

왜 catalog-info.yaml 은 코드 옆에 사는가

카탈로그를 채우는 방식은 세 가지입니다.

  1. 정적 등록 — Backstage 설정 파일에 URL 목록을 적는다. 소규모에는 되지만 늘어나면 관리 불가.
  2. Location 엔티티 — 표지판 엔티티가 다른 파일들을 가리킨다. 계층적으로 묶을 때 유용.
  3. 디스커버리(discovery) — 조직의 저장소를 훑어 catalog-info.yaml 을 찾아 자동 등록. 실무의 정답.

3 번이 성립하려면 파일이 코드와 같은 저장소 에 있어야 합니다. 이 배치가 만드는 효과가 큽니다.

반대로 카탈로그를 중앙 저장소 한 곳에 몰아 두면, 그 파일을 고칠 동기가 있는 사람이 아무도 없어집니다. 카탈로그가 썩는 가장 흔한 경로입니다.

소유권이 심장인 이유

카탈로그에서 딱 하나만 정확해야 한다면 그것은 소유자 입니다.

그래서 소유자는 사람(User)이 아니라 팀(Group) 이어야 합니다. 사람은 퇴사하고 팀은 인수됩니다. 시험에서 자주 나오는 지점이고, 실무에서 카탈로그가 무너지는 첫 번째 원인이기도 합니다.

현장에서 만나는 모습

저자의 홈랩에서 쿠버네티스 워크로드에 app.kubernetes.io/name, app.kubernetes.io/part-of 같은 표준 라벨을 붙이는 습관이 이 카탈로그 사고와 정확히 같은 것입니다. Helm 차트 모범 사례에서도 app.kubernetes.io/name, instance, version, component, part-of, managed-by 여섯 개를 표준으로 붙이라고 권합니다.

같은 소유권·소속 정보를 클러스터 라벨과 카탈로그 엔티티 두 곳에 일관되게 표현 하는 것이 실무의 모습입니다. 그리고 이 둘을 연결해 주는 것이 Backstage 의 Kubernetes 플러그인입니다 — 엔티티에 애너테이션 backstage.io/kubernetes-id 를 달아 두면, 그 값과 같은 라벨을 가진 워크로드를 클러스터에서 찾아 엔티티 페이지에 보여 줍니다.

홈랩 GPU 노드에 붙인 gpu.homelab/tier=xlarge 같은 의미 기반 라벨도 같은 정신입니다. 물리적 사실을 사람이 결정에 쓸 수 있는 어휘로 번역하는 것 — 카탈로그가 시스템·도메인으로 서비스를 묶는 이유와 다르지 않습니다.

다음 실습에서 할 것

/root/cba-catalog/ 에 Component, API, Resource, System, Domain, Group, User, Location 엔티티 파일을 직접 작성합니다. 그다음 같은 소유권 정보를 실제 클러스터의 라벨로 표현해 kubectl 로 확인하고, 마지막에 모든 엔티티의 참조 문자열을 정규화된 형식으로 뽑아 봅니다.