분산 추적 개발 지침

GitLab은 분산 추적을 위해 도구를 제공합니다. 현재 GitLab에서의 분산 추적은 실험적으로 간주되며, 아직 GitLab.com에서 대규모로 테스트되지 않았습니다.

Open Tracing에 따르면:

분산 추적 또는 분산 요청 추적은 주로 마이크로서비스 아키텍처를 사용하여 구축된 응용 프로그램을 프로파일링하고 모니터링하는 메서드입니다. 분산 추적은 실패가 발생하는 위치를 정확하게 파악하고 성능 문제의 원인을 찾는 데 도움이 됩니다.

분산 추적은 GitLab 응용 프로그램의 다양한 구성 요소를 통과하는 요청의 수명 주기를 이해하는 데 특히 도움이 됩니다. 현재 Workhorse, Rails, Sidekiq 및 Gitaly에서 추적 기기가 지원됩니다.

분산 추적은 비활성화되어 있을 때 최소한의 오버헤드가 추가되지만, 활성화되어 있을 때에도 오버헤드가 거의 없어 어떠한 환경에서도 사용할 수 있으며, 특히 성능 문제와 같은 프로덕션 문제를 진단하는 데 유용할 수 있습니다.

서비스에는 분산 추적을 지원하는 다양한 수준이 있습니다. 가장 일반적인 라이브러리에 대한 미리 구성된 추적 장치에 추가로 응용 프로그램 계층에 사용자 정의 추적 장치가 추가되어야 합니다.

서비스별 정보는 다음을 참조하세요:

분산 요청을 조사하기 위한 상호 ID 사용

GitLab 응용 프로그램은 요청 내의 다양한 구성 요소 간에 상호 ID를 전달합니다. 상호 ID는 단일 요청에 대해 고유한 토큰으로, 요청이 시스템 내에서 양뱡향으로 전파되는 이벤트를 연관시키는 데 사용됩니다(예: Rails, Workhorse). 로그 출력에 상호 ID가 포함되어 있기 때문에 엔지니어는 상호 ID를 사용하여 시스템을 통해 요청의 종단 간 경로를 이해하고 다른 서브시스템의 로그를 연관시킬 수 있습니다. 요청이 프로세스 경계를 통과할 때, 상호 ID는 외부 요청에 주입됩니다. 이를 통해 상호 ID가 하위 시스템으로 전파됩니다.

일부 사용자 대면형 시스템은 일부 상호 요청(예: SSH를 통한 Git 푸시)에 대해 상호 ID를 생성하지 않습니다.

상호 ID 작업을 위한 개발자 지침

새로운 시스템에 추적을 통합할 때, 개발자는 상호 ID에 대해 특정한 가정을 피해야 합니다. 다음과 같은 지침은 GitLab의 모든 서브시스템에 적용됩니다:

  • 상호 ID는 항상 선택 사항입니다.
    • 추적 기능이 없는 기능이 상위 시스템의 상호 ID에 의존하도록 하면 안 됩니다.
  • 상호 ID는 항상 자유 형식의 텍스트입니다.
    • 상호 ID를 사용하여 컨텍스트(예: 사용자 이름 또는 IP 주소)를 전달해서는 안 됩니다.
    • 상호 ID를 _파싱_하거나 기타 방법으로 조작해서는 안 됩니다(예: 분할).

LabKit library는 Go 프로그래밍 언어에서 GitLab 상호 ID를 사용할 때 표준화된 인터페이스를 제공합니다. LabKit은 상호 추적 및 상호 ID와 함께 작업하는 개발자들을 위한 참조 구현으로 사용할 수 있습니다.

분산 추적 활성화

GitLab은 분산 추적을 구성하기 위해 GITLAB_TRACING 환경 변수를 사용합니다. 같은 구성이 모든 컴포넌트 (예: Workhorse, Rails 등)에 사용됩니다.

GITLAB_TRACING이 설정되지 않으면 응용 프로그램은 추적이 되지 않으며, 따라서 어떠한 오버헤드도 없습니다.

GITLAB_TRACING를 활성화하려면 URL 형식으로 된 유효한 “구성 문자열” 값을 설정해야 합니다:

GITLAB_TRACING=opentracing://<driver>?<param_name>=<param_value>&<param_name_2>=<param_value_2>

이 예에서는 다음과 같은 가상의 값이 있습니다:

  • driver: Jaeger와 같은 드라이버.
  • param_name, param_value: 이들은 드라이버별 구성 값입니다. Jaeger의 구성 매개변수에 대한 내용은 이 문서의 더 자세한 내용에 있으며, URL 인코딩되어야 합니다. 여러 값을 URL처럼 & 문자로 구분해야 합니다.

GitLab Rails은 요청의 상세한 뷰를 제공하는 일반적인 종류의 조작에 대한 미리 구성된 추적 장치를 제공합니다. 그러나 상세한 정보는 비용이 발생합니다. 결과적으로 추적은 길고 처리하기 어려울 수 있으므로, 기본적으로 일부 추적 장치가 비활성화되어 있습니다. 이러한 비활성화된 추적 장치를 활성화하려면 다음과 같은 환경 변수를 설정하세요:

  • GITLAB_TRACING_TRACK_CACHES: 캐시 읽기, 쓰기 또는 삭제와 같은 캐시 조작 추적을 활성화합니다.
  • GITLAB_TRACING_TRACK_REDIS: Redis 조작 추적을 활성화합니다. 대부분의 Redis 조작은 캐싱을 위한 것입니다.

GitLab Development Kit에서 Jaeger 사용

GitLab이 지원하는 첫 번째 추적 구현은 Jaeger이며 GitLab Development Kit은 Jaeger를 사용한 분산 추적을 기본적으로 지원합니다. GDK는 서비스에 GITLAB_TRACING 환경 변수를 자동으로 추가합니다.

gdk.yml 파일을 편집하여 GDK를 Jaeger로 구성하려면 다음 설정을 추가하세요:

tracer:
  build_tags: tracer_static tracer_static_jaeger
  jaeger:
    enabled: true
    listen_address: 127.0.0.1
    version: 1.43.0

gdk.yml 파일을 수정한 후 gdk reconfigure 명령을 실행하여 GDK를 다시 구성하세요. 이렿게 하면 GDK가 올바르게 구성되어 사용할 준비가 됩니다.

위의 구성은 Go로 작성된 서비스를 처음으로 다시 빌드할 때 tracer_statictracer_static_jaeger 빌드 태그를 설정합니다. 이후에 수정한 내용은 이러한 빌드 태그를 사용하여 다시 빌드해야 합니다. 다음 중 하나를 선택할 수 있습니다:

  • 이러한 빌드 태그를 기본 빌드 태그 집합에 추가합니다.
  • 빌드 명령에 수동으로 추가하세요. 예를 들어, Gitaly는 기본적으로 빌드 태그를 추가합니다. make all WITH_BUNDLED_GIT=YesPlease BUILD_TAGS="tracer_static tracer_static_jaeger"를 실행할 수 있습니다.

재구성한 후에는 Jaeger 대시보드를 http://localhost:16686에서 사용할 수 있습니다. 또한 GDK 환경에서 추적에 액세스하는 또 다른 방법은 성능 표를 통해서입니다. 브라우저 창에서 p b를 입력하여 성능 표를 켜면 감지할 수 있습니다.

성능 표를 활성화한 후에는 성능 표에서 Trace를 선택하여 Jaeger UI로 이동할 수 있습니다.

Jaeger 검색 UI는 현재 요청의 Correlation-ID에 대한 쿼리 결과를 반환합니다. 이 검색 결과는 단일 추적 결과를 반환해야 합니다. 이 결과를 선택하면 계층적 시간 경계에 대한 추적의 세부 정보가 표시됩니다.

Jaeger 검색 UI

GitLab 개발자 키 없이 Jaeger 사용하기

분산 추적은 문제 해결을 위해 GDK(GitLab 개발자 키) 개발 환경뿐만 아니라 프로덕션 또는 스테이징 환경에서도 활성화될 수 있습니다. 현재 이 기능은 실험적이며 현재 프로덕션 환경에서는 지원되지 않습니다. 이 첫 번째 릴리스에서는 개발 환경에서만 디버깅에 사용되도록 의도되었습니다.

Jaeger 추적은 다음의 세 가지 단계를 거쳐 활성화될 수 있습니다:

  1. Jaeger 시작.
  2. GITLAB_TRACING 환경 변수 구성.
  3. GitLab 어플리케이션 시작](#3-gitlab-어플리케이션-시작).
  4. 브라우저에서 Jaeger 검색 UI로 이동.

1. Jaeger 시작

Jaeger에는 많은 구성 옵션이 있지만, 추적 저장을 위해 메모리(따라서 비영속적임)를 사용하는 “all-in-one” 모드로 매우 쉽게 시작할 수 있습니다. “all-in-one” 모드의 주요 장점은 사용 편의성입니다.

더 자세한 구성 옵션은 Jaeger 문서를 참조하세요.

Docker 사용

Docker를 사용할 수 있다면 Jaeger all-in-one을 실행하는 더 쉬운 방법은 다음 명령을 사용하여 Docker를 통해 실행하는 것입니다:

$ docker run \
  --rm \
  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411  \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 9411:9411 \
  jaegertracing/all-in-one:latest

Jaeger 프로세스 사용

Docker가 없더라도 all-in-one 프로세스를 쉽게 설정할 수 있습니다.

  1. 플랫폼에 맞는 최신 Jaeger 릴리스를 다운로드하세요.
  2. 아카이브를 추출하고 bin/all-in-one 프로세스를 실행하세요.

이렇게 하면 기본 수신 포트로 프로세스가 시작될 것입니다.

2. GITLAB_TRACING 환경 변수 구성

Jaeger를 실행한 후에는 GITLAB_TRACING 변수를 해당 구성 문자열로 구성하세요.

모든 것을 동일한 호스트에서 실행 중이라면, 다음 값을 사용하세요:

export GITLAB_TRACING="opentracing://jaeger?http_endpoint=http%3A%2F%2Flocalhost%3A14268%2Fapi%2Ftraces&sampler=const&sampler_param=1"

이 구성 문자열은 Jaeger 드라이버 opentracing://jaeger를 사용하여 다음 옵션을 사용합니다:

| 이름 | 값 | 설명 | |——|——-|————-| | http_endpoint | http://localhost:14268/api/traces | Jaeger를 구성하여 http://localhost:14268/에서 실행 중인 HTTP 엔드포인트로 추적 정보를 보내게 합니다. 대안으로 upd_endpoint를 사용할 수도 있습니다. | | sampler | const | Jaeger를 상수 샘플러(사용 또는 미사용 중 하나)를 사용하도록 구성합니다. | | sampler_param | 1 | const 샘플러를 모든 추적에 대해 샘플링하도록 구성합니다. 0을 사용하면 추적을 샘플링하지 않습니다. | 다른 매개변수 값도 가능합니다:

이름 설명
udp_endpoint localhost:6831 이것이 기본값입니다. Jaeger를 UDP 수신기에 compact thrift 프로토콜을 사용하여 포트 6831에서 추적 정보를 보내도록 구성합니다. 이 프로토콜을 사용할 때 Jaeger Client for Ruby에서 일부 문제가 발생했습니다.
sampler probabilistic Jaeger를 확률적 랜덤 샘플러를 사용하도록 구성합니다. 샘플의 비율은 sampler_param 값으로 구성됩니다.
sampler_param 0.01 probabilistic 샘플러를 사용하여 1% 추적을 랜덤으로 샘플링하도록 구성합니다.
service_name api Jaeger 백엔드에서 사용하는 서비스 이름을 재정의합니다. 이 매개변수는 응용프로그램이 제공하는 값보다 우선순위가 높습니다.

참고: 동일한 GITLAB_TRACING 값을 설정해야 모든 GitLab 프로세스, 포함하여 Workhorse, Gitaly, Rails 및 Sidekiq의 환경 변수에서 구성됩니다.

3. GitLab 애플리케이션 시작

GITLAB_TRACING 환경 변수가 모든 GitLab 서비스에 내보내어진 후에 어플리케이션을 시작하세요.

GITLAB_TRACING이 올바르게 구성된 경우 애플리케이션은 시작 시 이를 로깅합니다:

13:41:53 gitlab-workhorse.1      | 2019/02/12 13:41:53 추적이 활성화됨
...
13:41:54 gitaly.1                | 2019/02/12 13:41:54 추적이 활성화됨
...

GITLAB_TRACING이 올바르게 구성되지 않은 경우 다음과 같은 문제가 로깅됩니다:

13:43:45 gitaly.1                | 2019/02/12 13:43:45 추적 구성 단계를 건너뜁니다: 추적기: 드라이버 mytracer를 로드할 수 없음

기본적으로 GitLab에는 Jaeger 추적기가 포함되어 있지만, 컴파일 시 다른 추적기를 포함할 수 있습니다. 이를 수행하는 방법에 대한 자세한 내용은 LabKit 추적 문서에 포함되어 있습니다.

추적에 관한 로그 메시지가 표시되지 않으면, GITLAB_TRACING 환경 변수가 설정되지 않은 것일 수 있습니다.

4. Jaeger 검색 UI 열기

기본적으로 Jaeger 검색 UI는 http://localhost:16686/search에서 이용할 수 있습니다.

참고: Jaeger UI에 나타나기 전에 응용 프로그램을 사용하여 추적을 생성해야 한다는 점을 잊지 마세요.