This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned on this page are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
ongoing @mappelman @sguyn @nklick @mkaeppler devops monitor 2023-09-11

Summary

GitLab Observability는 먼저 Cloud Connector를 통해 자체 호스팅된 인스턴스에 제공될 것이며, 이를 통해 자체 호스팅된 사용자는 관측성 플랫폼을 관리할 필요 없이 GitLab Observability의 이점을 누릴 수 있습니다. 이 문서는 아키텍처를 개요합니다.

GitLab Observability를 Cloud Connector를 통해 자체 호스팅된 인스턴스에 제공하는 것 외에도, GitLab.com의 GitLab Observability도 Cloud Connector를 활용하도록 아키텍처가 재조정됩니다.

다음의 아키텍처 개요는 자체 호스팅된 GitLab 인스턴스와 .com GitLab 인스턴스에 적용될 수 있습니다.

Goals

  • 스케일링 가능하고 신뢰할 수 있는 관측성 시스템을 관리할 필요 없이, 자체 호스팅된 사용자들에게 원활한 관측성 기능 제공하기
  • 관측성 API를 GitLab 프로젝트 리소스 API로 이동하기
  • .com과 자체 호스팅된 GitLab 간의 API 일관성 유지하기

Architecture

GitLab Observability Backend (GOB) 배포는 GitLab Inc. 인프라의 일부로 관리될 것입니다. GitLab.com 및 모든 자체 호스팅된 GitLab 인스턴스는 초기에는 현재 존재하는 동일한 GOB 백엔드를 사용할 것입니다. 그러나 향후에는 지역 GOB 인스턴스 또는 필요에 따라 고객별 GOB 인스턴스를 배포하고 원하는 GOB 인스턴스로 요청을 라우팅할 수도 있습니다.

파란색 화살표는 GitLab SaaS 및 GitLab 자체 호스팅된 인스턴스에서 GOB로의 요청 경로를 강조합니다. 모든 요청은 Cloud Connector Gateway 공용 서비스를 통과하여 비공개 GOB 서비스로 전달됩니다. GitLab SaaS 셀은 모두 공용 Cloud Connector Gateway에 액세스할 수 있을 것입니다.

Cloud Connector Gateway는 단일 진입점 로드 밸런서가 될 것입니다.

자세한 요청 아키텍처는 다음 섹션에서 설명됩니다.

Observability Requests Walkthrough

다음 두 다이어그램은 GitLab.com 고객 및 자체 호스팅된 GitLab 고객의 요청 흐름을 강조합니다. 두 경우 모두 약간의 차이가 있습니다:

  1. GitLab.com 요청에서 GOB로 전송된 JWT는 Rails에서 생성되지만, 자체 호스팅된 플로우에서의 JWT 또는 그 외에 IJWT는 CustomersDot에서 생성됩니다.
  2. GitLab.com 플로우에는 CustomersDot JWT 동기화가 없습니다.

GitLab.com에서 제공되는 Observability

sequenceDiagram autonumber participant U as GitLab.com 사용자 participant SDK as OpenTelemetry <br/> SDK/Collector participant .comUI as GitLab.com (UI) participant .comW as GitLab.com (WorkHorse) participant .comR as GitLab.com (Rails) participant GOB as cloud.gitlab.com 뒤의 GOB SaaS <br/>(GitLab Observability Backend) Note over U,GOB: SDK/Collector 구성 U->>.comR: 그룹/프로젝트 PAT 생성 .comR-->>U: PAT U->>SDK: PAT 및 프로젝트 엔드포인트로 구성 Note over U,GOB: OpenTelemetry 데이터 전송 loop SDK/Collector에 의해 발행된 요청 SDK->>.comW: PAT로 opentelemetry 데이터 전송 .comW->>.comR: 본인 확인 핸들러(body 없음) .comR->>.comR: PAT로 본인 확인 .comR-->>.comW: 메타데이터 + JWT .comW->>GOB: JWT 및 메타데이터 헤더로 데이터 전송 GOB->>GOB: JWT 유효성 검사 및 데이터 저장 GOB-->>.comW: 응답 .comW-->>SDK: 응답 end Note over U,GOB: GitLab UI U->>.comUI: 보기 .comUI->>.comW: 쿠키로 요청 .comW->>.comR: 본인 확인 핸들러가 쿠키를 전달 .comR->>.comR: 쿠키로 본인 확인 .comR-->>.comW: 메타데이터 + JWT .comW->>GOB: JWT 및 메타데이터 헤더 전송 GOB->>GOB: JWT 유효성 검사 및 결과 반환 GOB-->>.comW: 응답 .comW-->>.comUI: 응답 Note over U,GOB: API로 직접 접근 U->>.comR: 그룹/프로젝트 PAT 생성 .comR-->>U: PAT U->>.comW: PAT로 요청 .comW->>.comR: 본인 확인 핸들러 .comR->>.comR: PAT로 본인 확인 .comR-->>.comW: 메타데이터 + JWT .comW->>GOB: JWT 및 메타데이터 헤더 전달 GOB->>GOB: JWT 유효성 검사 및 결과 반환 GOB-->>.comW: 응답 .comW-->>U: 응답

Self-Managed GitLab에서 제공하는 Observability

sequenceDiagram autonumber participant U as SM 사용자 participant SDK as OpenTelemetry <br/> SDK/Collector participant SMUI as SM GitLab (UI) participant SMW as SM GitLab (WorkHorse) participant SMR as SM GitLab (Rails) participant CD as CustomersDot participant GOB as GOB SaaS behind cloud.gitlab.com <br/>(GitLab Observability Backend) Note over U,GOB: instance-to-instance auth loop chron job SMR->>CD: sync Cloud Connector access data Note over CD,SMR: Includes instance JWT (IJWT) scoped to eligible services CD-->>SMR: access data + IJWT SMR->>SMR: store access data + IJWT end Note over U,GOB: SDK/Collector 구성 U->>SMR: 그룹/프로젝트 PAT 생성 SMR-->>U: PAT U->>SDK: PAT 및 프로젝트 엔드포인트로 구성 Note over U,GOB: OpenTelemetry 데이터 전송 loop SDK/Collector에 의한 발급된 요청 SDK->>SMW: PAT로 opentelemetry 데이터 전송 SMW->>SMR: 본문 없이 preAuthHandler SMR->>SMR: PAT로 인증 SMR-->>SMW: 메타데이터 + IJWT SMW->>GOB: IJWT 및 메타데이터 헤더로 데이터 전송 GOB->>GOB: IJWT 유효성 검사 및 데이터 저장 GOB-->>SMW: 응답 SMW-->>SDK: 응답 end Note over U,GOB: GitLab UI U->>SMUI: 보기 SMUI->>SMW: 쿠키를 사용하여 요청 SMW->>SMR: 쿠키를 전달하는 preAuthHandler SMR->>SMR: 쿠키로 인증 SMR-->>SMW: 메타데이터 + IJWT SMW->>GOB: IJWT 및 메타데이터 헤더로 전달 GOB->>GOB: IJWT 유효성 검사 GOB-->>SMW: 응답 SMW-->>SMUI: 응답 Note over U,GOB: API로 직접 전송 U->>SMR: 그룹/프로젝트 PAT 생성 SMR-->>U: PAT U->>SMW: PAT로 요청 SMW->>SMR: preAuthHandler SMR->>SMR: PAT로 인증 SMR-->>SMW: 메타데이터 + IJWT SMW->>GOB: IJWT 및 메타데이터 헤더로 전송 GOB->>GOB: IJWT 유효성 검사 GOB-->>SMW: 응답 SMW-->>U: 응답

성능

어떠한 Observability 요청의 본문이 Rails/Puma를 무겁게 만드는 것은 매우 중요합니다. Workhorse의 모든 preAuthHandler는 본문이 Rails로 전달되지 않도록 하고, 인증이 성공하면 GOB로만 전달됨을 보장합니다.

GitLab.com의 Observability에 대한 매일 전송되고 저장된 데이터를 고려하고, 이를 동등하게 요구하는 자체 관리 고객들에 대해 추정한다면, Workhorse와 Cloud Connector를 통해 얼마나 많은 데이터가 전달될지에 대한 감을 잡을 수 있습니다. GitLab.com은 30-60초마다 샘플링된 150M 이상의 메트릭 시리즈와 하루에 18-22TB의 로그를 생성합니다.

GitLab.com 또는 자체 관리 인스턴스에서 Ultimate 티어 루트 레벨 네임스페이스가 동등한 양의 데이터를 cloud.GitLab.com을 통해 전송할 수 있다고 가정할 수 있습니다.

이것이 의미하는 바를 초당 요청수 및 바이트당 초당 양으로 추정하기 위해 다음의 기본적인 예시를 살펴보겠습니다.

가정:

  • 압축: observeability 데이터 유형에 대한 압축 비율을 보여주는 차트를 사용합니다.
  • 예시 메트릭은 396바이트이고, 위에서 링크된 압축 테이블의 md_metric_request에 해당함:
    • {__name__="cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits", cluster="play-db-cluster", container="k6-grpc", instance="10.4.3.6:8080", job="integrations/Kubernetes/kube-state-metrics", namespace="play-backends", node="gke-raintank-dev-pla-raintank-dev-pla-3cd3aafc-hijt", pod="k6-grpc-5c74969fdc-6n2bn", resource="cpu", uid="56e073b7-ca28-4cf4-b3da-83dc97763bef", unit="core"}
  • 추적 볼륨은 로그 볼륨을 쉽게 초과할 수 있는데, 각 span에 로그 라인에서 찾을 수 있는 것과 유사한 context가 첨부됩니다. 추적은 디버그 로깅과 유사하기 때문에 샘플링을 사용하여 전체 볼륨을 합리적인 수준으로 줄입니다. 이 상황에서 추적 볼륨을 샘플링 후 로깅 볼륨과 동일하다고 가정합시다.
  • 압축 비율을 위해 md_log_request, md_trace_request, md_metric_request를 가정합니다.

하나의 큰 Ultimate 티어 조직 (GitLab.com 또는 자체 관리)에 대한 싱글 데이터 처리량:

  • 메트릭 볼륨: 매 30초마다 샘플링된 150M 개의 활성 메트릭 시리즈
    • 초당 샘플 수 = 150M / 30 = 5M
    • 초당 바이트 = 5M * 396B / 2.21 압축 비율 = 896MB/s
  • 로그 볼륨: 하루에 18TB
    • 압축되지 않은 초당 바이트 = 18e+12 / ( 24 x 60 x 60 ) = 208MB/s
    • 압축된 초당 바이트 = 208 / 1.35 압축 비율 = 154Mb/s
  • 추적 볼륨: 위의 가정에 따라, 로그 볼륨과 동일하다고 가정합니다
    • 압축된 초당 바이트 = 208 / 1.57 압축 비율 = 132Mb/s

이러한 것들을 고려하여 Ultimate 티어 고객으로부터 가능한 총 수요가 데이터 흡수를 위해 1.2GB/s일 수 있다고 가정할 수 있습니다. 데이터 흡수 수요는 항상 관측 가능한 데이터를 다시 읽는 것보다 최대 수량 생성되므로 이 나킨 계산의 목적을 위해 읽기 부하는 무시할 수 있습니다.

또한, 1.2GB/s를 전달하는 초당 평균 요청 수를 고려하는 것은 유용합니다. 이를 통해 Rails에 대한 preAuthHandler 요청 수를 추론할 수 있습니다.

OpenTelemetry Batch Processor는 구성 가능한 크기의 일괄 처리로 메트릭, 로그 및 추적을 전송하는 권장 방법입니다. 기본 배치 크기는 8192 이벤트입니다. Opentelemetry 압축 비교의 평균 압축 크기, 메트릭, 로그, 추적 볼륨을 가정한 경우, 기본 배치 크기를 사용하여 평균 초당 요청 수를 계산할 수 있습니다.

  • 메트릭 요청/초:
    • 초당 896MB / 145 압축 바이트 당 이벤트 = 6.2M 이벤트/초
    • 6.2M 이벤트/초 / 8192 이벤트/배치 = 760 요청/초
  • 로그 요청/초:
    • 초당 154MB / 268 압축 바이트 당 이벤트 = 0.57M 이벤트/초
    • 0.57M 이벤트/초 / 8192 이벤트/배치 = 70 요청/초
  • 추적 요청/초:
    • 초당 132MB / 288 압축 바이트 당 이벤트 = 0.46M 이벤트/초
    • 0.46M 이벤트/초 / 8192 이벤트/배치 = 56 요청/초

대규모 고객마다 평균 배치 크기를 사용하여 150M 활성 메트릭 시리즈, 하루 18TB 로그 및 하루 18TB 추적을 가진 경우 매 초 890개의 요청이 발생합니다.

GitLab.com을 위한 Observability

GitLab.com의 이러한 규모를 가진 각 고객에게는 Workhorse를 통해 1.2GB/s의 수요가 있을 것입니다.

성능과 GitLab 서비스 가용성을 극대화하기 위해 최근 코드 제안과 마찬가지로 관측 가능성을 위한 전용 웹 플릿을 생성해야 합니다. .com에 있는 /api/v4/projects/:id/observability/로 시작하는 모든 들어오는 요청 경로는 전용 관측 가능성 웹 플릿으로 라우팅될 수 있습니다. 이를 통해 관측 가능성 요청이 주요 GitLab 웹 플릿을 포화시키는 위험을 완화하고 수요에 따라 관측 가능성 플릿을 수평으로 자동으로 확장할 수 있습니다.

Self-Managed를 위한 Observability

이 정도의 데이터에 대한 Self-Managed Workhorse 처리량은 1.2GB/s가 될 것입니다. Self-Managed 고객은 참조 아키텍처 문서에서 적절한 구성에 액세스할 수 있을 것입니다.

인증 및 권한

요청 흐름에 설명된대로 GOB와의 상호 작용에는 두 가지 주요 요청 레그가 있습니다.

  1. 사용자/클라이언트에서 GitLab 인스턴스로
  2. GitLab 인스턴스에서 GOB로

1 레그 요청에 대해 인증 및 권한 부여는 Workhorse의 preAuthorizeHandler를 활용하여 강제로 적용될 것입니다. 이 handler는 내부 Rails API를 호출하여 제공된 PAT 또는 브라우저 쿠키를 사용하여 authN 및 authZ를 수행합니다. 내부 Rails API는 먼저 Workhorse/Rails JWT와 공유 서명 비밀을 사용하여 요청을 인증하여야 합니다. 성공적인 경우, 엔드포인트는 제공된 PAT/브라우저 쿠키에 대해 적절한 권한 확인을 수행합니다. 성공적인 경우, Rails는 Workhorse로 다시 보내야 하는 모든 GOB에 보내야 하는 헤더를 응답으로 반환할 것입니다. 이때, 이것은 Workhorse/Rails 웹소켓 auth-data와 유사한 방식으로 이뤄집니다.

그런 다음 Workhorse는 이 요청을 GOB로 IJWT(자체 관리) 또는 Workhorse JWT(SaaS)와 함께 전달할 것입니다. 그리고 GOB는 요청을 인증하기 위해 JWT를 검증할 것입니다.

Rails와 Workhorse는 JWT를 서명하기 위해 동일한 비밀을 사용하므로, https://gitlab.com/.well-known/openid-configuration에서 찾을 수 있는 jwks_uri에서 사용 가능한 JWKS를 사용하여 Rails 또는 Workhorse에서 생성된 JWT의 ID를 검증할 수 있습니다. 이는 IJWT의 경우에도 적용되며, 여기에서 IJWT를 검색할 수 있습니다.

활성화

Self-Managed 사용자는 고객 포털을 통해 Cloud Connected GitLab Observability를 활성화할 것입니다. 모든 관련 라이선스 및 구독 정보가 Workhorse, Rails 및 GOB가 액세스 및 제한과 할당량을 관리하는 데 사용할 IJWT에 인코딩될 것입니다.

요율 제한 및 할당량 관리

GitLab Observability Backend에는 거부된 서비스 공격을 방지하기 위해 API 게이트웨이에 이미 요율 제한이 있습니다.

기존의 요율 제한 외에도, 우리는 Workhorse/Rails에 요율 제한을 동일한 방식으로 추가할 것입니다. 이를 통해 edge에서 요율 제한이 강제되어 edge에서의 DOS 공격을 완화하고 하위 서비스를 호출하기 전에 edge에서 DOS 공격을 완화할 수 있습니다.

GitLab Observability 할당량 관리는 GOB에서 강제됩니다. GOB는 고객 라이선스에 따라 각 최상위 네임스페이스에 대한 컴퓨팅 할당량을 구성합니다. 추가로, GOB는 스토리지 할당량을 적절하게 구성함으로써 스토리지를 추적하고 오래된 데이터를 정리하여 새 데이터를 위한 공간을 확보하여 항상 각 최상위 네임스페이스의 상한선 아래에 유지합니다. 최종적으로, 이 할당량 관리는 최상위 네임스페이스 대신 GitLab 조직 구조로 매핑될 것입니다.

GOB 서비스에서 요율 제한 및 할당량 관리가 올바르게 적용되도록 하기 위해 GOB는 IJWT 토큰을 사용하여 고객 라이선스에 대한 관련 정보를 추출할 것입니다. Workhorse에서 GOB로의 요청 레그에서 필요한 모든 추가 정보를 제공하는 메타데이터 헤더도 전송될 것입니다.

API

모든 관측 가능성 API는 Workhorse를 통해 프록시되며 GitLab 프로젝트 리소스 하위에 존재할 것입니다. 초기에는 HTTP를 지원하고 나중에 gRPC가 추가될 것입니다.

시스템 모니터링

GitLab Observability Backend에 이미 GitLab 중앙 집중식 메트릭 및 로깅 시스템에 플러그인 된 시스템 모니터링이 있습니다. 사용자 중심 API의 가시성과 경보를 제공하기 위해 Workhorse와 Rails에서 추가 메트릭도 캡처될 것입니다.