Gitaly 클러스터 구성

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

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

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

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

요구 사항

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

  • 1개의 로드 밸런서
  • 1개의 PostgreSQL 서버 (PostgreSQL 11 이상)
  • 3개의 Praefect 노드
  • 3개의 Gitaly 노드 (1개의 기본 및 2개의 보조)
note

트랜잭션이 변이하는 RPC 호출 중 하나의 Gitaly 노드가 실패하는 경우를 대비하여 홀수 개의 Gitaly 노드를 구성해야 합니다.

구현 세부 정보는 설계 문서를 참조하세요.

note
GitLab에서 설정되지 않은 경우 피쳐 플래그가 콘솔에서 거짓으로 읽히고 Praefect는 그들의 기본값을 사용합니다. 기본값은 GitLab 버전에 따라 달라집니다.

네트워크 지연 및 연결성

Gitaly 클러스터의 네트워크 지연은 이상적으로 10밀리초 이내로 측정될 수 있어야 합니다. 지연은 특히 다음과 같은 경우에 중요합니다:

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

Gitaly 노드 간에 적절한 지연 시간 달성:

  • 물리적 네트워크에서는 일반적으로 대역폭이 높은 단일 위치 연결을 의미합니다.
  • 클라우드에서는 동일한 지역에서, 가용 영역을 가로 질러 복제가 가능하게 하는 것을 포함합니다. 이러한 링크는 이러한 유형의 동기화를 위해 설계되었습니다. Gitaly 클러스터에는 2밀리초 미만의 지연이 충분합니다.

복제를 위해 낮은 네트워크 지연을 제공할 수 없는 경우(예: 먼 위치간), 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 로드 밸런서로의 요청이 여전히 차단될 수 있습니다. 따라서 Praefect 노드의 방화벽에서 Gitaly 노드로부터의 트래픽을 허용해야 합니다.

Praefect 데이터베이스 저장소

이 요구 사항은 비교적 낮습니다. 데이터베이스에는 다음과 같은 메타데이터만 포함되어 있습니다:

  • 저장소 위치 정보
  • 일부 대기 중인 작업

저장소의 수에 따라 다르지만, 좋은 최소 용량은 메인 GitLab 애플리케이션 데이터베이스와 유사한 5-10GB입니다.

설정 지침

GitLab을 Linux 패키지를 사용하여 설치한 경우에는 다음 단계를 따르세요:

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

준비

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

PostgreSQL 서버를 제공하세요. Linux 패키지와 함께 제공되는 PostgreSQL을 사용하여 PostgreSQL 데이터베이스를 구성해야 합니다. 외부 PostgreSQL 서버(버전 11 이상)를 사용할 수도 있지만 수동으로 설정해야 합니다.

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

  • 1개의 PostgreSQL 노드
  • 1개의 PgBouncer 노드 (선택 사항)
  • 최소 1개의 Praefect 노드 (최소 저장 공간 필요)
  • 3개의 Gitaly 노드 (높은 CPU, 높은 메모리, 빠른 저장소)
  • 1개의 GitLab 서버

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

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

Google Cloud Platform, SoftLayer 또는 가상 사설 클라우드(VPC)를 제공하는 기타 공급업체를 사용하는 경우 각 클라우드 인스턴스에 대한 사설 주소(구글 클라우드 플랫폼의 “내부 주소”에 해당)를 사용하여 PRAEFECT_HOST, GITALY_HOST_*, GITLAB_HOST를 사용할 수 있습니다.

비밀 정보

구성 요소 간의 통신은 다양한 비밀 토큰으로 보호됩니다. 아래에서 설명하는 이 비밀 토큰을 생성하고 메모해두세요. 이를 통해 설치 프로세스를 완료하는 동안 이러한 플레이스홀더 토큰을 안전한 토큰으로 교체할 수 있습니다.

  1. GITLAB_SHELL_SECRET_TOKEN: 이는 깃 훅에서 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에 연결합니다. 자세한 내용은 번들된 PgBouncer 문서를 참조하세요.

아래의 지침에서 이러한 비밀 정보가 필요한 위치를 알려드립니다.

참고: 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

참고: Geo를 사용하는 경우 GitLab 애플리케이션 데이터베이스와 Praefect 데이터베이스를 동일한 PostgreSQL 서버에 저장하지 마세요. 복제 상태는 각 GitLab 인스턴스에 대해 내부적으로 유지되어야 하며 복제되어서는 안됩니다.

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

다음 옵션이 있습니다:

PostgreSQL 설정은 Praefect 테이블을 비웁니다. 자세한 내용은 관련 문제 해결 섹션을 참조하세요.

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

GitLab 응용프로그램 데이터베이스와 Praefect 데이터베이스는 동일한 서버에서 실행될 수 있습니다. 그러나 PostgreSQL을 Linux 패키지에서 사용할 때는 Praefect가 자체 데이터베이스 서버를 가져야 합니다. 장애 조치(failover)가 발생하면 Praefect는 알지 못하고 사용하려는 데이터베이스가 다음과 같은 이유로 실행되지 않거나 읽기 전용 모드로 전환되어 실패합니다.

  • 사용할 수 없는 상태일 수 있음.
  • 읽기 전용 모드일 수 있음.

수동 데이터베이스 설정

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

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

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

다음 지침을 실행하려면 Linux 패키지에 설치된 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를 사용할 때 추가 작업을 수행해야 합니다. 백엔드로 Linux 패키지에서 제공하는 PostgreSQL을 사용하는 것을 강력히 권장합니다. 다음 지침은 Linux 패키지 제공 PostgreSQL에서만 작동합니다.

Linux 패키지에서 제공되는 PgBouncer를 위해 praefect 암호의 해시를 실제 암호 대신 사용해야 합니다:

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

<PRAEFECT_SQL_PASSWORD_HASH>는 준비 단계에서 생성한 암호의 해시로 대체합니다. md5 리터럴로 접두어가 붙습니다.

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 기능을 사용하고 PostgreSQL에서 cache invalidation을 위한 Praefect로의 알림을 받을 수 있습니다.

Praefect 로그에 다음과 같은 로그 항목을 확인하여 이 기능이 작동하는지 확인합니다:

reads distribution caching is enabled by configuration

PgBouncer 사용

PostgreSQL 리소스 소비를 줄이기 위해 PgBouncer를 설정하고 구성해야 합니다. 그러나 Praefect가 낮은 수의 연결을 만드므로 PgBouncer가 필수적이지는 않습니다. PgBouncer를 사용하기로 결정한 경우 GitLab 응용프로그램 데이터베이스와 Praefect 데이터베이스 모두에 동일한 PgBouncer 인스턴스를 사용할 수 있습니다.

PostgreSQL 인스턴스 앞에 PgBouncer를 구성하려면 Praefect 구성에서 데이터베이스 매개변수를 PgBouncer를 가리키도록 설정해야 합니다.

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

Praefect는 LISTEN 기능을 지원하는 PostgreSQL에 대한 추가 연결을 필요로 합니다. 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를 구성할 수 있습니다.

참고: Linux 패키지 설치는 인증 요구 사항을 처리하지만, 데이터베이스를 수동으로 구성하고 외부 PgBouncer를 구성하는 경우 auth_file 구성 옵션을 설정한 경우 praefect 사용자와 해당 비밀번호를 PgBouncer에서 사용하는 파일에 포함해야 합니다. 자세한 내용은 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 서버가 필요합니다.

경고: 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'] = {
       # ...
       #
       # Praefect에 대한 Prometheus 메트릭 액세스를 활성화합니다. 방화벽을 사용하여이 주소/포트의 액세스를 제한해야 합니다.
       # 기본 메트릭 엔드포인트는 /metrics입니다
       prometheus_listen_addr: '0.0.0.0:9652',
       # 일부 메트릭은 데이터베이스에서 쿼리를 실행합니다. 별도의 데이터베이스 메트릭을 활성화하여
       # 이러한 메트릭이 스크래핑될 때 수집되도록합니다.
       prometheus_exclude_database_from_default_metrics: true,
    }
    
  3. /etc/gitlab/gitlab.rb를 편집하여 Praefect에 대한 강력한 인증 토큰을 구성합니다.

    praefect['configuration'] = {
       # ...
       auth: {
          # ...
          token: 'PRAEFECT_EXTERNAL_TOKEN',
       },
    }
    
  4. Praefect 클러스터가 PostgreSQL 데이터베이스에 연결하도록 구성합니다. 또한 PgBouncer를 사용하는 것이 좋습니다.

    TLS 클라이언트 인증서를 사용하려면 다음 옵션을 사용할 수 있습니다:

    praefect['configuration'] = {
       # ...
       database: {
          # ...
          #
          # TLS 클라이언트 인증서를 사용하여 PostgreSQL에 연결합니다
          # sslcert: '/path/to/client-cert',
          # sslkey: '/path/to/client-key',
          #
          # 사용자 정의 인증 기관 신뢰
          # sslrootcert: '/path/to/rootcert',
       },
    }
    

    기본적으로 Praefect는 PostgreSQL로 암호화되지 않은 연결을 거부합니다. 다음 줄에서 오버라이드할 수 있습니다:

    praefect['configuration'] = {
       # ...
       database: {
          # ...
          # sslmode: 'disable',
       },
    }
    
  5. Praefect 클러스터가 클러스터의 각 Gitaly 노드에 연결하도록 /etc/gitlab/gitlab.rb를 편집합니다.

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

    경고: 이미 존재하는 default라는 이름의 저장소에 데이터가 있는 경우 가상 저장소 이름을 다른 이름으로 구성하고 Gitaly 클러스터 저장소로 데이터를 마이그레이션해야합니다.

    PRAEFECT_INTERNAL_TOKEN을 강력한 비밀로 바꿔서 Praefect이 클러스터 내의 Gitaly 노드와 통신할 때 사용하는 토큰입니다. 이 토큰은 PRAEFECT_EXTERNAL_TOKEN과 다릅니다.

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

    더 많은 Gitaly 노드를 추가하여 복제본 수를 늘릴 수 있습니다. 매우 큰 GitLab 인스턴스의 경우 추가 클러스터를 추가할 수도 있습니다.

    참고: 가상 저장소에 추가적인 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'
                },
             ],
          },
       ],
    }
    
  6. /etc/gitlab/gitlab.rb에 대한 변경 사항을 저장하고 Praefect을 다시 구성합니다.

    gitlab-ctl reconfigure
    
  7. 다음 단계를 위해 배포 노드에서:

    • Praefect 데이터베이스 자동 마이그레이션을 다시 활성화하려면 /etc/gitlab/gitlab.rbpraefect['auto_migrate'] = true로 설정하십시오.
    • 마이그레이션이 업그레이드 중 자동으로 실행되지 않도록 하려면 다음 절차를 수행하십시오.

      sudo touch /etc/gitlab/skip-auto-reconfigure
      
    • 서버 재구성을 실행하는 대신 추가 절차를 수행할 수 있도록 /etc/gitlab/skip-auto-reconfigure를 설정할 필요는 없지만, 처음부터 명령줄을 통해 apt-get update 등을 실행할 때 서버의 자동 재구성을 방지하려면 이를 설정할 수 있습니다. 추가 구성 변경 사항을 수행한 뒤 재구성을 수동으로 실행할 수 있습니다.
  8. /etc/gitlab/gitlab.rb에 대한 변경 사항을 저장하고 Praefect을 다시 구성합니다.

    gitlab-ctl reconfigure
    
  9. Praefect가 Prometheus의 대기 주소를 업데이트하도록하려면 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를 활성화한 상태에서 dial-nodeslist-untracked-repositories와 같은 Praefect 하위 명령을 커맨드 라인에서 실행할 때, 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 모두 구성할 수 있습니다. 필요한 경우, 이를 통해 암호화되지 않은 트래픽에서 암호화된 트래픽으로 단계적으로 전환할 수 있습니다.

    암호화되지 않은 수신기를 비활성화하려면 다음을 설정하세요:

    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. 파일을 저장하고 재구성하세요.

  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 서버 인증서 또는 인증서 기관을 시스템 신뢰 인증서로 복사하여 Gitaly 서버에서 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을 다시 시작하세요.

서비스 검색

  • GitLab 15.10에 도입되었습니다(https://gitlab.com/groups/gitlab-org/-/epics/8971).

전제 조건:

  • DNS 서버가 있어야 함.

GitLab은 서비스 검색을 사용하여 Praefect 호스트의 목록을 검색합니다. 서비스 검색에는 DNS A 또는 AAAA 레코드의 주기적인 확인이 관련되며, 레코드에서 검색된 IP가 대상 노드의 주소로 작용합니다. Praefect는 SRV 레코드에 의한 서비스 검색을 지원하지 않습니다.

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

  • 새 IP 주소로의 새 연결 설정.
  • 기존 IP 주소로의 기존 연결 유지.
  • 제거된 IP 주소로의 연결 삭제.

제거될 연결에서 발신 중인 요청은 완료될 때까지 처리됩니다. Workhorse에는 10분의 타임아웃이 있으며, 다른 클라이언트에는 타임아웃이 명시되어 있지 않습니다.

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

클라이언트 구성을 업데이트하기 전에 DNS 서비스 검색이 올바르게 작동하는지 확인하세요. 이는 IP 주소 목록을 올바르게 반환해야 합니다. 확인하는 데 사용할 수 있는 좋은 도구는 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://[권한있는_호스트]:[권한_포트]/[호스트]:[포트]
Linux 패키지 (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 주소가 dig A praefect.service.consul @CONSUL_SERVER -p 8600로 등록되었는지 확인하세요. 위의 단계에서 구성한 값을 사용하고 모든 Praefect 노드 IP 주소가 출력에 나와야 합니다.
  6. 파일을 저장하고 GitLab을 다시 시작하세요.

Gitaly

참고: 각 Gitaly 노드에 대해 다음 단계를 완료하십시오.

이 섹션을 완료하려면 다음이 필요합니다: - 구성된 Praefect 노드 - GitLab이 설치된 3대 이상의 서버를 Gitaly 노드로 구성합니다. 이러한 노드들은 전용 노드여야 하며, 이러한 노드에서 다른 서비스를 실행하지 마십시오.

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. 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 노드에서 gitaly['configuration'][:storage]를 고유하게 구성하는 대신, 모든 Gitaly 노드의 구성을 모든 Gitaly 노드에 포함시키는 것이 종종 더 쉽습니다. 이것은 Praefect virtual_storage 구성이 각 저장소 이름(예: gitaly-1)을 특정 노드에 매핑하고 요청이 그에 따라 경로로 지정되기 때문에 가능합니다. 이것은 귀하의 플릿에있는 모든 Gitaly 노드가 동일한 구성을 공유할 수 있음을 의미합니다.

    # 이전 단계에서 주소가 제공된대로 Praefect가 작업을 경로로 선정할 수 있기 때문에
    # 이와 같이 모든 노드에 대한 데이터 디렉토리를 구성할 수 있습니다.
    gitaly['configuration'] = {
       # ...
       storage: [
         {
           name: 'gitaly-1',
           path: '/var/opt/gitlab/git-data/repositories',
         },
         {
           name: 'gitaly-2',
           path: '/var/opt/gitlab/git-data/repositories',
         },
         {
           name: 'gitaly-3',
           path: '/var/opt/gitlab/git-data/repositories',
         },
       ],
    }
    
  8. 변경 내용을 /etc/gitlab/gitlab.rb에 저장하고, Gitaly을 다시 구성합니다:

    gitlab-ctl reconfigure
    
  9. Gitaly가 프로메테우스 수신 주소를 업데이트했는지 확인하고, Gitaly을 다시 시작하십시오:

    gitlab-ctl restart gitaly
    

위의 단계는 반드시 각 Gitaly 노드에서 완료되어야 합니다!

모든 Gitaly 노드가 구성된 후, Praefect가 Praefect 구성의 모든 Gitaly 서버에 연결할 수 있는지 확인하기 위해 Praefect 연결 확인기를 실행하십시오.

  1. Praefect 노드에 SSH하여 Praefect 연결 확인기를 실행하십시오:

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

로드 밸런서

고가용성 Gitaly 구성에서는 로드 밸런서가 필요하여 GitLab 애플리케이션에서 Praefect 노드로의 내부 트래픽을 라우팅해야 합니다. 어떤 로드 밸런서를 사용해야 하는지 또는 정확한 구성은 GitLab 설명서의 범위를 벗어납니다.

참고: 로드 밸런서는 GitLab 노드로부터의 트래픽을 수락하도록 구성되어야 합니다.

우리는 GitLab과 같은 고가용성 시스템을 관리한다면 이미 선호하는 로드 밸런서를 가지고 있을 것으로 기대합니다. 몇 가지 예시는 HAProxy(오픈 소스), Google Internal Load Balancer, AWS Elastic Load Balancer, F5 Big-IP LTM, 및 Citrix Net Scaler가 있습니다. 이 설명서는 구성해야 하는 포트와 프로토콜에 대해 설명합니다.

참고: 오래 실행되는 작업(예: 복제)으로 인해 일부 연결이 긴 시간 동안 열려 있으므로 HAProxy leastconn 로드 밸런싱 전략과 동등한 것을 사용해야 합니다.

LB 포트 백엔드 포트 프로토콜
2305 2305 TCP

GitLab

이 섹션을 완료하려면:

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

특별히 다음을 주의 깊게 살펴봐야 합니다:

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

    sudo -i
    
  2. /etc/gitlab/gitlab.rb를 편집하여 올바른 엔드포인트에 의해 GitLab에서 파일을 제공할 수 있도록 external_url을 구성합니다:

    GITLAB_SERVER_URL을 현재 GitLab 인스턴스가 제공되는 실제 외부 URL로 교체해야 합니다:

    external_url 'GITLAB_SERVER_URL'
    
  3. 기본 Gitaly 서비스를 비활성화합니다. 구성된 클러스터에 GitLab이 연결되어 있기 때문에 필요하지 않습니다.

    경고: 기본 Gitaly 저장소에 기존 데이터가 있는 경우, 먼저 데이터를 Gitaly 클러스터 저장소로 이전해야 합니다.

    gitaly['enable'] = false
    
  4. /etc/gitlab/gitlab.rb를 수정하여 Praefect 클러스터를 저장 위치로 추가합니다.

    다음을 교체해야 합니다:

    • PRAEFECT_LOADBALANCER_HOST를 로드 밸런서의 IP 주소 또는 호스트 이름으로 교체합니다.
    • PRAEFECT_EXTERNAL_TOKEN을 실제 비밀로 교체합니다.

    TLS를 사용하는 경우:

    • gitaly_addresstls://로 시작해야 합니다.
    • 포트를 3305로 변경해야 합니다.
    git_data_dirs({
      "default" => {
        "gitaly_address" => "tcp://PRAEFECT_LOADBALANCER_HOST:2305",
        "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
      }
    })
    
  5. git push 중 Gitaly 노드로부터의 콜백이 올바르게 인증되도록 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. /etc/gitlab/gitlab.rb를 수정하여 Prometheus 모니터링 설정을 추가합니다. Prometheus가 다른 노드에서 사용 중인 경우 해당 노드에서 편집합니다.

    다음을 교체해야 합니다:

    • PRAEFECT_HOST를 Praefect 노드의 IP 주소 또는 호스트 이름으로 교체합니다.
    • GITALY_HOST_*을 각 Gitaly 노드의 IP 주소 또는 호스트 이름으로 교체합니다.
    prometheus['scrape_configs'] = [
      {
        'job_name' => 'praefect',
        'static_configs' => [
          'targets' => [
            'PRAEFECT_HOST:9652', # praefect-1
            'PRAEFECT_HOST:9652', # praefect-2
            'PRAEFECT_HOST:9652', # praefect-3
          ]
        ]
      },
      {
        'job_name' => 'praefect-gitaly',
        'static_configs' => [
          'targets' => [
            'GITALY_HOST_1:9236', # gitaly-1
            'GITALY_HOST_2:9236', # gitaly-2
            'GITALY_HOST_3:9236', # gitaly-3
          ]
        ]
      }
    ]
    
  7. 변경 사항을 /etc/gitlab/gitlab.rb에 저장하고 GitLab을 재구성합니다:

    gitlab-ctl reconfigure
    
  8. 각 Gitaly 노드에서 Git Hooks가 GitLab에 도달하는지 확인합니다. 각 Gitaly 노드에서 다음을 실행합니다:
    • GitLab 15.3 이상의 경우, sudo /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml을 실행합니다.
    • GitLab 15.2 이하의 경우, sudo /opt/gitlab/embedded/bin/gitaly-hooks check /var/opt/gitlab/gitaly/config.toml을 실행합니다.
  9. GitLab이 Praefect에 도달하는지 확인합니다.

    gitlab-rake gitlab:gitaly:check
    
  10. Praefect 저장소가 새 저장소를 저장하기 위해 구성되었는지 확인합니다.

    1. 왼쪽 사이드바에서 관리 영역을 선택합니다.
    2. 왼쪽 사이드바에서 설정 > 저장소를 선택합니다.
    3. 저장소 저장소 섹션을 확장합니다.

    이 가이드를 따르면 default 저장소가 모든 새 저장소를 저장하기 위해 가중치 100을 가져야 합니다.

  11. “README로 리포지토리 초기화” 상자를 선택하여 새 프로젝트를 생성하여 모든 것이 작동하는지 확인합니다. 프로젝트가 생성되고 README 파일을 확인할 수 있다면 작동합니다!

기존 GitLab 인스턴스에 TCP 사용

기존 Gitaly 인스턴스에 Gitaly 클러스터를 추가할 때는 기존 Gitaly 저장소가 TCP/TLS를 수신 대기해야 합니다. gitaly_address가 지정되지 않은 경우 Unix 소켓이 사용되어 클러스터와의 통신을 방해합니다.

예시:

git_data_dirs({
  'default' => { 'gitaly_address' => 'tcp://old-gitaly.internal:8075' },
  'cluster' => {
    'gitaly_address' => 'tls://<PRAEFECT_LOADBALANCER_HOST>:3305',
    'gitaly_token' => '<praefect_external_token>'
  }
})

다중 Gitaly 저장소를 실행하는 세부 정보는 혼합 구성을 참조하세요.

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 서버의 /-/grafana (예: https://gitlab.example.com/-/grafana)를 엽니다.

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

  6. Explor로 이동하고 gitlab_build_info를 조회하여 모든 기계에서 메트릭을 가져오는지 확인합니다.

축하합니다! 가시적인 고장 허용 Praefect 클러스터를 구성했습니다.

복제 요소 구성

Praefect는 저장소별로 복제 요소를 구성할 수 있도록 지원하며, 이를 통해 특정 저장소를 호스팅하는 특정 저장소 노드를 할당할 수 있습니다.

경고: 구성 가능한 복제 요소는 저장소별 기본 노드를 필요로 합니다.

Praefect는 실제 복제 요소를 저장하지 않지만, 원하는 복제 요소에 충족되도록 충분한 저장소를 할당합니다. 나중에 저장소 노드가 가상 저장소에서 제거되면 해당 저장소에 할당된 복제 요소가 줄어듭니다.

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

  • 새로 생성된 저장소에 적용되는 각 가상 저장소의 기본 복제 요소.
  • set-replication-factor 하위 명령을 사용하여 기존 저장소에 대한 복제 요소를 구성합니다.

기본 복제 요소 구성

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

많은 저장소 노드가 있는 대규모 Gitaly 클러스터 배포의 경우 모든 저장소 노드에 저장소를 복제하는 것은 종종 합리적이지 않으며 문제를 유발할 수 있습니다. 일반적으로 복제 요소 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 <virtual-storage> -repository <relative-path> -replication-factor <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

현재 할당된 호스트 저장소: gitaly-1, gitaly-2

저장소 저장소 권장 사항

필요한 저장소 크기는 인스턴스마다 다를 수 있으며 복제 요소(factor)에 따라 다릅니다. 저장소 저장소 이중화를 구현할 수 있습니다.

복제 요소에 대해:

  • 1의 경우: Gitaly 및 Gitaly Cluster의 저장소 요구 사항은 대략적으로 동일합니다.
  • 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"
      ]
    }
  }
}

확인 워커 구성

기본적으로 워커는 메타데이터 레코드를 7일마다 확인합니다. 확인 간격은 유효한 Go duration string으로 구성할 수 있습니다.

메타데이터를 3일마다 확인하려면:

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

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

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

삭제 활성화

경고: 삭제는 이전에 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 노드로 장애 조치를 실행합니다.

Repository-specific primary nodes을 사용해야 합니다. 이것은 GitLab 14.0에서 유일하게 사용 가능한 선출 전략입니다.

Repository-specific primary nodes

  • GitLab 13.12에서 소개되었으며, Praefect가 시작되거나 클러스터의 Gitaly 노드 상태의 합의가 변경될 때 주요 선출이 실행됩니다.
  • GitLab 14.1에서 변경되어, 주요 선출은 지연해서 실행됩니다.

Gitaly 클러스터는 각 저장소별로 별도의 주요 Gitaly 노드를 선출합니다. 구성 가능한 복제 인자와 결합하여 저장 용량을 수평 확장하고 쓰기 부하를 Gitaly 노드에 골고루 분산시킬 수 있습니다.

주요 선출은 지연해서 실행됩니다. Praefect는 현재 주요 노드가 불건전한 경우 즉시 새로운 주요 노드를 선출하지 않습니다. 현재 주요 노드가 사용 불가능한 상태에서 요청을 처리해야 하는 경우 새로운 주요 노드가 선출됩니다.

유효한 주요 노드 후보는 다음 조건을 충족해야 합니다:

  • 건강해야 합니다. Gitaly 노드는 최근 10초 동안 >=50% Praefect 노드가 성공적으로 건강 검사를 한 경우 건강하다고 간주됩니다.
  • 저장소의 완전히 최신 복사본을 보유해야 합니다.

여러 주요 노드 후보가 있는 경우, Praefect는 다음과 같은 방식으로 선택합니다:

  • 그 중 하나를 무작위로 선택합니다.
  • 저장소를 호스트로 할당받은 Gitaly 노드를 우선하여 주요 노드로 승격시킵니다. 저장소에 할당된 Gitaly 노드가 없는 경우 Praefect는 일시적으로 할당되지 않은 노드를 선출할 수 있습니다. 할당된 노드가 사용 가능해지면 할당되지 않은 주요 노드는 우선 순위에 따라 하락됩니다.

저장소에 유효한 주요 후보가 없는 경우:

  • 불건전한 주요 노드가 하락되고 저장소에 주요 노드가 없는 상태로 남겨집니다.
  • 주요 노드가 성공적으로 선출될 때까지 주요 노드가 필요한 작업은 실패합니다.

저장소별 주요 Gitaly 노드로 마이그레이션하기

새로운 Gitaly 클러스터는 즉시 per_repository 선출 전략을 사용할 수 있습니다.

기존 클러스터를 마이그레이션하려면:

  1. Praefect 노드는 기존에 클러스터에 저장된 각 저장소에 대한 데이터베이스 레코드를 보관하지 않았습니다. per_repository 선출 전략이 구성되면 Praefect는 각 저장소의 데이터베이스 레코드가 있다고 예상합니다. 마이그레이션 전에 Praefect의 로그를 확인하여 저장소의 누락된 데이터베이스 레코드가 작성되었는지 확인하세요.

    repository importer finished 메시지가 Praefect의 로그에 있는지 확인하세요. virtual_storages 필드에는 가상 저장소의 이름과 누락된 데이터베이스 레코드가 작성되었는지 여부가 나타납니다.

    예를 들어, default 가상 저장소가 성공적으로 마이그레이션된 경우:

    {"level":"info","msg":"repository importer finished","pid":19752,"time":"2021-04-28T11:41:36.743Z","virtual_storages":{"default":true}}
    

    가상 저장소가 성공적으로 마이그레이션되지 않은 경우 false가 나타납니다:

    {"level":"info","msg":"repository importer finished","pid":19752,"time":"2021-04-28T11:41:36.743Z","virtual_storages":{"default":false}}
    

    데이터베이스 마이그레이션은 Praefect가 시작될 때 실행됩니다. 데이터베이스 마이그레이션이 실패한 경우 Praefect 노드를 다시 시작하여 재시도할 수 있습니다.

  2. 서로 다른 선출 전략을 함께 실행하는 것은 저장소가 서로 다른 주요를 가지고 있다고 판단하는 분산 머리를 유발할 수 있습니다. 이를 피하는 방법은 다음과 같습니다:

    • 짧은 다운타임이 허용될 경우:

      1. 선출 전략을 변경하기 전 Praefect 노드를 모두 종료합니다. Praefect 노드에서 gitlab-ctl stop praefect를 실행하여 이 작업을 수행합니다.

      2. Praefect 노드에서 /etc/gitlab/gitlab.rb에서 선출 전략을 praefect['failover_election_strategy'] = 'per_repository'로 구성합니다.

      3. Praefect 노드를 다시 구성하고 시작하기 위해 gitlab-ctl reconfigure && gitlab-ctl start를 실행합니다.

    • 다운타임이 허용되지 않을 경우:

      1. 현재 주요 Gitaly 노드가 무엇인지 확인합니다.

      2. Praefect 노드에 모두 있는 /etc/gitlab/gitlab.rb에서 가상 저장소의 구성에서 보조 Gitaly 노드를 주석 처리합니다. 이를 통해 구성된 Gitaly 노드가 하나뿐이므로 양쪽 선출 전략이 동일한 주요 Gitaly 노드를 선출하도록 보장합니다.

      3. 모든 Praefect 노드에서 gitlab-ctl reconfigure를 실행합니다. 이 작업은 모든 Praefect 프로세스가 재시작되고 이전 프로세스가 종료될 때까지 기다립니다. 이 과정은 최대 1분까지 소요될 수 있습니다.

      4. 모든 Praefect 노드에서 /etc/gitlab/gitlab.rb에서 선출 전략을 praefect['failover_election_strategy'] = 'per_repository'로 구성합니다.

      5. 모든 Praefect 노드에서 gitlab-ctl reconfigure를 실행합니다. 모든 Praefect 프로세스가 재시작되고 이전 프로세스가 종료될 때까지 기다립니다. 이 과정은 최대 1분까지 소요될 수 있습니다.

      6. 모든 Praefect 노드에서 이전 단계에서 주석 처리한 보조 Gitaly 노드 구성을 다시 활성화합니다.

      7. 모든 Praefect 노드에서 gitlab-ctl reconfigure를 실행하여 Praefect 프로세스를 다시 구성하고 시작합니다.