Gitaly 클러스터의 문제 해결

Tier: 무료, 프리미엄, 얼티메이트 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. Praefect가 PostgreSQL에 연결하는 사용자가 데이터베이스에 대해 읽기 및 쓰기 액세스 권한을 가졌는지 확인합니다.
  3. 데이터베이스가 읽기 전용 모드로 설정되어 있는지 확인합니다. 확인하려면 다음을 실행합니다:

    show default_transaction_read_only
    

액세스할 수 없는 저장소

기본 할당이 없거나 기본이 사용 불가능한 저장소로 인해 액세스할 수 없는 저장소의 수를 확인합니다.

이 검사가 실패하는 경우:

  1. Gitaly 노드 중지 상태를 확인합니다. 확인하려면 praefect ping-nodes를 실행합니다.
  2. 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']이 일치하지 않습니다.
    • 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 데이터베이스가 높은 CPU 사용률을 겪는 일반적인 이유는 다음과 같습니다:

  • Prometheus 메트릭 스크랩이 비용이 많이 드는 쿼리를 실행합니다. GitLab 14.2 이상인 경우, gitlab.rb에서 praefect['configuration'][:prometheus_exclude_database_from_default_metrics] = true를 설정하세요.
  • Read 분산 캐싱이 비활성화되어 있으면, 사용자 트래픽이 많을 때 데이터베이스로의 쿼리 수가 증가합니다. Read 분산 캐싱이 활성화되어 있는지 확인하세요.

기본 Gitaly 노드 확인

저장소의 기본 노드를 확인하려면 다음을 수행하세요:

  • GitLab 14.6 이상인 경우, praefect metadata 하위 명령어를 사용합니다.
  • GitLab 13.12에서 GitLab 14.5까지 저장소별 기본 노드를 사용하는 경우, gitlab:praefect:replicas Rake 작업을 사용합니다.
  • GitLab 13.12 이하에서는 레거시 선거 전략에 따라 모든 저장소에 대해 기본이 동일했습니다. 특정 가상 저장소에 대한 현재 기본 Gitaly 노드를 확인하려면 다음을 수행하세요:

    • (권장) Gitlab Omnibus - Praefect 대시보드Shard Primary Election Grafana 차트를 사용합니다.
    • Grafana를 설정하지 않은 경우, 각 Praefect 노드의 각 호스트에서 다음 명령을 사용합니다:

      curl localhost:9652/metrics | grep gitaly_praefect_primaries
      

저장소 메타데이터 보기

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로 검색된 메타데이터에는 다음 테이블의 필드가 포함됩니다.

필드 설명
Repository ID Praefect가 리포지토리에 할당한 영구 고유 ID. GitLab이 리포지토리에 사용하는 ID와는 다릅니다.
Virtual Storage 리포지토리가 저장된 가상 스토리지의 이름입니다.
Relative Path 가상 스토리지 내의 리포지토리 경로입니다.
Replica Path Gitaly 노드의 디스크에 리포지토리 복제본이 저장된 경로입니다.
Primary 리포지토리의 현재 프라이머리입니다.
Generation Praefect가 리포지토리 변경을 추적하는 데 사용됩니다. 리포지토리에 대한 각 쓰기 작업은 리포지토리의 세대를 증가시킵니다.
Replicas 존재하거나 존재할 것으로 예상되는 복제본의 목록입니다.

각 복제본에 대해 다음과 같은 메타데이터가 사용 가능합니다:

Replicas 필드 설명
Storage 복제본을 포함하는 Gitaly 스토리지의 이름입니다.
Assigned 해당 복제본이 스토리지에 존재해야 할지를 나타냅니다. 리포지토리의 복제 요소가 감소된 후 스토리지가 추가 복사본을 포함하는 경우 또는 Gitaly 노드가 클러스터에서 제거된 경우 false가 될 수 있습니다.
Generation 복제본의 최신 확인된 세대입니다. 이는 다음을 나타냅니다:

- 세대가 리포지토리의 세대와 일치하는 경우 복제본이 완전히 최신 상태임을 나타냅니다.
- 복제본의 세대가 리포지토리의 세대보다 작은 경우 복제본이 오래되었음을 나타냅니다.
- 복제본이 스토리지에 아직 전혀 존재하지 않은 경우 replica not yet created가 나타납니다.
Healthy 이 복제본을 호스팅하는 Gitaly 노드가 Praefect 노드의 합의에 따라 건강하다고 간주되는지를 나타냅니다.
Valid Primary 복제본이 주 노드로서 작동할 수 있는지를 나타냅니다. 리포지토리의 주 노드가 유효한 주 노드가 아닌 경우, 다른 복제본이 유효한 주 노드인 경우 리폴오버(failover)가 발생합니다. 복제본이 유효한 주 노드인 경우 다음이 됩니다:

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

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

-virtual-storage에 입력된 값이 올바르지 않은 경우, 다음 오류가 발생합니다.

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

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

리포지토리의 동기화 확인

어떤 경우에는 Praefect 데이터베이스가 기본 Gitaly 노드와 동기화 되지 않을 수 있습니다. 특정 리포지토리가 모든 노드에서 완전히 동기화되었는지 확인하려면 Rails 노드에서 gitlab:praefect:replicas Rake 작업을 실행하세요. 이 Rake 작업은 모든 Gitaly 노드에서 리포지토리의 체크섬을 생성합니다.

Praefect dataloss 명령어는 Praefect 데이터베이스에서 리포지토리의 상태를 확인하고 이 시나리오에서 동기화 문제를 감지하는 데 사용될 수 없습니다.

관계가 존재하지 않는 오류

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

그러나 초기 구성(reconfigure) 시 Praefect 데이터베이스 테이블이 생성되지 않을 수 있으며 다음과 같은 경우에 관계가 존재하지 않는 오류가 발생할 수 있습니다:

  • 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)

‘저장소 범위: 유효하지 않은 저장소’ 오류로 인해 요청이 실패합니다.

이는 Praefect 구성에서 사용된 가상 저장소 이름이 GitLab의 gitaly['configuration'][:storage][<index>][:name] 설정에서 사용된 저장소 이름과 일치하지 않음을 나타냅니다.

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

클라우드 플랫폼에서 Gitaly 클러스터 성능 문제

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

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']가 정수가 아닌 문자열로 구성된 경우 발생합니다.