Gitaly 클러스터 구성

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

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

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

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

요구 사항

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

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

Gitaly 노드 중 하나에서의 변이 RPC 호출 실패 시 트랜잭션이 판별자를 가지도록 Gitaly 노드를 홀수로 구성해야 합니다.

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

note
GitLab에서 설정되지 않은 경우, 기능 플래그는 콘솔에서 false로 읽히고 Praefect는 기본 값을 사용합니다. 기본 값은 GitLab 버전에 따라 다릅니다.

네트워크 지연 및 연결성

Gitaly 클러스터의 네트워크 대기 시간은 원칙적으로 1자리 숫자 밀리초 단위로 측정될 수 있어야 합니다. 대기 시간은 특히 다음에 중요합니다:

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

Gitaly 노드 간의 적절한 대기 시간 달성:

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

복제를 위한 저렴한 네트워크 대기 시간을 제공할 수 없는 경우(예를 들어, 먼 지역간), 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 노드로의 트래픽을 허용하지 않는 한 차단될 수 있습니다.

Praefect 데이터베이스 저장소

데이터베이스에는 다음에 대한 메타데이터만 포함되므로 요구 사항은 비교적 낮습니다:

  • 리포지토리 위치.
  • 일부 대기 중인 작업.

리포지토리 수에 따라 다르지만 GitLab 애플리케이션 데이터베이스와 유사한 5-10GB가 좋은 최소값입니다.

설정 지침

Linux 패키지를 사용하여 GitLab을 설치한 경우, 아래 단계를 따릅니다:

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

준비

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

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

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

  • 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)를 제공하는 기타 업체를 사용하는 경우 PRAEFECT_HOST, GITALY_HOST_*GITLAB_HOST에 대해 각 클라우드 인스턴스의 사설 주소(“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 문서를 참조하세요.

위에서 이러한 비밀이 필요한 지침 아래에 기록합니다.

참고: Linux 패키지 설치에서는 gitlab-secrets.jsonGITLAB_SHELL_SECRET_TOKEN에 대해 사용할 수 있습니다.

시간 서버 설정 사용자화

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

  • Gitaly 노드에 대해 gitaly['env'] = { "NTP_HOST" => "ntp.example.com" }를 추가하세요.
  • Praefect 노드에 대해 praefect['env'] = { "NTP_HOST" => "ntp.example.com" }를 추가하세요.

PostgreSQL

참고: 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 패키지가 설치된 Praefect 노드(/opt/gitlab/embedded/bin/psql에서 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 패키지로 제공된 PostgreSQL에서만 작동합니다:

  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 데이터베이스 오류를 확인하려면 문제 해결 단계를 참조하세요.

Reads distribution caching

Praefect의 성능을 향상시키기 위해 session_pooled 설정을 추가로 구성함으로써 세션 풀링의 프로퍼티들을 구성할 수 있습니다:

praefect['configuration'] = {
   # ...
   database: {
      # ...
      session_pooled: {
         # ...
         host: POSTGRESQL_HOST,
         port: 5432

         # 직접적인 데이터베이스 연결의 파라미터들을 오버라이드하기 위해 다음을 사용하세요.
         # 두 연결의 파라미터가 같을 경우 주석처리하세요.
         user: 'praefect',
         password: PRAEFECT_SQL_PASSWORD,
         dbname: 'praefect_production',
         # sslmode: '...',
         # sslcert: '...',
         # sslkey: '...',
         # sslrootcert: '...',
      }
   }
}

이 구성이 완료되면, 이 연결은 PostgreSQL로부터 캐시 무효화에 대한 통지를 Praefect에게 가능하게 합니다.

이 기능이 작동하는지 확인하려면 Praefect 로그에서 다음과 같은 로그 항목을 찾으세요:

reads distribution caching is enabled by configuration

PgBouncer 사용

PostgreSQL 리소스 소비를 줄이기 위해, 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 데이터베이스 엔드포인트를 사용하여 새로운 PgBouncer 데이터베이스를 구성하되, 다른 풀 모드 (pool_mode = session)를 사용합니다.
  • PgBouncer를 우회하여 Praefect를 직접적으로 PostgreSQL에 연결합니다.

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를 사용합니다.

참고: 리눅스 패키지 설치는 인증 요구사항을 처리합니다(auth_query 사용), 그러나 데이터베이스를 수동으로 준비하고 외부 PgBouncer를 구성하는 경우, PgBouncer 문서를 참고하여 praefect 사용자 및 해당 암호를 사용하여 해당 파일에 포함해야 합니다. 예를 들어, auth_file(https://www.pgbouncer.org/config.html#auth_file) 구성 옵션을 설정할 경우 userlist.txt를 사용합니다. 자세한 내용은 PgBouncer 문서를 참고하세요.

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

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
   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에 대한 프로메테우스 메트릭 액세스 활성화. 방화벽을 사용하여
       #이 주소/포트에 대한 액세스를 제한해야 합니다.
       # 기본 메트릭 엔드포인트는 /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. PraefectPostgreSQL 데이터베이스에 연결하도록 구성. PgBouncer 사용을 강력히 권장합니다.

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

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

    기본적으로 Praefect는 기회가 있는 TLS를 사용하여 PostgreSQL에 연결합니다. 이는 Praefect가 sslmodeprefer로 설정하여 PostgreSQL에 연결을 시도합니다. 다음 줄을 주석 처리하여 이를 재정의할 수 있습니다:

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

    가상 저장소의 이름은 GitLab 구성의 git_data_dirs와 Gitaly 노드의 gitaly[‘configuration’][:storage][INDEX][:name]과 일치해야 합니다. 나중 단계에서 저장소 이름을 default로 구성하므로 여기서도 default를 사용합니다. 본 클러스터에는 각각 gitaly-1, gitaly-2, gitaly-3라는 세 개의 Gitaly 노드가 포함되어 있습니다. 복제본을 의도한 것입니다.

    경고: 이미 “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['configuration'][:storage][INDEX][:name]('gitaly-1')와 일치해야 합니다
    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. 다음과 같은 경우:

    • “배포 노드”는:
      1. /etc/gitlab/gitlab.rb에서 praefect['auto_migrate'] = true로 설정하여 Praefect 데이터베이스 자동 마이그레이션을 다시 활성화합니다.
      2. 마이그레이션을 다시 구성 중에만 데이터베이스 마이그레이션이 실행되고 자동으로 업그레이드되지 않으며 다음과 같이 실행합니다:

        sudo touch /etc/gitlab/skip-auto-reconfigure
        
    • 다른 노드의 경우 설정을 그대로 둘 수 있습니다. 그러나 /etc/gitlab/skip-auto-reconfigure가 필요하지는 않지만 apt-get update 등의 명령을 실행할 때 GitLab이 자동으로 재구성되지 않도록하기 위해 추가 구성 변경이 완료된 후 수동으로 다시 구성할 수 있습니다.
  8. /etc/gitlab/gitlab.rb에 대한 변경 사항을 저장하고 Praefect를 다시 구성:

    gitlab-ctl reconfigure
    
  9. Praefect를 프로메테우스가 수신하는 주소를 업데이트 확인하도록 하십시오. 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 서버에 해당하는 인증서를 설치해야 합니다.

또한 인증서 또는 해당 인증서 기관은 모든 Gitaly 서버 및 해당 절차에 따라 통신하는 모든 Praefect 클라이언트에 설치되어 있어야 합니다. 이에 대한 절차는 GitLab 사용자 정의 인증서 구성에서 설명되어 있으며 아래에서 다시 설명합니다.

다음 사항을 주의하세요.

  • 인증서에는 Praefect 서버에 액세스하는 주소를 지정해야 합니다. 호스트명 또는 IP 주소를 인증서의 대체 주체 이름으로 추가해야 합니다.
  • dial-nodeslist-untracked-repositories와 같은 Praefect 하위 명령을 Gitaly TLS가 활성화된 상태에서 명령줄에서 실행하는 경우 SSL_CERT_DIR 또는 SSL_CERT_FILE 환경 변수를 설정하여 Gitaly 인증서가 신뢰되도록 해야 합니다. 예를 들어:

     SSL_CERT_DIR=/etc/gitlab/trusted-certs sudo -u git -- /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. 파일을 저장하고 GitLab을 다시 구성하세요.

  5. Praefect 클라이언트(각 Gitaly 서버 포함)에서 인증서 또는 해당 인증서 기관을 /etc/gitlab/trusted-certs에 복사하세요.

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

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

Self-compiled 설치의 경우:

  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.ymlstorages를 다음과 같이 편집하세요.

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

  6. Praefect 서버의 모든 인증서 또는 해당 인증서 기관을 각 Gitaly 서버의 시스템 신뢰 인증서로 복사하여 Praefect 서버가 Gitaly 서버에서 호출될 때 해당 인증서를 신뢰하도록 하세요.

    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 서비스 검색이 올바르게 작동하는지 확인하세요. 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. DNS 서비스 디스커버리 주소에 각 Praefect 노드의 IP 주소를 추가합니다.
  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. dig를 사용하여 Praefect 클라이언트에서 praefect.service.consul에 각 IP 주소가 등록됐는지 확인합니다. dig A praefect.service.consul @CONSUL_SERVER -p 8600을 사용합니다. CONSUL_SERVER를 위에서 구성한 값으로 대체하고 모든 Praefect 노드 IP 주소가 출력에 나타나야 합니다.
  6. 파일을 저장하고 GitLab을 다시 구성하세요.

Gitaly

참고: 각각의 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). 이 문서에서는 PRAEFECT_INTERNAL_TOKEN을 플레이스홀더로 사용합니다.
  • 이 섹션에서 구성된 gitaly['configuration'][:storage]의 물리적 스토리지 이름은 Praefect 노드의 praefect['configuration'][:virtual_storage]에서 물리적 스토리지 이름과 일치해야 합니다. 이것은 이전 섹션에서 설정되었습니다(praefect). 이 문서에서는 gitaly-1, gitaly-2, gitaly-3을 물리적 스토리지 이름으로 사용합니다.

Gitaly 서버 구성에 대한 자세한 내용은 Gitaly 문서를 참조하세요.

  1. Gitaly 노드에 SSH로 로그인하여 루트로 전환하세요.

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

    # Gitaly 노드에서 다른 모든 서비스를 비활성화합니다
    postgresql['enable'] = false
    redis['enable'] = false
    nginx['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. 강력한 auth_tokenGitaly에 구성하여 Gitaly 클라이언트가 이 Gitaly 노드와 통신하기 위해 필요합니다. 일반적으로 이 토큰은 모든 Gitaly 노드에 대해 동일합니다.

    gitaly['configuration'] = {
       # ...
       auth: {
          # ...
          token: 'PRAEFECT_INTERNAL_TOKEN',
       },
    }
    
  5. gitlab_shell 비밀 토큰을 설정합니다. 이 토큰은 git push 작업에 필요합니다. 둘 중 하나의 방법을 사용하세요.

    • 방법 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. gitlab-shell API 콜백 URL을 구성합니다. 이것은 git push 실패를 방지하기 위해 필요합니다.

    # gitlab-shell API 콜백 URL을 구성합니다. 이것이 없으면 `git push`가 실패합니다.
    이것은 프런트 도어 GitLab URL이나 내부 로드 밸런서가   있습니다.
    : 'https://gitlab.example.com', 'http://10.0.2.2'
    gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
    
  7. /etc/gitlab/gitlab.rb에서 gitaly['configuration'][:storage]를 설정하여 Git 데이터의 저장 위치를 구성합니다. 각 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가 프로메테우스 리스닝 주소를 업데이트했는지 확인하기 위해 Gitaly을 다시 시작하십시오.

    gitlab-ctl restart gitaly
    

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

모든 Gitaly 노드가 구성된 후 Praefect 연결 확인기를 실행하여 Praefect가 Praefect 구성에서 모든 Gitaly 서버에 연결할 수 있는지 확인하세요.

  1. Praefect 노드에서 SSH를 통해 각 Praefect 노드에 연결 확인기를 실행하세요.

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

로드 밸런서

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

참고: 로드 밸런서는 Gitaly 노드로부터의 트래픽을 받아들이도록 구성되어야 합니다. 추가로 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를 업데이트하여 수행됩니다.

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

  • 이 섹션에 추가된 저장 이름은 이 가이드의 Praefect 섹션에서 설정한 Praefect 노드의 praefect['configuration'][:virtual_storage] 하위의 저장 이름과 일치해야 합니다. 이 문서에서는 default를 Praefect 저장 이름으로 사용합니다.
  1. GitLab 노드로 SSH로 로그인하고 root로 로그인합니다.

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

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

    external_url 'GITLAB_SERVER_URL'
    
  3. GitLab 호스트에서 실행 중인 기본 Gitaly 서비스를 비활성화합니다. 설정된 클러스터에 GitLab이 연결되므로 필요하지 않습니다.

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

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

    다음을 대체해야합니다:

    • PRAEFECT_LOADBALANCER_HOST를 로드 밸런서의 IP 주소 또는 호스트명으로
    • PRAEFECT_EXTERNAL_TOKEN를 실제 비밀로

    TLS를 사용하는 경우:

    • gitaly_address는 대신 tls://로 시작해야 합니다.
    • 포트를 3305로 변경해야합니다.
    git_data_dirs({
      "default" => {
        "gitaly_address" => "tcp://PRAEFECT_LOADBALANCER_HOST:2305",
        "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
      }
    })
    
  5. /etc/gitlab/gitlab-secrets.json을 Gitaly 클라이언트에서 Gitaly 서버 및 기타 Gitaly 클라이언트에 복사합니다.
  6. Gitaly 서버에서 GitLab 재구성을 실행합니다.

또는:

  1. /etc/gitlab/gitlab.rb를 편집합니다.
  2. GITLAB_SHELL_SECRET_TOKEN을 실제 비밀로 대체합니다.

    gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
    
  3. /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
          ]
        ]
      }
    ]
    
  4. 수정 사항을 /etc/gitlab/gitlab.rb에 저장하고 GitLab 재구성합니다:

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

    gitlab-rake gitlab:gitaly:check
    
  7. Praefect 저장이 새 저장소를 저장하도록 구성됐는지 확인합니다.

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

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

  8. 새 프로젝트를 만들어 모든 것이 작동하는지 확인합니다. “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>'
  }
})

추가 정보는 혼합 구성을 참조하세요. ### Grafana

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

빠르게 시작하려면:

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

    sudo -i
    
  2. /etc/gitlab/gitlab.rb를 편집하여 그라파나 로그인 폼을 활성화합니다.

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

    gitlab-ctl reconfigure
    
  4. 그라파나 관리자 비밀번호를 설정합니다. 이 명령을 실행하면 새로운 비밀번호를 입력하라는 메시지가 표시됩니다.

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

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

  6. 탐색(Explore)에 이동하여 gitlab_build_info를 쿼리하여 모든 기기에서 지표를 받고 있는지 확인합니다.

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

복제 요소 구성

Praefect는 리포지토리별로 복제 요소를 구성할 수 있으며, 리포지토리를 호스팅할 구체적인 저장소 노드를 할당합니다.

경고: 구성 가능한 복제 요소는 리포지토리별 주 노드가 필요합니다.

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 -u git -- /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 -u git -- /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보다 큰 경우: 필요한 저장소 양은 사용 중인 공간 * 복제 요소입니다. 사용 중인 공간에는 계획된 미래 성장이 포함되어야 합니다.

리포지토리 확인

  • 소개: GitLab 15.0에서 도입됨.

Praefect는 리포지토리에 대한 메타데이터를 데이터베이스에 저장합니다. 만약 권장되지 않는 상태에서 디스크에서 수정된다면 메타데이터가 부정확해질 수 있습니다. 예를 들어 Gitaly 노드를 새 노드로 교체하는 대신 다시 작성하는 경우 리포지토리 확인은 이러한 상황을 감지합니다.

이러한 메타데이터는 복제 및 라우팅 결정에 사용되므로 정확하지 않은 경우 문제가 발생할 수 있습니다. Praefent에는 메타데이터를 주기적으로 디스크의 실제 상태와 비교하는 백그라운드 워커가 포함되어 있습니다. 이 워커는:

  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 지속 시간 문자열로 구성할 수 있습니다.

메타데이터를 3일마다 검증하려면:

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

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

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

삭제 기능 활성화

경고: 레파지토리 이름 변경과 관련된 경합 조건으로 인해 15.9 이전의 GitLab에서는 기본적으로 삭제가 비활성화되었습니다. 이 경합 조건은 Geo인스턴스에서 특히 두드러지며 Geo는 비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 -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml verify -repository-id=<repository-id>

가상 저장소에 저장된 모든 레플리카의 우선 검증 설정:

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

스토리지에 저장된 모든 레플리카의 우선 검증 설정:

sudo -u git -- /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 노드는 직전 10초 내에 >=50% Praefect 노드가 성공적으로 건강 확인한 경우 건강하다고 간주됩니다.
  • 레파지토리의 최신 업데이트된 복사본을 갖고 있는 경우.

여러 주요 노드 후보가 있는 경우, Praefect는 다음과 같이 처리합니다:

  • 그 중 하나를 무작위로 선택합니다.
  • 레파지토리를 호스팅하도록 지정된 Gitaly 노드를 승격하는 것을 우선시합니다. 레파지토리를 호스팅하도록 지정된 Gitaly 노드가 있는 경우, 이를 주요 노드로 승격합니다. 호스팅되는 Gitaly 노드가 없는 경우, Praefect는 임시로 지정되지 않은 노드를 선출할 수 있습니다. 그러나 호스팅되는 노드가 사용 가능해지면 지정되지 않은 주요 노드는 취소됩니다.

레파지토리에 유효한 주요 노드 후보가 없는 경우:

  • 건강하지 않은 주요 노드가 해제되고 레파지토리는 주요 노드 없이 남습니다.
  • 주요 노드가 성공적으로 선출될 때까지 주요 노드가 필요한 작업은 실패합니다.