Gitaly 클러스터 문제 해결

Tier: Free, Premium, Ultimate Offering: Self-Managed

Gitaly 클러스터 (Praefect) 문제 해결 시 아래 정보를 참조하십시오. Gitaly 문제 해결에 대한 자세한 내용은 Gitaly 문제 해결을 참조하십시오.

클러스터 상태 확인

check Praefect 하위 명령은 Gitaly 클러스터의 상태를 확인하기 위해 일련의 확인 항목을 실행합니다.

gitlab-ctl praefect check

다음 섹션에서 실행되는 확인 항목에 대해 설명합니다.

Praefect 마이그레이션

Praefect가 올바르게 작동하려면 데이터베이스 마이그레이션이 최신 상태여야 하므로 Praefect 마이그레이션이 최신 상태인지 확인합니다.

이 확인이 실패하는 경우:

  1. 데이터베이스의 schema_migrations 테이블에서 실행된 마이그레이션을 확인하십시오.
  2. 마이그레이션을 최신 상태로 가져오려면 praefect sql-migrate을 실행하십시오.

노드 연결 및 디스크 액세스

Praefect가 모든 Gitaly 노드에 연결할 수 있는지, 각 Gitaly 노드가 모든 리포지터리에 대해 읽기 및 쓰기 액세스를 가지고 있는지 확인합니다.

이 확인이 실패하는 경우:

  1. 네트워크 주소 및 토큰이 올바르게 설정되었는지 확인하십시오:
    • Praefect 구성에서
    • 각 Gitaly 노드의 구성에서
  2. Gitaly 노드에서 실행 중인 gitaly 프로세스가 git으로 실행되는지 확인하십시오. 리포지터리 디렉터리에 액세스하지 못하는 권한 문제가 있을 수 있습니다.
  3. Praefect를 Gitaly 노드에 연결하는 네트워크에 문제가 없는지 확인하십시오.

데이터베이스 읽기 및 쓰기 액세스

Praefect가 데이터베이스를 읽고 쓸 수 있는지 확인합니다.

이 확인이 실패하는 경우:

  1. Praefect 데이터베이스가 복구 모드에 있는지 확인하십시오. 복구 모드에서는 테이블을 읽기 전용으로 설정할 수 있습니다. 확인하려면 다음을 실행하십시오:

    select pg_is_in_recovery()
    
  2. PostgreSQL에 연결하는 데 사용하는 사용자가 데이터베이스에 대해 읽기 및 쓰기 액세스 권한이 있는지 확인하십시오.
  3. 데이터베이스가 읽기 전용 모드에 설정되었는지 확인하십시오. 확인하려면 다음을 실행하십시오:

    show default_transaction_read_only
    

액세스할 수 없는 리포지터리

기본 할당이 없거나 기본이 사용할 수 없어 액세스할 수 없는 리포지터리의 수를 확인합니다.

이 확인이 실패하는 경우:

  1. Gitaly 노드가 다운되었는지 확인하십시오. 확인하려면 praefect ping-nodes를 실행하십시오.
  2. Praefect 데이터베이스에 부하가 있는지 확인하십시오. Praefect 데이터베이스가 응답이 느릴 경우, 건강 확인이 데이터베이스에 지속적으로 실패하여 Praefect가 노드가 비정상적이라고 판단합니다.

시계 동기화 확인

Praefect와 Gitaly 서버 간의 인증에는 서버 시간이 동기화되어야 합니다.

이 확인은 permission denied 오류의 원인을 식별하는데 도움이 됩니다.

공용 pool.ntp.org 서버에 액세스할 수 없는 오프라인 환경에서는 Praefect check 하위 명령이 다음과 유사한 오류 메시지와 함께이 확인을 실패합니다.

checking with NTP service at  and allowed clock drift 60000ms [correlation_id: <XXX>]
Failed (fatal) error: gitaly node at tcp://[gitlab.example-instance.com]:8075: rpc error: code = DeadlineExceeded desc = context deadline exceeded

이 문제를 해결하려면 모든 Praefect 서버에 환경 변수를 설정하여 접근 가능한 내부 NTP 서버를 가리키도록하십시오. 예:

export NTP_HOST=ntp.example.com

로그의 Praefect 오류

오류를 받은 경우 /var/log/gitlab/gitlab-rails/production.log를 확인하십시오.

일반적인 오류와 가능한 원인은 다음과 같습니다:

  • 500 응답 코드
    • ActionView::Template::Error (7:permission denied)
      • GitLab 서버에서 praefect['configuration'][:auth][:token]gitlab_rails['gitaly_token']이 일치하지 않습니다.
      • Sidekiq 서버에서 git_data_dirs 저장 구성이 누락되었습니다.
    • Unable to save project. Error: 7:permission denied
      • GitLab 서버의 praefect['configuration'][:virtual_storage]에있는 시크릿 토큰이 하나 이상의 Gitaly 서버의 gitaly['auth_token'] 값과 일치하지 않습니다.
  • 503 응답 코드
    • GRPC::Unavailable (14:failed to connect to all addresses)
      • GitLab이 Praefect에 연결하지 못했습니다.
    • GRPC::Unavailable (14:all SubCons are in TransientFailure...)
      • Praefect가 하나 이상의 하위 Gitaly 노드에 연결할 수 없습니다. 진단을 위해 Praefect 연결 확인기를 실행해 보십시오.

Praefect 데이터베이스 CPU 부하

Praefect 데이터베이스가 고부하를 경험하는 일반적인 이유는 다음과 같습니다:

  • Prometheus 메트릭 스크랩 비용이 많이 드는 쿼리를 실행합니다. praefect['configuration'][:prometheus_exclude_database_from_default_metrics] = truegitlab.rb에 설정하십시오.
  • 읽기 분산 캐싱이 비활성화되어 사용자 트래픽이 많을 때 데이터베이스에 대한 쿼리 수가 증가합니다. 읽기 분산 캐싱이 활성화되어 있는지 확인하십시오.

기본 Gitaly 노드 결정

리포지터리의 기본 노드를 확인하려면 praefect metadata 하위 명령을 사용하십시오.

리포지터리 메타데이터 보기

Gitaly 클러스터는 클러스터에 저장된 리포지터리에 대한 메타데이터 데이터베이스를 유지합니다. praefect metadata 하위 명령을 사용하여 문제 해결을 위해 메타데이터를 검사합니다.

Praefect가 할당한 리포지터리 ID로 리포지터리의 메타데이터를 검색할 수 있습니다:

sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -repository-id <repository-id>

물리적 리포지터리의 물리적 경로가 @cluster로 시작하는 경우 물리적 경로에서 리포지터리 ID를 찾을 수 있습니다.

또한 가상 리포지터리와 상대 경로로 리포지터리의 메타데이터를 검색할 수 있습니다:

sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -virtual-storage <virtual-storage> -relative-path <relative-path>

예제

Praefect가 할당한 리포지터리 ID가 1인 리포지터리의 메타데이터를 검색하려면:

sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -repository-id 1

가상 리포지터리가 default이고 상대 경로가 @hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git인 리포지터리의 메타데이터를 검색하려면:

sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml metadata -virtual-storage default -relative-path @hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git

이 두 예제 중 하나로 다음 예제의 예상 리포지터리에 대한 메타데이터를 검색할 수 있습니다:

리포지터리 ID: 54771
가상 리포지터리: "default"
상대 경로: "@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git"
복제 경로: "@hashed/b1/7e/b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9.git"
기본: "gitaly-1"
세대: 1
복제본:
- 리포지터리: "gitaly-1"
  할당됨: true
  세대: 1, 완전히 최신 상태
  건강 상태: true
  유효 기본: true
  확인 날짜: 2021-04-01 10:04:20 +0000 UTC
- 리포지터리: "gitaly-2"
  할당됨: true
  세대: 0, 1개의 변경 뒤쳐짐
  건강 상태: true
  유효 기본: false
  확인 날짜: 확인되지 않음
- 리포지터리: "gitaly-3"
  할당됨: true
  세대: 아직 복제본이 생성되지 않음
  건강 상태: false
  유효 기본: false
  확인 날짜: 확인되지 않음

사용 가능한 메타데이터

praefect metadata에 의해 검색된 메타데이터에는 다음 표의 필드가 포함됩니다.

Field Description
Repository ID Praefect에 의해 리포지터리에 할당된 영구 고유 ID. GitLab이 리포지터리에 사용하는 ID와 다릅니다.
Virtual Storage 리포지터리가 저장된 가상 리포지터리의 이름.
Relative Path 가상 리포지터리 내 리포지터리의 경로.
Replica Path 리포지터리의 복제본이 저장된 Gitaly 노드 디스크 상의 위치.
Primary 리포지터리의 현재 주 복제본.
Generation Praefect가 리포지터리의 변경을 추적하는 데 사용됩니다. 리포지터리의 각 쓰기 작업마다 리포지터리의 세대가 증가합니다.
Replicas 존재하거나 존재할 것으로 예상되는 복제본의 디렉터리.

각 복제본에 대해 다음 메타데이터를 사용할 수 있습니다.

Replicas Field Description
Storage 복제본을 포함하는 Gitaly 리포지터리의 이름.
Assigned 복제본이 리포지터리의 복제 요소가 줄어든 후 추가 복사본이 리포지터리에 있을 경우 또는 Gitaly 노드가 클러스터에서 제거된 경우 false가 될 수 있습니다.
Generation 복제본의 최신 확인된 세대. 다음을 나타냅니다:

- 복제본의 세대가 리포지터리의 세대와 일치하는 경우 복제본이 완전히 최신 상태입니다.
- 복제본의 세대가 리포지터리의 세대보다 작은 경우 복제본이 오래된 상태입니다.
- 복제본이 리포지터리에 아직 전혀 존재하지 않으면 replica not yet created가 표시됩니다.
Healthy 이 복제본을 호스팅하는 Gitaly 노드가 Praefect 노드의 합의에 의해 건강 상태로 간주되는지 여부를 나타냅니다.
Valid Primary 복제본이 주 복제본으로서 적합한지 여부를 나타냅니다. 리포지터리의 주 복제본이 적합한 주 복제본이 아닌 경우, 다른 복제본이 적합한 주 복제본인 경우 리포지터리에 다음 쓰기가 발생하면 장애 조치가 발생합니다. 복제본이 적합한 주 복제본인 경우 다음 조건을 충족합니다:

- 건강한 Gitaly 노드에 저장되어 있음.
- 완전히 최신 상태임.
- 복제 요소가 감소하는 삭제 작업의 대상이 아님.
- 지정됨.
Verified At 검증 워커에 의해 복제본의 마지막 성공적인 검증을 나타냅니다. 만약 복제본이 아직 검증되지 않았다면, 성공적인 검증 시간 대신에 unverified가 표시됩니다. GitLab 15.0에서 도입되었습니다.

‘리포지터리를 찾을 수 없음’ 오류로 인한 명령 실패

만일 -virtual-storage에 제공된 값이 잘못된 경우, 명령은 다음과 같은 오류를 반환합니다:

get metadata: rpc error: code = NotFound desc = repository not found

문서화된 예시에서는 -virtual-storage default를 지정합니다. /etc/gitlab/gitlab.rb의 Praefect 서버 설정 praefect['configuration'][:virtual_storage]을 확인하세요.

리포지터리가 동기화되었는지 확인

각 경우에 따라 Praefect 데이터베이스가 기본 Gitaly 노드와 동기화되지 않을 수 있습니다. 특정 리포지터리가 모든 노드에서 완전히 동기화되었는지 확인하려면 Rails 노드에서 gitlab:praefect:replicas 레이크 태스크를 실행하세요. 이 레이크 태스크는 모든 Gitaly 노드에서 리포지터리를 체크섬합니다.

Praefect dataloss 명령은 Praefect 데이터베이스에서 리포지터리의 상태를 확인하며, 이러한 시나리오에서 동기화 문제를 감지하는 데 의존할 수 없습니다.

‘Relation does not exist’ 오류

기본적으로 Praefect 데이터베이스 테이블은 gitlab-ctl reconfigure 태스크에 의해 자동으로 생성됩니다.

그러나 초기 reconfigure시 Praefect 데이터베이스 테이블이 생성되지 않을 수 있으며, 다음 중 하나의 경우 relations do not exist 오류가 발생할 수 있습니다:

  • gitlab-ctl reconfigure 명령이 실행되지 않은 경우.
  • 실행 중에 오류가 발생한 경우.

예를 들면:

  • ERROR: relation "node_status" does not exist at character 13
  • ERROR: relation "replication_queue_lock" does not exist at character 40
  • 이 오류:

    {"level":"error","msg":"Error updating node: pq: relation \"node_status\" does not exist","pid":210882,"praefectName":"gitlab1x4m:0.0.0.0:2305","time":"2021-04-01T19:26:19.473Z","virtual_storage":"praefect-cluster-1"}
    

이를 해결하기 위해 praefect 명령의 sql-migrate 하위 명령을 사용하여 데이터베이스 스키마 마이그레이션을 수행할 수 있습니다:

$ sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate
praefect sql-migrate: OK (applied 21 migrations)

‘repository scoped: invalid Repository’ 오류로 인한 요청 실패

이는 Praefect 구성에 사용된 가상 리포지터리 이름이 GitLab의 gitaly['configuration'][:storage][<index>][:name] setting에서 사용된 리포지터리 이름과 일치하지 않을 때 발생합니다.

Praefect와 GitLab 구성에서 사용된 가상 리포지터리 이름을 일치시켜 문제를 해결하세요.

클라우드 플랫폼에서의 Gitaly 클러스터 성능 이슈

Praefect는 많은 CPU나 메모리를 필요로하지 않으며, 소형 가상 머신에서 실행될 수 있습니다. 클라우드 서비스는 디스크 IO 및 네트워크 트래픽과 같은 소형 VM이 사용할 수 있는 리소스에 대한 제한을 할 수 있습니다.

Praefect 노드는 많은 네트워크 트래픽을 생성합니다. 클라우드 서비스에서 네트워크 대역폭이 제한되었을 경우 다음과 같은 증상이 나타날 수 있습니다:

  • Git 작업의 성능이 저하됨.
  • 네트워크 대기 시간이 높음.
  • Praefect가 많은 메모리를 사용함.

가능한 해결책:

  • 더 큰 VM을 프로비저닝하여 더 큰 네트워크 트래픽 할당량에 액세스하세요.
  • Praefect 노드가 트래픽 할당량을 소진하고 있는지를 확인하기 위해 클라우드 서비스의 모니터링 및 로깅을 사용하세요.

‘gitlab-ctl reconfigure’가 ‘STDOUT: praefect: configuration error: error reading config file: toml: cannot store TOML string into a Go int’ 오류로 실패

이 오류는 praefect['database_port'] 또는 praefect['database_direct_port']가 정수 대신 문자열로 구성된 경우 발생합니다.