Gitaly 클러스터 구성

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

다음 중 하나를 사용하여 Gitaly 클러스터를 구성합니다.

더 작은 GitLab 설치에서는 Gitaly 자체만 필요할 수 있습니다.

note
Gitaly 클러스터는 아직 Kubernetes, Amazon ECS 또는 유사한 컨테이너 환경에서 지원되지 않습니다. 자세한 정보는 epic 6127를 참조하세요.

요구 사항

Gitaly 클러스터의 최소 권장 구성은 다음과 같습니다:

  • 로드 밸런서 1대
  • 1개의 PostgreSQL 서버 (PostgreSQL 11 이상)
  • Praefect 노드 3대
  • Gitaly 노드 3대 (주 노드 1대, 보조 노드 2대)

Gitaly 노드 중 하나가 변이 RPC 호출에서 실패하는 경우 트랜잭션이 결정자(tie-breaker)를 가질 수 있도록 홀수 개수로 Gitaly 노드를 구성해야 합니다.

구현 세부 정보는 설계 문서에서 확인할 수 있습니다.

note
GitLab에서 feature flags가 설정되지 않으면 콘솔에서 false로 읽히며 Praefect는 기본값을 사용합니다. 기본값은 GitLab 버전에 따라 다릅니다.

네트워크 지연 및 연결성

Gitaly 클러스터의 네트워크 지연은 이상적으로 일부 밀리초 내에 메트릭 가능해야 합니다. 지연은 특히 다음과 같은 경우에 중요합니다:

  • Gitaly 노드에서의 건강 상태 확인. 노드는 1초 이내에 응답해야 합니다.
  • 강력한 일관성을 적용하는 참조 트랜잭션. 낮은 지연 시간은 Gitaly 노드가 변경 사항에 대해 빠르게 합의할 수 있도록 합니다.

Gitaly 노드 간의 수용 가능한 지연시간 달성:

  • 물리적 네트워크에서는 대체로 대역폭이 높은 단일 위치 연결을 의미합니다.
  • 클라우드에서는 주로 동일한 지역에서 이루어지며, 가용 영역간 복제를 허용합니다. 이러한 링크는 이러한 유형의 동기화를 위해 설계되었습니다. Gitaly 클러스터에는 2ms 미만의 지연시간이 충분합니다.

복제를 위해 낮은 네트워크 지연 시간을 제공할 수 없는 경우(예: 먼 위치 간), Geo를 고려해 보세요. 자세한 내용은 Geo와의 비교를 참조하세요.

Gitaly 클러스터 컴포넌트는 서로 다양한 경로를 통해 통신합니다. 방화벽 규칙은 Gitaly 클러스터가 올바르게 작동하려면 다음을 허용해야 합니다:

출발지 목적지 기본 포트 TLS 포트
GitLab Praefect 로드 밸런서 2305 3305
Praefect 로드 밸런서 Praefect 2305 3305
Praefect Gitaly 8075 9999
Praefect GitLab(내부 API) 80 443
Gitaly GitLab(내부 API) 80 443
Gitaly Praefect 로드 밸런서 2305 3305
Gitaly Praefect 2305 3305
Gitaly Gitaly 8075 9999
note
Gitaly는 Praefect에 직접 연결하지 않습니다. 그러나 Gitaly에서 Praefect 로드 밸런서로의 요청은 여전히 Gitaly 노드의 방화벽에서 차단될 수 있습니다.

Praefect 데이터베이스 리포지터리

데이터베이스의 요구 사항은 다음과 같습니다.

  • 리포지터리 위치
  • 일부 대기 작업

리포지터리의 수에 따라 다르지만, 최소한 5-10GB(주로 메인 GitLab 애플리케이션 데이터베이스와 유사)가 필요합니다.

설정 지침

Linux 패키지(강력 추천)를 사용하여 GitLab을 설치한 경우, 아래 단계를 따르세요.

  1. 준비
  2. Praefect 데이터베이스 구성
  3. Praefect 프록시/라우터 구성
  4. 각 Gitaly 노드 구성 (각 Gitaly 노드에 대해 한 번씩)
  5. 로드 밸런서 구성
  6. GitLab 서버 구성 업데이트
  7. Grafana 구성

준비

시작하기 전에 작동 중인 GitLab 인스턴스가 있어야 합니다. GitLab 설치 방법을 확인하세요.

PostgreSQL 서버를 프로비저닝하세요. Linux 패키지에서 제공되는 PostgreSQL을 사용하고 PostgreSQL 데이터베이스를 구성하기 위해 사용하세요. 외부 PostgreSQL 서버(버전 11 이상)를 사용할 수 있지만 매뉴얼으로 설정해야 합니다.

새 노드 모두를 설치하여 준비하세요. 다음이 필요합니다:

  • PostgreSQL 노드 1대
  • PgBouncer 노드 1대 (옵션)
  • Praefect 노드 1대 이상 (최소 리포지터리 필요)
  • Gitaly 노드 3대 (고 CPU, 고 메모리, 빠른 리포지터리)
  • GitLab 서버 1대

또한 각 노드의 IP/호스트 주소가 필요합니다:

  1. PRAEFECT_LOADBALANCER_HOST: Praefect 로드 밸런서의 IP/호스트 주소
  2. POSTGRESQL_HOST: PostgreSQL 서버의 IP/호스트 주소
  3. PGBOUNCER_HOST: PostgreSQL 서버의 IP/호스트 주소
  4. PRAEFECT_HOST: Praefect 서버의 IP/호스트 주소
  5. GITALY_HOST_*: 각 Gitaly 서버의 IP 또는 호스트 주소
  6. GITLAB_HOST: GitLab 서버의 IP/호스트 주소

Google Cloud Platform, SoftLayer 또는 VPC를 제공하는 기타 업체를 사용하는 경우 각 클라우드 인스턴스에 대한 개인 주소를 사용할 수 있습니다 (Google Cloud Platform의 경우 “내부 주소”에 해당).

Secrets (비밀 정보)

컴포넌트 간의 통신은 아래에 설명한 여러 가지 비밀 정보로 보호됩니다. 시작하기 전에 각 비밀 정보에 대해 고유한 비밀을 생성하고 이 설정 프로세스를 완료하면 이러한 플레이스홀더 토큰을 안전한 토큰으로 교체할 수 있습니다.

  1. GITLAB_SHELL_SECRET_TOKEN: 이것은 Git 훅이 Git 푸시를 수락할 때 GitLab에게 HTTP API 요청을 수행하기 위해 사용됩니다. 이 비밀은 레거시 이유로 GitLab Shell과 공유됩니다.
  2. PRAEFECT_EXTERNAL_TOKEN: Praefect 클러스터에 호스팅된 리포지터리는 이 토큰을 갖고 있는 Gitaly 클라이언트만 액세스할 수 있습니다.
  3. PRAEFECT_INTERNAL_TOKEN: 이 토큰은 Praefect 클러스터 내부에서 복제 트래픽에 사용됩니다. 이 토큰은 PRAEFECT_EXTERNAL_TOKEN과는 다르며 Gitaly 클라이언트가 Praefect 클러스터의 내부 노드에 직접 액세스하지 못하게 해야 합니다.
  4. PRAEFECT_SQL_PASSWORD: 이 패스워드는 Praefect가 PostgreSQL에 연결할 때 사용됩니다.
  5. PRAEFECT_SQL_PASSWORD_HASH: Praefect 사용자의 패스워드 해시값입니다. 해시는 gitlab-ctl pg-password-md5 praefect를 사용하여 생성합니다. 이 명령은 praefect 사용자의 패스워드를 요청합니다. PRAEFECT_SQL_PASSWORD 평문 패스워드를 입력하세요. 기본적으로 Praefect는 praefect 사용자를 사용하지만 변경할 수 있습니다.
  6. PGBOUNCER_SQL_PASSWORD_HASH: PgBouncer 사용자의 패스워드 해시값입니다. PgBouncer는 PostgreSQL에 연결할 때 이 패스워드를 사용합니다. 자세한 내용은 bundled PgBouncer 문서를 참조하세요.

아래 지시사항은 이러한 비밀 정보가 필요한 곳을 설명합니다.

note
Linux 패키지 설치에서는 gitlab-secrets.jsonGITLAB_SHELL_SECRET_TOKEN에 사용할 수 있습니다.

사용자 정의 시간 서버 설정

기본적으로, Gitaly 및 Praefect 노드는 시간 동기화 확인을 위해 pool.ntp.org의 시간 서버를 사용합니다. 각 노드의 gitlab.rb에 다음을 추가하여 이 설정을 사용자 정의할 수 있습니다:

  • gitaly['env'] = { "NTP_HOST" => "ntp.example.com" }, Gitaly 노드용.
  • praefect['env'] = { "NTP_HOST" => "ntp.example.com" }, Praefect 노드용.

PostgreSQL

note
만약 Geo를 사용 중이라면 GitLab 애플리케이션 데이터베이스와 Praefect 데이터베이스를 동일한 PostgreSQL 서버에 저장하지 마십시오. 복제 상태는 GitLab의 각 인스턴스에게 내부적으로 있어야 하며 복제되어서는 안 됩니다.

이 지침은 단일 PostgreSQL 데이터베이스를 설정하는 데 도움이 됩니다. 이는 단일 장애 지점을 만듭니다. 이를 피하기 위해 직접 클러스터화된 PostgreSQL을 구성할 수 있습니다. Linux 패키지를 사용하여 PostgreSQL 복제 및 장애 조치를 지원하는 것은 epic 7814에서 제안되었습니다. 기타 데이터베이스(예: Praefect 및 Geo 데이터베이스)에 대한 클러스터화된 데이터베이스 지원은 issue 7292에서 제안되었습니다.

다음 옵션이 있습니다:

PostgreSQL을 설정하면 빈 Praefect 테이블이 생성됩니다. 자세한 정보는 해당 문제 해결 섹션을 참조하십시오.

GitLab 및 Praefect 데이터베이스를 동일한 서버에서 실행

GitLab 애플리케이션 데이터베이스와 Praefect 데이터베이스를 동일한 서버에서 실행할 수 있습니다. 그러나 Linux 패키지에서 PostgreSQL을 사용할 때 Praefect는 별도의 데이터베이스 서버를 가져야 합니다. 장애 조치가 발생하면 Praefect가 인식하지 못하고 다음과 같이 실패합니다:

  • 사용할 수 없음.
  • 읽기 전용 모드로 설정됨.

매뉴얼 데이터베이스 설정

이 섹션을 완료하려면 다음이 필요합니다:

  • Praefect 노드 한 대
  • PostgreSQL 노드 한 대 (버전 11 이상)
    • 데이터베이스 서버를 관리할 권한이 있는 PostgreSQL 사용자

이 섹션에서는 PostgreSQL 데이터베이스를 구성합니다. 외부 및 Linux 패키지에서 제공하는 PostgreSQL 서버 모두 사용할 수 있습니다.

다음 지침을 실행하려면, Linux 패키지에서 psql이 설치된 Praefect 노드를 사용할 수 있습니다(/opt/gitlab/embedded/bin/psql). Linux 패키지에서 제공하는 PostgreSQL을 사용 중이라면 PostgreSQL 노드에서 gitlab-psql을 대신 사용할 수 있습니다:

  1. Praefect가 사용할 새 사용자 praefect를 만듭니다:

    CREATE ROLE praefect WITH LOGIN PASSWORD 'PRAEFECT_SQL_PASSWORD';
    

    PRAEFECT_SQL_PASSWORD을(를) 사전 설정 단계에서 생성한 강력한 비밀번호로 교체하십시오.

  2. praefect 사용자가 소유한 praefect_production이라는 새 데이터베이스를 만듭니다.

    CREATE DATABASE praefect_production WITH OWNER praefect ENCODING UTF8;
    

Linux 패키지에서 제공하는 PgBouncer를 사용할 때, 다음 추가 단계를 수행해야 합니다. 백엔드로 제공되는 PostgreSQL을 강력히 권장합니다. 다음 지침은 Linux 패키지에서만 작동합니다:

  1. Linux 패키지에서 제공하는 PgBouncer를 위해 praefect 암호의 해시를 사용해야 합니다:

    ALTER ROLE praefect WITH PASSWORD 'md5<PRAEFECT_SQL_PASSWORD_HASH>';
    

    <PRAEFECT_SQL_PASSWORD_HASH>를 사전 설정 단계에서 생성한 암호의 해시로 교체하십시오. 이는 md5 리터럴로 접두어가 붙습니다.

  2. Linux 패키지와 함께 제공되는 PgBouncer는 auth_query를 사용하며 pg_shadow_lookup 함수를 사용합니다. 이 함수를 praefect_production 데이터베이스에 만들어야 합니다:

    CREATE OR REPLACE FUNCTION public.pg_shadow_lookup(in i_username text, out username text, out password text) RETURNS record AS $$
    BEGIN
        SELECT usename, passwd FROM pg_catalog.pg_shadow
        WHERE usename = i_username INTO username, password;
        RETURN;
    END;
    $$ LANGUAGE plpgsql SECURITY DEFINER;
       
    REVOKE ALL ON FUNCTION public.pg_shadow_lookup(text) FROM public, pgbouncer;
    GRANT EXECUTE ON FUNCTION public.pg_shadow_lookup(text) TO pgbouncer;
    

Praefect이 사용할 데이터베이스가 이제 구성되었습니다.

이제 Praefect가 데이터베이스를 사용하도록 구성할 수 있습니다:

praefect['configuration'] = {
   # ...
   database: {
      # ...
      host: POSTGRESQL_HOST,
      user: 'praefect',
      port: 5432,
      password: PRAEFECT_SQL_PASSWORD,
      dbname: 'praefect_production',
   }
}

PostgreSQL을 구성한 후 Praefect 데이터베이스에 대한 오류가 발생하면 문제 해결 단계를 참조하십시오.

읽기 분배 캐싱

database_direct 설정을 추가로 구성함으로써 Praefect 성능을 향상시킬 수 있습니다:

praefect['configuration'] = {
   # ...
   database: {
      # ...
      session_pooled: {
         # ...
         host: POSTGRESQL_HOST,
         port: 5432
         
         # 직접 데이터베이스 연결의 매개변수를 재정의하려면 다음을 사용하십시오.
         # 매개변수가 두 연결 모두 동일한 경우 주석 처리하십시오.
         user: 'praefect',
         password: PRAEFECT_SQL_PASSWORD,
         dbname: 'praefect_production',
         # sslmode: '...',
         # sslcert: '...',
         # sslkey: '...',
         # sslrootcert: '...',
      }
   }
}

이렇게 구성하면 이 연결이 자동으로 SQL LISTEN 기능에 사용되며 Praefect가 캐시 무효화를 위해 PostgreSQL로부터 알림을 수신할 수 있게 합니다.

Praefect 로그에서 다음 로그 항목을 찾아 기능이 작동하는지 확인하십시오:

reads distribution caching is enabled by configuration

PgBouncer 사용

PostgreSQL 리소스 소비를 줄이려면 PostgreSQL 인스턴스 앞에 PgBouncer를 설정하고 구성해야 합니다. 그러나 Praefect는 적은 수의 연결을 만드므로 PgBouncer가 필수는 아닙니다. PgBouncer를 사용하려면 GitLab 애플리케이션 데이터베이스와 Praefect 데이터베이스에 동일한 PgBouncer 인스턴스를 사용할 수 있습니다.

PostgreSQL 인스턴스 앞에 PgBouncer를 구성하려면 Praefect 구성에서 데이터베이스 매개변수를 사용하여 Praefect를 PgBouncer로 지정해야 합니다:

praefect['configuration'] = {
   # ...
   database: {
      # ...
      host: PGBOUNCER_HOST,
      port: 6432,
      user: 'praefect',
      password: PRAEFECT_SQL_PASSWORD,
      dbname: 'praefect_production',
      # sslmode: '...',
      # sslcert: '...',
      # sslkey: '...',
      # sslrootcert: '...',
   }
}

Praefect가 추가로 PostgreSQL에 대해 LISTEN 기능을 지원하는 연결이 필요합니다. PgBouncer를 사용하면 이 기능은 session 풀 모드(pool_mode = session)에서만 사용할 수 있습니다. transaction 풀 모드(pool_mode = transaction)에서는 사용할 수 없습니다.

추가 연결을 구성하려면 다음 중 하나를 수행해야 합니다:

  • 동일한 PostgreSQL 데이터베이스 엔드포인트를 사용하지만 다른 풀 모드(pool_mode = session)를 사용하는 새 PgBouncer 데이터베이스를 구성합니다.
  • Praefect를 직접 PostgreSQL에 연결하고 PgBouncer를 우회합니다.

pool_mode = session로 새로운 PgBouncer 데이터베이스 구성

session 풀 모드로 PgBouncer를 사용해야 합니다. 번들된 PgBouncer를 사용하거나, 외부 PgBouncer를 사용하고 매뉴얼으로 구성할 수 있습니다.

다음 예시는 번들된 PgBouncer를 사용하고 PostgreSQL 호스트에 두 개의 별도 연결 풀을 설정하며, 하나는 session 풀 모드이고 다른 하나는 transaction 풀 모드입니다. 이 예제가 작동하려면 설치 지침에 문서화된 대로 PostgreSQL 서버를 준비해야 합니다.

pgbouncer['databases'] = {
  # gitlabhq_production을 포함한 다른 데이터베이스 구성
  ...
  
  praefect_production: {
    host: POSTGRESQL_HOST,
    # 데이터베이스 백엔드에 연결하기 위해 `pgbouncer` 사용
    user: 'pgbouncer',
    password: PGBOUNCER_SQL_PASSWORD_HASH,
    pool_mode: 'transaction'
  },
  praefect_production_direct: {
    host: POSTGRESQL_HOST,
    # 데이터베이스 백엔드에 연결하기 위해 `pgbouncer` 사용
    user: 'pgbouncer',
    password: PGBOUNCER_SQL_PASSWORD_HASH,
    dbname: 'praefect_production',
    pool_mode: 'session'
  },
  
  ...
}

# praefect 사용자가 PgBouncer에 연결할 수 있도록 함
pgbouncer['users'] = {
  'praefect': {
    'password': PRAEFECT_SQL_PASSWORD_HASH,
  }
}

praefect_productionpraefect_production_direct는 동일한 데이터베이스 엔드포인트(praefect_production)를 사용하지만 다른 풀 모드로 설정됩니다. 이는 PgBouncer의 다음 databases 섹션으로 변환됩니다:

[databases]
praefect_production = host=POSTGRESQL_HOST auth_user=pgbouncer pool_mode=transaction
praefect_production_direct = host=POSTGRESQL_HOST auth_user=pgbouncer dbname=praefect_production pool_mode=session

이제 Praefect가 두 연결 유형에 모두 PgBouncer를 사용하도록 구성할 수 있습니다.

note
Linux 패키지 설치는 인증 요구 사항(auth_query 사용)을 처리하지만, 데이터베이스를 매뉴얼으로 준비하고 외부 PgBouncer를 구성하는 경우 PgBouncer가 사용하는 파일에 praefect 사용자 및 비밀번호를 포함해야 합니다. 예를 들어 auth_file 구성 옵션으로 userlist.txt를 사용하는 경우입니다. 자세한 내용은 PgBouncer 설명서를 참조하세요.

Praefect가 PostgreSQL에 직접 연결하도록 구성

session 풀 모드로 PgBouncer를 구성하는 대신 Praefect를 PostgreSQL에 직접 액세스하도록 다른 연결 매개변수를 사용할 수 있습니다. 이 연결은 LISTEN 기능을 지원합니다.

PgBouncer를 우회하고 PostgreSQL에 직접 연결하는 Praefect 구성 예시:

praefect['configuration'] = {
   # ...
   database: {
      # ...
      session_pooled: {
         # ...
         host: POSTGRESQL_HOST,
         port: 5432,
         
         # 직접 데이터베이스 연결 매개변수를 재정의하려면 다음을 사용하세요.
         # 매개변수가 두 연결 모두 동일한 경우 주석 처리하세요.
         #
         user: 'praefect',
         password: PRAEFECT_SQL_PASSWORD,
         dbname: 'praefect_production',
         # sslmode: '...',
         # sslcert: '...',
         # sslkey: '...',
         # sslrootcert: '...',
      },
   },
}

Praefect

여러 개의 Praefect 노드가 있는 경우:

  1. 배포 노드를 하나 지정하고 다음 단계를 사용하여 구성하세요.
  2. 추가 노드마다 다음 단계를 완료하세요.

이 섹션을 완료하려면 구성된 PostgreSQL 서버가 필요합니다.

caution
Praefect는 전용 노드에서 실행해야 합니다. Praefect를 애플리케이션 서버나 Gitaly 노드에서 실행하지 마세요.

Praefect 노드에서:

  1. /etc/gitlab/gitlab.rb를 편집하여 다른 모든 서비스를 비활성화합니다:
   # Praefect 서버에서 불필요한 서비스 실행 방지
   gitaly['enable'] = false
   postgresql['enable'] = false
   redis['enable'] = false
   nginx['enable'] = false
   puma['enable'] = false
   sidekiq['enable'] = false
   gitlab_workhorse['enable'] = false
   prometheus['enable'] = false
   alertmanager['enable'] = false
   grafana['enable'] = false
   gitlab_exporter['enable'] = false
   gitlab_kas['enable'] = false
   
   # Praefect 서비스만 활성화
   praefect['enable'] = true
   
   # 업그레이드 시 자동으로 데이터베이스 마이그레이션 실행 방지
   praefect['auto_migrate'] = false
   gitlab_rails['auto_migrate'] = false
  1. /etc/gitlab/gitlab.rb를 편집하여 Praefect가 네트워크 인터페이스에서 수신하도록 구성합니다:

    praefect['configuration'] = {
       # ...
       listen_addr: '0.0.0.0:2305',
    }
    
  2. /etc/gitlab/gitlab.rb를 편집하여 Prometheus 메트릭을 구성합니다:

    praefect['configuration'] = {
       # ...
       #
       # Prometheus 메트릭을 Praefect에 사용 가능하게 함. 방화벽을 사용하여 이 주소/포트에 대한 액세스를 제한해야 합니다.
       # 기본 메트릭 엔드포인트는 /metrics 입니다.
       prometheus_listen_addr: '0.0.0.0:9652',
       # 일부 메트릭을 데이터베이스에 대한 쿼리를 실행합니다. 별도의 데이터베이스 메트릭을 사용하도록 활성화하면
       # 이 메트릭이 수집될 수 있습니다.
       prometheus_exclude_database_from_default_metrics: true,
    }
    
  3. /etc/gitlab/gitlab.rb를 편집하여 Praefect에 대한 강력한 인증 토큰을 구성합니다. 이는 클러스터 외부의 클라이언트(GitLab Shell 등)가 Praefect 클러스터와 통신할 때 필요합니다:

    praefect['configuration'] = {
       # ...
       auth: {
          # ...
          token: 'PRAEFECT_EXTERNAL_TOKEN',
       },
    }
    
  4. Praefect 클러스터가 각 Gitaly 노드에 연결하도록 구성합니다.

    가상 스토리지의 이름은 GitLab 구성에서 default로 구성된 스토리지 이름과 일치해야 합니다. 나중에 스토리지 이름을 default로 구성했으므로 여기서도 default를 사용합니다. 이 클러스터에는 gitaly-1, gitaly-2, gitaly-3 세 개의 Gitaly 노드가 있으며 서로의 복제본이 되도록 의도되었습니다.

    caution
    이미 존재하는 default라는 이름의 스토리지에 데이터가 있는 경우 가상 스토리지에 다른 이름으로 구성하고, 이후 Gitaly 클러스터 스토리지로 데이터 마이그레이션을 수행해야 합니다.

    PRAEFECT_INTERNAL_TOKEN을 강력한 비밀로 교체합니다. 이는 Praefect가 클러스터 내의 Gitaly 노드와 통신할 때 사용됩니다. 이 토큰은 PRAEFECT_EXTERNAL_TOKEN와는 다릅니다.

    GITALY_HOST_*을 각 Gitaly 노드의 IP 또는 호스트 주소로 교체합니다.

    클러스터에는 추가 Gitaly 노드를 추가하거나 매우 큰 GitLab 인스턴스의 경우 추가 클러스터를 추가할 수 있습니다.

    note
    추가 Gitaly 노드를 가상 스토리지에 추가할 때 해당 가상 스토리지의 모든 스토리지 이름이 고유해야 합니다. 또한 Praefect 구성에서 참조하는 모든 Gitaly 노드 주소도 고유해야 합니다.
    # 스토리지 해시의 이름은 GitLab 서버의 git_data_dirs(`default`) 및 Gitaly 노드('gitaly-1'에서 gitaly['configuration'][:storage][INDEX][:name])에서 구성된 스토리지 이름과 일치해야 합니다
    praefect['configuration'] = {
       # ...
       virtual_storage: [
          {
             # ...
             name: 'default',
             node: [
                {
                   storage: 'gitaly-1',
                   address: 'tcp://GITALY_HOST_1:8075',
                   token: 'PRAEFECT_INTERNAL_TOKEN'
                },
                {
                   storage: 'gitaly-2',
                   address: 'tcp://GITALY_HOST_2:8075',
                   token: 'PRAEFECT_INTERNAL_TOKEN'
                },
                {
                   storage: 'gitaly-3',
                   address: 'tcp://GITALY_HOST_3:8075',
                   token: 'PRAEFECT_INTERNAL_TOKEN'
                },
             ],
          },
       ],
    }
    
  5. 변경 사항을 /etc/gitlab/gitlab.rb에 저장하고 Praefect를 다시 구성합니다:

    gitlab-ctl reconfigure
    
  6. “배포 노드”의 경우:
    1. /etc/gitlab/gitlab.rb에서 praefect['auto_migrate'] = true로 Praefect 데이터베이스 자동 마이그레이션을 다시 활성화합니다.
    2. 업그레이드 중에 데이터베이스 마이그레이션이 자동으로 실행되는 것이 아니라 재구성 중에만 실행되도록 하기 위해 다음을 실행합니다:

      sudo touch /etc/gitlab/skip-auto-reconfigure
      
  7. 다른 노드에서는 설정을 그대로 두십시오. /etc/gitlab/skip-auto-reconfigure가 필요하지는 않지만, apt-get update와 같은 명령을 실행할 때 GitLab이 자동으로 다시 구성되지 않도록하려면 이 파일을 설정해두는 것이 좋습니다. 추가 구성 변경을 완료한 후에는 매뉴얼으로 다시 구성을 실행할 수 있습니다.

  8. 변경 사항을 /etc/gitlab/gitlab.rb에 저장하고 Praefect를 다시 구성합니다:

    gitlab-ctl reconfigure
    
  9. Praefect가 Prometheus listen 주소를 업데이트했는지 확인하고, Praefect를 다시 시작합니다:

    gitlab-ctl restart praefect
    
  10. Praefect가 PostgreSQL에 연결할 수 있는지 확인합니다:

    sudo -u git /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-ping
    

    확인이 실패하는 경우 단계를 올바르게 따랐는지 확인하세요. /etc/gitlab/gitlab.rb를 편집한 경우 sudo gitlab-ctl reconfigure를 실행한 후 sql-ping 명령을 다시 시도해야 합니다.

TLS 지원 활성화

Praefect는 TLS 암호화를 지원합니다. 안전한 연결을 수신 대기 중인 Praefect 인스턴스와 통신하려면 다음을 수행해야 합니다:

  • Gitaly가 TLS로 구성되어 있고 GitLab 구성의 해당 리포지터리 항목의 gitaly_addresstls:// URL 스키마를 사용합니다.
  • 이 기능은 자동으로 제공되지 않으므로 사용자가 고유의 인증서를 가져와야 합니다. 각 Praefect 서버에 해당하는 인증서를 설치해야 합니다.

또한 인증서 또는 인증서 기관을 설치해야 합니다. 이는 GitLab 사용자 정의 인증서 구성에서 설명된 절차에 따라 해당되는 모든 Gitaly 서버 및 Praefect 클라이언트에 설치되어야 합니다.

다음을 주의하세요:

  • 인증서는 Praefect 서버에 액세스하는 데 사용하는 주소를 지정해야 합니다. 호스트 이름 또는 IP 주소를 인증서의 대체 이름(Subject Alternative Name)으로 추가해야 합니다.
  • Gitaly TLS로 실행된 Praefect 하위 명령(예: dial-nodeslist-untracked-repositories)을 명령줄에서 실행할 때 SSL_CERT_DIR 또는 SSL_CERT_FILE 환경 변수를 설정하여 Gitaly 인증서를 신뢰할 수 있도록 해야 합니다. 예:

     sudo SSL_CERT_DIR=/etc/gitlab/trusted-certs /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes
    
  • Praefect 서버를 암호화되지 않은 수신 대기 주소 listen_addr 및 암호화된 수신 대기 주소 tls_listen_addr로 동시에 구성할 수 있습니다. 필요한 경우 암호화되지 않은 트래픽에서 암호화된 트래픽으로 점진적 전환을 수행할 수 있습니다.

    암호화되지 않은 수신 대기자(Listener)를 비활성화하려면 다음과 같이 설정합니다:

     praefect['configuration'] = {
       # ...
       listen_addr: nil,
     }
    

TLS로 Praefect를 구성합니다.

Linux 패키지 설치의 경우:

  1. Praefect 서버용 인증서를 생성합니다.

  2. Praefect 서버에서 /etc/gitlab/ssl 디렉터리를 생성하고 키와 인증서를 복사합니다:

    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo cp key.pem cert.pem /etc/gitlab/ssl/
    sudo chmod 644 key.pem cert.pem
    
  3. /etc/gitlab/gitlab.rb를 편집하고 다음을 추가합니다:

    praefect['configuration'] = {
       # ...
       tls_listen_addr: '0.0.0.0:3305',
       tls: {
          # ...
          certificate_path: '/etc/gitlab/ssl/cert.pem',
          key_path: '/etc/gitlab/ssl/key.pem',
       },
    }
    
  4. 파일을 저장하고 GitLab을 다시 구성합니다.

  5. Praefect 클라이언트(각 Gitaly 서버 포함)에서 인증서 또는 인증서 기관을 /etc/gitlab/trusted-certs로 복사합니다:

    sudo cp cert.pem /etc/gitlab/trusted-certs/
    
  6. Praefect 클라이언트(단, Gitaly 서버는 제외)에서 다음과 같이 /etc/gitlab/gitlab.rb에서 git_data_dirs를 편집합니다:

    git_data_dirs({
      "default" => {
        "gitaly_address" => 'tls://PRAEFECT_LOADBALANCER_HOST:3305',
        "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
      }
    })
    
  7. 파일을 저장하고 GitLab을 다시 구성합니다.

자체 컴파일 설치의 경우:

  1. Praefect 서버용 인증서를 생성합니다.
  2. Praefect 서버에서 /etc/gitlab/ssl 디렉터리를 생성하고 키와 인증서를 복사합니다:

    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo cp key.pem cert.pem /etc/gitlab/ssl/
    sudo chmod 644 key.pem cert.pem
    
  3. Praefect 클라이언트(각 Gitaly 서버 포함)에서 인증서 또는 인증서 기관을 시스템 신뢰 인증서로 복사합니다:

    sudo cp cert.pem /usr/local/share/ca-certificates/praefect.crt
    sudo update-ca-certificates
    
  4. Praefect 클라이언트(단, Gitaly 서버는 제외)에서 /home/git/gitlab/config/gitlab.yml에서 storages를 다음과 같이 편집합니다:

    gitlab:
      repositories:
        storages:
          default:
            gitaly_address: tls://PRAEFECT_LOADBALANCER_HOST:3305
    
  5. 파일을 저장하고 GitLab을 다시 시작합니다.

  6. 각 Gitaly 서버의 시스템 신뢰 인증서로 Praefect 서버의 인증서 또는 인증서 기관을 모두 복사하여 Praefect 서버가 호출될 때 Praefect 서버가 인증서를 신뢰할 수 있도록 합니다:

    sudo cp cert.pem /usr/local/share/ca-certificates/praefect.crt
    sudo update-ca-certificates
    
  7. /home/git/praefect/config.toml를 편집하고 다음을 추가합니다:

    tls_listen_addr = '0.0.0.0:3305'
       
    [tls]
    certificate_path = '/etc/gitlab/ssl/cert.pem'
    key_path = '/etc/gitlab/ssl/key.pem'
    
  8. 파일을 저장하고 GitLab을 다시 시작합니다.

서비스 디스커버리

전제 조건:

  • DNS 서버.

GitLab은 서비스 디스커버리를 사용하여 Praefect 호스트 디렉터리을 검색합니다. 서비스 디스커버리는 DNS A 또는 AAAA 레코드의 주기적인 확인을 포함하며, 해당 레코드에서 검색된 IP가 대상 노드의 주소로 사용됩니다. Praefect는 SRV 레코드를 통한 서비스 디스커버리를 지원하지 않습니다.

기본적으로 확인 간의 최소 시간은 레코드의 TTL과 관계없이 5분입니다. Praefect는 이 간격을 사용자 정의하는 것을 지원하지 않습니다. 클라이언트가 업데이트를 받으면:

  • 새 IP 주소로 새 연결을 설정합니다.
  • 기존의 IP 주소로 이미 있는 연결을 유지합니다.
  • 제거된 IP 주소로의 연결을 끊습니다.

제거 예정의 연결에서 실행 중인 요청은 완료될 때까지 처리됩니다. Workhorse에는 10분의 제한 시간이 있으며, 다른 클라이언트에는 유예 시간 제한이 정의되어 있지 않습니다.

DNS 서버는 로드 밸런싱 대신 모든 IP 주소를 반환해야 합니다. 클라이언트는 IP 주소에 라운드로빈 방식으로 요청을 분산할 수 있습니다.

클라이언트 구성을 업데이트하기 전에 DNS 서비스 디스커버리가 올바르게 작동하는지 확인하세요. 확인하는 데 유용한 도구로 dig가 있습니다.

❯ dig A praefect.service.consul @127.0.0.1

; <<>> DiG 9.10.6 <<>> A praefect.service.consul @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29210
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;praefect.service.consul.                     IN      A

;; ANSWER SECTION:
praefect.service.consul.              0       IN      A       10.0.0.3
praefect.service.consul.              0       IN      A       10.0.0.2
praefect.service.consul.              0       IN      A       10.0.0.1

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Wed Dec 14 12:53:58 +07 2022
;; MSG SIZE  rcvd: 86
서비스 검색 구성

기본적으로 Praefect는 DNS 해상도를 운영 체제에 위임합니다. 이러한 경우에 Gitaly 주소는 다음 중 하나의 형식으로 설정할 수 있습니다.

  • dns:[호스트]:[포트]
  • dns:///[호스트]:[포트] (세 개의 슬래시에 주목하세요)

이 형식으로 권한 있는 이름 서버를 지정할 수도 있습니다.

  • dns://[인가_호스트]:[인가_포트]/[호스트]:[포트]

리눅스 패키지 (Omnibus)

  1. 각 Praefect 노드의 IP 주소를 DNS 서비스 검색 주소에 추가합니다.
  2. Praefect 클라이언트(단, Gitaly 서버는 제외)에서 /etc/gitlab/gitlab.rbgit_data_dirs를 다음과 같이 편집합니다. PRAEFECT_SERVICE_DISCOVERY_ADDRESSpraefect.service.consul과 같은 Praefect 서비스 검색 주소로 바꿉니다.

    git_data_dirs({
      "default" => {
        "gitaly_address" => 'dns:PRAEFECT_SERVICE_DISCOVERY_ADDRESS:2305',
        "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
      }
    })
    
  3. 파일을 저장하고 GitLab 재구성합니다.

소스 컴파일(자체 컴파일)

  1. DNS 서비스 검색 서비스를 설치합니다. 모든 Praefect 노드를 서비스에 등록합니다.
  2. Praefect 클라이언트(단, Gitaly 서버는 제외)에서 /home/git/gitlab/config/gitlab.ymlstorages를 다음과 같이 편집합니다.

    gitlab:
      repositories:
        storages:
          default:
            gitaly_address: dns:PRAEFECT_SERVICE_DISCOVERY_ADDRESS:2305
    
  3. 파일을 저장하고 GitLab을 다시 시작합니다.

Consul을 사용한 서비스 검색 구성

아키텍처에 Consul 서버가 이미 있는 경우, 각 Praefect 노드에 Consul 에이전트를 추가하고 praefect 서비스를 등록할 수 있습니다. 이렇게 하면 각 노드의 IP 주소가 praefect.service.consul에 등록되어 서비스 검색에서 찾을 수 있게 됩니다.

전제 조건:

  • 하나 이상의 Consul 서버가 Consul 에이전트를 유지하는 데 필요합니다.
  1. 각 Praefect 서버에서 /etc/gitlab/gitlab.rb에 다음 내용을 추가합니다.

    consul['enable'] = true
    praefect['consul_service_name'] = 'praefect'
       
    # 다음은 이슈가 해결될 때까지 반드시 추가해야 합니다:
    # https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/8321
    consul['monitoring_service_discovery'] = true
    praefect['configuration'] = {
      # ...
      #
      prometheus_listen_addr: '0.0.0.0:9652',
    }
    
  2. 파일을 저장하고 GitLab 재구성합니다.
  3. 서비스 검색에 사용할 각 Praefect 서버에서 위의 단계를 반복합니다.
  4. Praefect 클라이언트(단, Gitaly 서버는 제외)에서 /etc/gitlab/gitlab.rbgit_data_dirs를 다음과 같이 편집합니다. CONSUL_SERVER를 Consul 서버의 IP 또는 주소로 바꿉니다. 기본 Consul DNS 포트는 8600입니다.

    git_data_dirs({
      "default" => {
        "gitaly_address" => 'dns://CONSUL_SERVER:8600/praefect.service.consul:2305',
        "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
      }
    })
    
  5. Praefect 클라이언트에서 dig를 사용하여 각 IP 주소가 praefect.service.consul에 등록되었는지 확인합니다. dig A praefect.service.consul @CONSUL_SERVER -p 8600를 사용합니다. 위에서 구성한 값을 CONSUL_SERVER로 대체하고 모든 Praefect 노드 IP 주소가 출력에 나와야 합니다.
  6. 파일을 저장하고 GitLab 재구성합니다.

Gitaly

note
Gitaly 노드에 대해 이러한 단계를 완료해야 합니다.

이 섹션을 완료하려면 다음이 필요합니다:

  • 구성된 Praefect 노드
  • Gitaly 노드로 구성될 GitLab이 설치된 3대(또는 그 이상) 서버. 이러한 서버는 전용 노드여야 하며 이러한 노드에서 다른 서비스를 실행해서는 안됩니다.

Praefect 클러스터에 할당된 각 Gitaly 서버를 구성해야 합니다. 구성은 일반 독립형 Gitaly 서버와 동일하지만 다음과 같은 점이 다릅니다.

  • 리포지터리 이름은 GitLab이 아니라 Praefect에서 노출됩니다.
  • 비밀 토큰은 GitLab이 아니라 Praefect와 공유됩니다.

Praefect 클러스터의 모든 Gitaly 노드의 구성은 동일할 수 있습니다. 왜냐하면 우리는 Praefect가 작업을 올바르게 경로로 지정할 것이라 믿기 때문입니다.

특히 다음을 주의 깊게 살펴보아야 합니다.

  • 이 섹션에서 구성한 gitaly['configuration'][:auth][:token]은 Praefect 노드의 praefect['configuration'][:virtual_storage][<index>][:node][<index>][:token] 아래의 token 값과 일치해야 합니다. 이 값은 이전 섹션에서 설정되었습니다. 이 문서에서 사용하는 PRAEFECT_INTERNAL_TOKEN은 플레이스홀더입니다.
  • 이 섹션에서 구성한 gitaly['configuration'][:storage]의 물리적 리포지터리 이름은 Praefect 노드의 praefect['configuration'][:virtual_storage] 아래의 물리적 리포지터리 이름과 일치해야 합니다. 이는 이전 섹션에서 설정되었습니다. 이 문서에서 gitaly-1, gitaly-2, gitaly-3를 물리적 리포지터리 이름으로 사용합니다.

자세한 내용은 Gitaly 서버 구성을 위한 문서를 참조하십시오. Gitaly 문서

  1. Gitaly 노드에 SSH하여 루트로 로그인합니다.

    sudo -i
    
  2. /etc/gitlab/gitlab.rb를 편집하여 다른 모든 서비스를 비활성화합니다.

    # Gitaly 노드에서 모든 다른 서비스 비활성화
    postgresql['enable'] = false
    redis['enable'] = false
    nginx['enable'] = false
    grafana['enable'] = false
    puma['enable'] = false
    sidekiq['enable'] = false
    gitlab_workhorse['enable'] = false
    prometheus_monitoring['enable'] = false
    gitlab_kas['enable'] = false
       
    # Gitaly 서비스만 활성화
    gitaly['enable'] = true
       
    # 필요한 경우 Prometheus 활성화
    prometheus['enable'] = true
       
    # 'gitlab-ctl reconfigure' 중에 데이터베이스 연결을 방지하기 위해 데이터베이스 마이그레이션 비활성화
    gitlab_rails['auto_migrate'] = false
    
  3. /etc/gitlab/gitlab.rb를 편집하여 Gitaly이 네트워크 인터페이스에서 수신하도록 구성합니다.

    gitaly['configuration'] = {
       # ...
       #
       # Gitaly가 모든 네트워크 인터페이스에서 연결을 수신하도록 설정합니다.
       # 이 주소/포트의 액세스를 제한하는 데 방화벽을 사용해야 합니다.
       listen_addr: '0.0.0.0:8075',
       # Gitaly에 Prometheus 메트릭 액세스를 활성화합니다. 액세스를 제한하는 데 방화벽을 사용해야 합니다.
       prometheus_listen_addr: '0.0.0.0:9236',
    }
    
  4. Gitaly에 대한 강력한 auth_token을 구성하여 편집합니다. 이 토큰은 클라이언트가 이 Gitaly 노드와 통신하기 위해 필요합니다. 일반적으로 이 토큰은 모든 Gitaly 노드에서 동일합니다.

    gitaly['configuration'] = {
       # ...
       auth: {
          # ...
          token: 'PRAEFECT_INTERNAL_TOKEN',
       },
    }
    
  5. git push 작업에 필요한 GitLab Shell 비밀 토큰을 구성합니다. 두 가지 방법 중 하나를 선택할 수 있습니다.

    • 방법 1:

      1. Gitaly 클라이언트의 /etc/gitlab/gitlab-secrets.json을 Gitaly 서버와 기타 Gitaly 클라이언트의 동일한 경로에 복사합니다.
      2. Gitaly 서버에서 GitLab 재구성을 실행합니다.
    • 방법 2:

      1. /etc/gitlab/gitlab.rb를 편집합니다.
      2. 실제 비밀 값을 사용하여 GITLAB_SHELL_SECRET_TOKEN을 대체합니다.
         gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
      
  6. git push 작업에 필요한 internal_api_url을 구성합니다.

    # gitlab-shell API 콜백 URL을 구성합니다. 이를 설정하지 않으면 `git push`가 실패합니다.
    # 이 URL은 전면 문이 GitLab URL 또는 내부 로드 밸런서일 수 있습니다.
    # 예: 'https://gitlab.example.com', 'http://10.0.2.2'
    gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
    
  7. Git 데이터의 저장 위치를 설정하여 gitaly['configuration'][:storage]/etc/gitlab/gitlab.rb에서 편집합니다. 각 Gitaly 노드에는 고유한 리포지터리 이름(예: gitaly-1)이 있어야 합니다.

    gitaly['configuration'] = {
       # ...
       storage: [
         # 각 Gitaly 노드에 적합한 이름으로 대체합니다.
         {
           name: 'gitaly-1',
           path: '/var/opt/gitlab/git-data/repositories',
         },
       ],
    }
    
  8. 파일을 /etc/gitlab/gitlab.rb에 적용하고 Gitaly 재구성을 실행합니다.

    gitlab-ctl reconfigure
    
  9. Gitaly에 대체된 Prometheus listen 주소가 적용되었는지 확인하여 Gitaly 재시작합니다.

    gitlab-ctl restart gitaly
    

위의 단계는 각 Gitaly 노드에 대해 완료되어야 합니다!

모든 Gitaly 노드를 구성한 후, Praefect 연결 확인기를 실행하여 Praefect가 Praefect 구성에서 모든 Gitaly 서버에 연결할 수 있는지 확인합니다.

  1. Praefect 노드에서 SSH로 로그인하여 Praefect 연결 확인기를 실행합니다.

    sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes
    

로드 밸런서

고장 허용성이 있는 Gitaly 구성에서는 로드 밸런서가 필요합니다. 이 로드 밸런서는 GitLab 애플리케이션에서 Praefect 노드로의 내부 트래픽을 라우트하기 위해 필요합니다. 어떤 로드 밸런서를 사용하거나 정확한 구성은 GitLab 문서의 범위를 벗어납니다.

::이하 생략::

GitLab

이 섹션을 완료하려면 다음이 필요합니다:

Praefect 클러스터는 GitLab 애플리케이션에 저장 위치로 노출되어야 합니다. 이 작업은 git_data_dirs를 업데이트하여 수행됩니다.

특히 다음에 주의해야 합니다.

  • 이 섹션에 추가된 git_data_dirs의 저장 이름은 Praefect 노드의 praefect['configuration'][:virtual_storage] 아래의 저장 이름과 일치해야 합니다. 이는 본 안내서의 Praefect 섹션에서 설정되었습니다. 본 문서에서는 default를 Praefect 저장 이름으로 사용합니다.

Grafana

Grafana는 GitLab에 포함되어 있으며 Praefect 클러스터를 모니터링하는 데 사용할 수 있습니다. 자세한 내용은 Grafana 대시보드 서비스를 참조하세요.

빠르게 시작하려면:

  1. GitLab 노드(또는 Grafana가 활성화된 노드)로 SSH를 통해 루트 사용자로 로그인합니다:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb를 편집하여 Grafana 로그인 양식을 활성화합니다.

    grafana['disable_login_form'] = false
    
  3. 변경 사항을 /etc/gitlab/gitlab.rb에 저장하고 GitLab 다시 구성을 수행합니다:

    gitlab-ctl reconfigure
    
  4. Grafana 관리자 비밀번호를 설정합니다. 이 명령은 새로운 암호를 입력하라는 프롬프트가 표시됩니다:

    gitlab-ctl set-grafana-password
    
  5. 웹 브라우저에서 GitLab 서버(https://gitlab.example.com/-/grafana와 같은)의 /-/grafana를 엽니다.

    설정한 암호와 admin 사용자 이름으로 로그인합니다.

  6. 탐색(Explore)으로 이동하여 gitlab_build_info를 쿼리하여 모든 머신에서 메트릭을 가져오는지 확인하세요.

축하합니다! 관찰 가능한 고장 허용 Praefect 클러스터를 구성했습니다.

복제 계수 구성

Praefect는 리포지터리마다 복제 계수를 구성하는 것을 지원하며, 특정 리포지터리를 호스팅할 특정 리포지터리 노드를 할당함으로써 이루어집니다.

caution
구성 가능한 복제 계수를 위해서는 특정 리포지터리에 기본 노드를 설정해야 합니다.

Praefect는 실제 복제 계수를 저장하지 않으나, 원하는 복제 계수가 충족되도록 리포지터리를 호스팅할 충분한 리포지터리를 할당합니다. 리포지터리 노드가 이후 가상 리포지터리에서 제거되면 해당 리포지터리에 할당된 리포지터리의 복제 계수가 그에 따라 감소합니다.

다음 중 하나를 구성할 수 있습니다:

  • 새로 생성된 리포지터리에 적용되는 기본 복제 계수
  • set-replication-factor 하위 명령을 사용하여 기존 리포지터리에 대한 복제 계수를 구성합니다.

기본 복제 계수 구성

default_replication_factor가 설정되지 않은 경우, 저장된 모든 리포지터리는 항상 virtual_storages에서 정의된 모든 리포지터리 노드에 복제됩니다. 새로운 리포지터리 노드가 가상 리포지터리에 도입되면, 새로운 리포지터리 및 기존 리포지터리가 자동으로 해당 노드에 복제됩니다.

많은 리포지터리 노드를 보유한 대규모 Gitaly 클러스터 배포의 경우, 모든 리포지터리를 모든 리포지터리 노드에 복제하는 것은 종종 합리적이지 않으며 문제를 일으킬 수 있습니다. 복제 계수 3은 보통 충분하며, 이는 사용 가능한 리포지터리보다 많더라도 리포지터리를 3개의 리포지터리에 복제함을 의미합니다. 더 높은 복제 계수는 주요 리포지터리에 압력을 가중시킵니다.

기본 복제 계수를 구성하려면 /etc/gitlab/gitlab.rb 파일에 구성을 추가하세요:

praefect['configuration'] = {
   # ...
   virtual_storage: [
      {
         # ...
         name: 'default',
         default_replication_factor: 3,
      },
   ],
}

기존 리포지터리에 대한 복제 계수 구성

set-replication-factor 하위 명령은 필요에 따라 무작위 리포지터리 노드를 할당하거나 해제하여 원하는 복제 계수에 도달하도록 합니다. 리포지터리의 주요 노드는 항상 먼저 할당되며 해제되지 않습니다.

sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml set-replication-factor -virtual-storage <가상-리포지터리> -repository <상대-경로> -replication-factor <복제-계수>
  • -virtual-storage는 리포지터리가 위치한 가상 리포지터리입니다.
  • -repository는 리포지터리가 리포지터리의 상대 경로입니다.
  • -replication-factor는 리포지터리의 원하는 복제 계수입니다. 최소 값은 1이며, 주요 리포지터리에 리포지터리의 사본이 필요합니다. 최대 복제 계수는 가상 리포지터리의 리포지터리 수입니다.

성공하면 할당된 호스트 리포지터리가 출력됩니다. 예:

$ sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml set-replication-factor -virtual-storage default -repository @hashed/3f/db/3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278.git -replication-factor 2

current assignments: gitaly-1, gitaly-2

리포지터리 저장 권장 사항

필요한 리포지터리의 크기는 인스턴스마다 다르며 복제 계수로 설정에 따라 달라질 수 있습니다. 리포지터리 저장의 중복성을 구현하는 것이 좋습니다.

복제 계수가:

  • 1인 경우: Gitaly 및 Gitaly 클러스터는 대략 동일한 리포지터리 요구 사항이 있습니다.
  • 1보다 큰 경우: 필요한 리포지터리의 양은 ‘사용 중인 공간 * 복제 계수’입니다. ‘사용 중인 공간’에는 계획된 미래 성장이 포함되어야 합니다.

리포지터리 확인

Praefect는 리포지터리에 대한 메타데이터를 데이터베이스에 저장합니다. 리포지터리가 Praefect를 통과하지 않고 디스크에서 수정되면 메타데이터가 부정확해질 수 있습니다. 예를 들어 Gitaly 노드가 새 노드로 대체되는 대신 다시 빌드된 경우, 리포지터리 확인이 이를 탐지합니다.

메타데이터는 복제 및 라우팅 결정에 사용되므로 정확하지 않으면 문제가 발생할 수 있습니다. Praefect에는 주기적으로 작업하는 백그라운드 워커가 메타데이터를 디스크의 실제 상태와 대조하여 검증합니다. 이 워커는 다음을 수행합니다:

  1. 건강한 리포지터리에서 검증할 복제본 배치를 선택합니다. 복제본은 확인되지 않았거나 구성된 검증 간격을 초과한 것입니다. 확인되지 않은 복제본이 우선되며, 가장 최근의 성공적인 검증 이후의 시간으로 정렬된 다른 복제본이 이어집니다.
  2. 해당 복제본이 각자의 리포지터리에 존재하는지 확인합니다. 복제본이:
    • 존재하는 경우, 마지막으로 성공적으로 검증된 시간을 업데이트합니다.
    • 존재하지 않는 경우, 해당 메타데이터 레코드를 제거합니다.
    • 확인에 실패하는 경우, 다음 작업을 대기할 때 해당 복제본이 다음으로 다시 검증을 받도록 선택합니다.

워커는 검증하기 전에 각 복제본에 대한 전용 검증 리스를 획득합니다. 이렇게 하면 여러 워커가 동시에 동일한 복제본을 검증하는 것을 피합니다. 워커는 검증을 완료하면 리스를 해제합니다. 특정 이유로 워커가 리스를 해제하지 않고 종료되는 경우, Praefect에는 10초마다 잘못된 리스를 해제하는 백그라운드 고르루틴이 있습니다.

작업자는 실제로 실행되기 전에 메타데이터 제거본마다 로깅합니다. perform_deletions 키는 잘못된 메타데이터 레코드를 실제로 삭제하는지 여부를 나타냅니다. 예:

{
  "level": "info",
  "msg": "removing metadata records of non-existent replicas",
  "perform_deletions": false,
  "replicas": {
    "default": {
      "@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.git": [
        "praefect-internal-0"
      ]
    }
  }
}

검증 작업자 구성

작업자는 기본적으로 활성화되어 있으며 메타데이터 레코드를 일주일마다 검증합니다. 검증 간격은 유효한 Go 기간 문자열로 구성할 수 있습니다.

메타데이터를 세 날마다 검증하려면:

praefect['configuration'] = {
   # ...
   background_verification: {
      # ...
      verification_interval: '72h',
   },
}

값이 0 및 이하인 경우 백그라운드 검증기가 비활성화됩니다.

praefect['configuration'] = {
   # ...
   background_verification: {
      # ...
      verification_interval: '0',
   },
}

삭제 기능 활성화

caution
이전에 GitLab 15.9 이전에는 삭제가 기본적으로 비활성화되었었으며, 리포지터리 이름 바꾸기와 관련된 경합 상태로 인해 잘못된 삭제가 발생할 수 있기 때문에 특히 Geo 인스턴스에서 더욱 두드러졌습니다. GitLab 15.0에서 15.5까지는 gitaly_praefect_generated_replica_paths 특성 플래그이 활성화된 경우에만 삭제를 활성화해야 합니다. 이 특성 플래그는 GitLab 15.6에서 제거되어 항상 삭제를 활성화할 수 있게 되었습니다.

기본적으로 워커는 잘못된 메타데이터 레코드를 삭제합니다. 또한 삭제된 레코드를 로그에 남기고 Prometheus 메트릭을 출력합니다.

잘못된 메타데이터 레코드의 삭제를 비활성화하려면:

praefect['configuration'] = {
   # ...
   background_verification: {
      # ...
      delete_invalid_records: false,
   },
}

매뉴얼으로 검증 우선 순위 지정

일부 복제본의 다음 예정된 검증 시간보다 우선하여 검증을 우선 순위로 지정할 수 있습니다. 예를 들어 디스크 장애가 발생한 경우, 디스크 내용이 변경되었을 수 있기 때문에 이것이 필요할 수 있습니다. Praefect는 결국 복제본을 다시 검증하지만 사용자는 그 동안 오류를 만날 수 있습니다.

일부 복제본의 재검증을 매뉴얼으로 우선 순위로 지정하려면 praefect verify 하위 명령을 사용하세요. 하위 명령은 복제본을 미검증으로 표시합니다. 미검증 복제본은 백그라운드 검증 워커에서 우선 순위가 지정됩니다. 복제본의 검증 워커를 활성화해야 합니다.

특정 리포지터리의 복제본을 우선하여 검증하려면:

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

가상 리포지터리에 저장된 모든 복제본을 우선하여 검증하려면:

sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml verify -virtual-storage=<virtual-storage>

리포지터리에 저장된 모든 복제본을 우선하여 검증하려면:

sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml verify -virtual-storage=<virtual-storage> -storage=<storage>

결과에는 미검증으로 표시된 복제본 수가 포함됩니다.

자동 장애 조치 및 기본 선출 전략

Praefect는 각 Gitaly 노드의 상태를 정기적으로 확인하여 현재 기본 Gitaly 노드가 비정상적으로 판명되면 자동으로 새로 선출된 기본 Gitaly 노드로 장애 조치되는 기능을 제공합니다.

리포지터리별 기본 노드 선출은 유일하게 사용 가능한 선출 전략입니다.

리포지터리별 기본 노드 선출

Gitaly 클러스터는 각 리포지터리에 대해 별도로 기본 Gitaly 노드를 선출합니다. 이는 구성 가능한 복제 요인과 함께 사용하여 리포지터리 용량을 수평 확장하고 쓰기 부하를 Gitaly 노드 사이에 분산할 수 있습니다.

기본 선출은 지연되어 실행됩니다. Praefect는 현재 기본 노드가 비정상적이라면 즉시 새로운 기본 노드를 선출하지 않습니다. 현재 기본 노드가 사용할 수 없는 상태에서 요청을 처리해야 하는 경우에만 새 기본 노드가 선출됩니다.

유효한 기본 노드 후보는 다음을 충족하는 Gitaly 노드입니다:

  • 건강합니다. Gitaly 노드가 최근 10초 동안 Praefect 노드의 >=50%가 성공적으로 건강 확인한 경우, Gitaly 노드는 건강하다고 간주됩니다.
  • 리포지터리의 완전히 최신 사본을 가지고 있습니다.

여러 기본 노드 후보가 있는 경우 Praefect는:

  • 이들 중 하나를 임의로 선택합니다.
  • 리포지터리를 호스팅하는 Gitaly 노드를 승격하는 것을 우선시합니다. 리포지터리에 할당된 Gitaly 노드가 기본 노드로 선출할 경우 지정되지 않은 기본 노드가 임시로 선출됩니다. 지정되지 않은 기본 노드는 사용 가능한 지정된 노드가 사용 가능해지면 우선하여 승격됩니다.

리포지터리에 유효한 기본 노드 후보가 없는 경우:

  • 비정상적인 기본 노드가 강등되고 리포지터리는 기본 노드 없이 남습니다.
  • 기본 노드가 성공적으로 선출될 때까지 기본 노드가 필요한 작업은 실패합니다.