본문 바로가기
WIKI 기술 지식 베이스

카탈로그 그래프 만들기

원문 보기 위키 갱신

카탈로그 그래프 만들기 (Creating the Catalog Graph)

Backstage Software Catalog가 엔티티와 관계로 소프트웨어를 모델링하는 방식을 설명하는 문서예요.

출처: 문서

본문

개요 (Overview)

Backstage의 Software Catalog는 가능한 모든 것을 빠짐없이 나열하는 인벤토리보다는, 엔티티와 그 관계를 사용해 인간의 정신적 모델(mental model)을 포착하는 것을 목표로 해요. 이 엔티티들을 중심으로 기능과 보기를 부착하는 데 초점을 맞춰요. 카탈로그가 끝나고 외부 세계가 시작되는 "경계(edge)"를 결정하는 것은 카탈로그의 범위가 적절하도록 보장하는 데 중요해요.

Backstage 소프트웨어 카탈로그는 소프트웨어 컴포넌트와 서비스를 구성하고 발견하기 위한 중앙 허브 역할을 해요. 이러한 개념들에 대한 높은 수준의 개요를 제공하는 데는 뛰어나지만, 컴포넌트와 서비스 사이의 동적 관계를 실시간으로 추적하기에는 이상적인 솔루션이 아닐 수 있어요. 어노테이션을 통해 그래프의 노드에 적절한 도구를 부착하고, 배포 정보와 기타 실시간 데이터를 표시하는 사용자 지정 프론트엔드 플러그인을 개발하면 실시간 보기를 얻을 수 있어요.

Backstage Software Catalog가 궁극적인 진실의 원천(source of truth)으로 간주되어서는 안 된다는 점을 주목할 필요가 있어요. 대신 Backstage Catalog를 카탈로그 UI와 다른 Backstage 플러그인에 정보를 전달하기 위해 REST API를 활용하는 캐싱 메커니즘으로 사용하는 것이 좋아요. Backstage에서 YAML 파일을 수정할 때는 GitOps 방식을 채택하는 것이 권장되는데, 저장소의 YAML 파일을 주요 진실의 원천으로 취급하고 Scaffolder를 사용해 UI를 통해 변경을 만들고 업데이트된 변경사항으로 저장소에 풀 리퀘스트를 생성하는 방식이에요.

카탈로그 그래프를 구축하는 데 사용되는 디스크립터 컴포넌트

엔티티(Entities): 엔티티는 그래프에서 뚜렷한 객체, 개념, 또는 사물을 나타내는 노드를 가리켜요. 노드는 그래프 데이터베이스의 기본 구성 요소이며 엔티티와 그 속성을 나타내는 데 사용돼요.

Kinds: 관련 엔티티를 그룹화하는 데 사용되는 광범위한 범주예요. Kinds는 "service", "database", "team" 같은 엔티티의 높은 수준 분류를 제공하는 데 사용돼요. Kinds는 카탈로그에서 엔티티를 필터링하는 방법을 제공하고, 관리되고 있는 엔티티 유형에 대한 높은 수준 개요를 제공하는 데 자주 사용돼요.

관계(Relations): 카탈로그의 서로 다른 엔티티 사이의 링크예요. Relations는 의존성이나 소유권 같은 서로 다른 엔티티 사이의 관계를 표현해요. 도입자는 relations를 사용해 사용자가 카탈로그를 탐색하고 서로 다른 엔티티 사이의 관계를 이해하도록 도울 수 있어요.

Spec: 스펙(spec)은 Backstage 카탈로그에서 엔티티의 데이터 구조를 설명하는 스키마예요. 엔티티의 속성, 관계, 데이터 타입, 제약 조건을 정의하고, 데이터의 일관성과 정확성을 보장하며 컴포넌트와 플러그인 간에 데이터를 쉽게 공유하고 소비할 수 있게 해줘요. Spec은 엔티티를 만들거나 확장할 때 유용하며, 데이터를 더 재사용 가능하고 상호 운용 가능하게 만드는 데 도움을 줘요. spec 섹션은 완전히 사용자 지정 가능하며, 사용자는 정보를 렌더링하는 나만의 컴포넌트와 플러그인을 만들 수 있어요.

Types: 주어진 Kind 내에서 엔티티를 분류하는 데 사용되는 더 구체적인 범주예요. Types는 "frontend-service"나 "backend-service" 같은 엔티티의 더 세분화된 분류를 제공해요. Types는 엔티티에 대한 추가 컨텍스트와 정보를 제공하고, 사용자가 더 넓은 시스템 안에서 엔티티의 역할과 기능을 이해하도록 돕는 데 자주 사용돼요.

어노테이션(Annotations): 이 키-값 쌍은 카탈로그의 엔티티에 부착할 수 있어요. 일반적으로 엔티티에 추가 정보나 메타데이터를 더하는 데 사용돼요. 어노테이션은 자동화된 도구나 스크립트가 사용하는 정보를 제공하고, 엔티티를 다루는 사람에게 추가 컨텍스트를 제공하거나 플러그인을 외부 세계로 연결하는 데 자주 사용돼요.

기본 제공 사용 사례 (Use cases out of the box)

카탈로그는 디스크립터를 노드로, relations를 간선(edge)으로 사용해 그래프를 구축해요. 기본적으로 다음과 같은 사용 사례를 얻을 수 있어요.

  • 소유권 추적(Ownership tracking)

  • 인벤토리(Inventory)

  • 검색(Search)

  • 수명주기 추적(Lifecycle tracking)

  • 실시간 정보 소스 추적(Tracking of real-time information sources)

  • 의존성 매핑(Dependency mapping)

  • API 노출(API exposure)

자산 추적하기 (Tracking Assets)

권장하는 접근 방식은 사용자가 스스로 관리할 수 있는 catalog-info 파일에 정보를 나타내는 것이에요. 저장소 내용에 기반한 자동 분류가 유용할 수 있지만, 초기 파일을 생성하는 데만 사용하고 그 후에는 사람이 수동으로 유지 관리하도록 하는 것을 권장해요. 그 이유는 자동화가 때때로 실패할 수 있고, 이 메타데이터의 정확성과 신뢰성을 보장하는 것이 필수적이기 때문이에요. 요컨대, 이 메타데이터를 유지 관리해 그 무결성을 유지해야 하는 것은 사람이에요.

잘 알려진 추적 가능한 자산

컴포넌트(Components)

  • 서비스(Services)

  • 웹사이트(Websites)

  • 라이브러리(Libraries)

  • 데이터 파이프라인(Data Pipelines)

  • 머신러닝 모델(Machine Learning Models)

  • 타사 소프트웨어 컴포넌트: 모든 서드파티 catalog-info 파일에는 별도의 저장소를 두는 것을 권장해요.

  • Jira 설치(Jira installation)

  • Pagerduty

리소스(Resources)

  • 물리적 리소스(Physical resources): 이는 아마도 수명이 더 긴 것(예: 서버)에 더 유용할 거예요.

  • 클라우드 인프라 서비스(Cloud Infrastructure services)

소유권 - 사용자 - 그룹별

  • 사업 부서(Business units)

  • 팀(Team)

  • 제품 영역(Product area)

명명 전략(Naming strategies):

  • Ldap: 내부 LDAP 사용자 이름을 엔티티 이름으로 사용해요. 예: owner: user:my-user 또는 user: my-team-name.

소유권 전략(Ownership strategies):

팀 기반 소유권: 시스템에서 소유권 개념은 팀 중심이에요. 따라서 "owner" 필드는 규정된 규칙 집합에 따라 스쿼드의 LDAP 이름을 참조해야 해요. 소유권이 개인에게 부여되는 경우가 있을 수 있지만, 그러한 이탈은 문제를 만들 수 있어요. 그럴 경우 사용자는 웹 인터페이스를 통해 알림을 받아, 이것이 예외이며 수정이 필요하다는 것을 알 수 있어요. 이 시스템을 준수하도록 보장하려면 모델의 모든 엔티티는 지정된 소유자를 가져야 하며, 가능하면 LDAP 계층 구조 안의 유효한 팀이어야 해요.

기능의 소유권(Ownership of features): 제품 안의 특정 기능과 그 상호관계의 소유권을 추적하려면 두 가지 옵션이 있어요. "feature" 같은 새 컴포넌트 유형을 도입하거나, 완전히 새로운 Kind를 만들거나. 하지만 전자의 방식을 선택해 "feature" 같은 새 유형을 도입하는 것이 덜 복잡하고 위험이 낮아 권장돼요.

LDAP이 조직 구조를 반영하지 않는 경우: Workday 같은 시스템이 진실의 원천이고 사용자 속성에 LDAP이 사용된다면, Backstage만이 아니라 조직 전체가 조회할 수 있는 통합 API를 만들기 위해 다양한 시스템 위에 계층을 개발하는 것이 권장돼요.

API들

  • OpenApi

  • AsyncApi

  • graphQL

  • gRPC

API는 네트워크 서비스나 라이브러리를 나열할 수 있으며, 시스템 사이의 경계를 형성하는 API를 식별하는 데 특히 유용해요. 몇 가지 고려할 점이 있어요.

API 버전: 주요(major) API 버전은 별개의 API로 취급할 수 있으며, 각각에 대해 별도의 엔티티 인스턴스를 만들 수 있어요(예: metadata.name: my-api-v1, metadata.name: my-api-v2). 하지만 이 접근 방식은 부(minor) 또는 패치(patch) 수준 변형에는 권장되지 않아요.

세부 수준(Detail): 지나치게 세분화하는 것은 권장되지 않아요. 현재 형태의 카탈로그가 이를 표현하기에 훌륭한 플랫폼이 아닐 수 있기 때문이에요.

API 간 관계(Relationships between APIs): 아이디어는 API를 노출하는 서비스 컴포넌트를 두고, 다른 API를 소비하는 것은 API가 아니라 컴포넌트라는 것이에요.

프론트엔드용 백엔드 API(BFF): 프론트엔드와 백엔드 서비스에 별도의 컴포넌트를 만드는 것을 권장해요. 프론트엔드 컴포넌트는 "website" 유형이고 백엔드 컴포넌트는 "service" 유형이에요. BFF API는 특정 UI를 위해 맞춤 제작되었고 다른 사람이 사용하도록 의도되지 않았으므로 카탈로그에 포함할 필요가 없기 때문이에요.

API 레지스트리: 조직 내 모든 API를 탐색하는 것은 API 레지스트리의 전형적인 사용 사례예요.

참조 모델 (Reference models)

C4 모델: 영감을 얻으려면 소프트웨어 아키텍처를 시각화하는 패턴을 정의하는 C4 모델을 검토할 수 있어요.

더 알아보기 (Learn more)