지리 데이터베이스 복제

Tier: Premium, Ultimate Offering: Self-managed

이 문서는 기본 GitLab 데이터베이스를 보조 사이트의 데이터베이스에 복제하기 위한 최소한의 필수 단계를 설명합니다. 데이터베이스의 설정 및 크기와 같은 속성을 기반으로 일부 값을 변경해야 할 수 있습니다.

note
GitLab 설치에서 외부 PostgreSQL 인스턴스(리눅스 패키지 설치로 관리되지 않음)를 사용하는 경우, 역할이 모든 필요한 구성 단계를 수행할 수 없습니다. 이 경우, 외부 PostgreSQL 인스턴스와 함께 Geo 프로세스를 대신 사용하십시오.
note
설정 프로세스의 단계는 문서화된 순서대로 완료되어야 합니다. 그렇지 않은 경우, 진행하기 전에 모든 이전 단계를 완료하십시오.

보조 사이트가 기본 사이트와 동일한 버전의 GitLab Enterprise Edition을 실행하는지 확인하십시오. 기본 사이트에 Premium 또는 Ultimate 구독에 대한 라이센스를 추가했는지 확인하십시오.

테스트 또는 프로덕션 환경에서 이 단계를 실행하기 전에 모든 단계를 읽고 검토하십시오.

단일 인스턴스 데이터베이스 복제

단일 인스턴스 데이터베이스 복제는 설정이 더 용이하며 클러스터링 대안과 동일한 Geo 기능을 제공합니다. 단일 머신에서 실행되거나 향후 클러스터 설치를 평가하려는 설정에 유용합니다.

단일 인스턴스는 Patroni를 사용하여 클러스터 버전으로 확장할 수 있으며, 이는 높은 가용성 아키텍처에 권장됩니다.

아래 지침을 따르십시오. 단일 인스턴스 데이터베이스로 PostgreSQL 복제를 설정하는 방법을 안내합니다. 또는 다중 노드 데이터베이스 복제 지침을 참조하여 Patroni 클러스터로 복제를 설정할 수 있습니다.

PostgreSQL 복제

쓰기 작업이 발생하는 GitLab 기본 사이트는 기본 데이터베이스 서버에 연결합니다. 보조 사이트는 자체 데이터베이스 서버(읽기 전용)에 연결합니다.

PostgreSQL의 복제 슬롯을 사용하여 기본 사이트가 보조 사이트가 복구하는 데 필요한 모든 데이터를 유지하도록 해야 합니다. 자세한 내용은 아래를 참조하십시오.

다음 가이드는 다음을 전제로 합니다:

  • 리눅스 패키지를 사용하고 있으며 (따라서 PostgreSQL 12 이상을 사용하고 있음), pg_basebackup 도구를 포함하고 있습니다.
  • 이미 설정된 기본 사이트(복제를 수행하는 GitLab 서버)가 있으며, 리눅스 패키지 설치로 관리되는 PostgreSQL(또는 동등한 버전)을 실행하고 있으며,
    모든 사이트에서 동일한 PostgreSQL 버전, 운영 체제 및 GitLab을 설치한 새 보조 사이트가 설정되어 있습니다.
caution
Geo는 스트리밍 복제로 작동합니다. 논리 복제는 현재 지원되지 않습니다. 지원이 논의되고 있는 문제가 있습니다.

1단계. 기본 사이트 구성

  1. SSH를 통해 GitLab 기본 사이트에 로그인하고 root 사용자로 로그인합니다:

    sudo -i  
    
  2. /etc/gitlab/gitlab.rb를 편집하고 사이트의 고유한 이름을 추가합니다:

    ##  
    ## Geo 사이트의 고유 식별자.  
    ## https://docs.gitlab.com/ee/administration/geo_sites.html#common-settings  
    ##  
    gitlab_rails['geo_node_name'] = '<site_name_here>'  
    
  3. 기본 사이트를 다시 구성하여 변경 사항이 적용되도록 합니다:

    gitlab-ctl reconfigure  
    
  4. 아래 명령을 실행하여 사이트를 기본 사이트로 정의합니다:

    gitlab-ctl set-geo-primary-node  
    

    이 명령은 /etc/gitlab/gitlab.rb에 정의된 external_url을 사용합니다.

  5. gitlab 데이터베이스 사용자에 대한 비밀번호를 정의합니다:

    원하는 비밀번호의 MD5 해시를 생성합니다:

    gitlab-ctl pg-password-md5 gitlab  
    # 비밀번호 입력: <your_db_password_here>  
    # 비밀번호 확인: <your_db_password_here>  
    # fca0b89a972d69f00eb3ec98a5838484  
    

    /etc/gitlab/gitlab.rb를 편집합니다:

    # `gitlab-ctl pg-password-md5 gitlab`로 생성된 해시를 채우십시오.  
    postgresql['sql_user_password'] = '<md5_hash_of_your_db_password>'  
    
    # Puma 또는 Sidekiq를 실행하는 모든 노드는 아래와 같이 데이터베이스  
    # 비밀번호를 지정해야 합니다. 고가용성 설정이 있는 경우 모든 애플리케이션 노드에  
    # 있어야 합니다.  
    gitlab_rails['db_password'] = '<your_db_password_here>'  
    
  6. 복제 사용자의 비밀번호를 정의합니다.

    /etc/gitlab/gitlab.rb에서 postgresql['sql_replication_user'] 설정 아래에 정의된 사용자 이름을 사용합니다. 기본값은 gitlab_replicator입니다. 사용자 이름을 다른 것으로 변경한 경우 아래 지침을 수정하십시오.

    원하는 비밀번호의 MD5 해시를 생성합니다:

    gitlab-ctl pg-password-md5 gitlab_replicator  
    # 비밀번호 입력: <your_replication_password_here>  
    # 비밀번호 확인: <your_replication_password_here>  
    # 950233c0dfc2f39c64cf30457c3b7f1e  
    

    /etc/gitlab/gitlab.rb를 편집합니다:

    # `gitlab-ctl pg-password-md5 gitlab_replicator`로 생성된 해시를 채우십시오.  
    postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'  
    

    리눅스 패키지 설치로 관리되지 않는 외부 데이터베이스를 사용하는 경우, gitlab_replicator 사용자 및 해당 사용자에 대한 비밀번호를 수동으로 생성해야 합니다:

    --- 'replicator'라는 새 사용자 생성  
    CREATE USER gitlab_replicator;  
    
    --- 비밀번호를 설정/변경하고 복제 권한 부여  
    ALTER USER gitlab_replicator WITH REPLICATION ENCRYPTED PASSWORD '<replication_password>';  
    
  7. /etc/gitlab/gitlab.rb를 편집하고 역할을 geo_primary_role로 설정합니다(자세한 내용은 Geo 역할을 참조하십시오):

    ## Geo 기본 역할  
    roles(['geo_primary_role'])  
    
  8. PostgreSQL이 네트워크 인터페이스에서 수신 대기하도록 구성합니다:

    보안상의 이유로 PostgreSQL은 기본적으로 어떤 네트워크 인터페이스에서도 수신 대기하지 않습니다. 그러나 Geo는 보조 사이트가 기본 사이트의 데이터베이스에 연결할 수 있도록 요구합니다. 이러한 이유로 각 사이트의 IP 주소가 필요합니다.

    note
    외부 PostgreSQL 인스턴스의 경우, 추가 지침을 참조하십시오.

    클라우드 공급자를 사용하는 경우, 클라우드 공급자의 관리 콘솔을 통해 각 Geo 사이트의 주소를 확인할 수 있습니다.

    Geo 사이트의 주소를 확인하려면 Geo 사이트에 SSH로 접속한 후 다음을 실행합니다:

    ##  
    ## 개인 주소  
    ##  
    ip route get 255.255.255.255 | awk '{print "Private address:", $NF; exit}'  
    
    ##  
    ## 공용 주소  
    ##  
    echo "External address: $(curl --silent "ipinfo.io/ip")"  
    

    대부분의 경우, GitLab Geo를 구성하기 위해 다음 주소를 사용합니다:

    구성 주소
    postgresql['listen_address'] 기본 사이트의 공용 또는 VPC 개인 주소.
    postgresql['md5_auth_cidr_addresses'] 기본보조 사이트의 공용 또는 VPC 개인 주소.

    Google Cloud Platform, SoftLayer 또는 기타 VPC를 제공하는 도급업체를 사용하는 경우,
    postgresql['md5_auth_cidr_addresses']postgresql['listen_address']에 대해 기본보조 사이트의 “개인” 또는 “내부” 주소를 사용하는 것이 좋습니다.

    listen_address 옵션은 지정된 주소와 관련된 인터페이스로 네트워크 연결을 사용할 수 있도록 PostgreSQL을 열어줍니다. 자세한 내용은 PostgreSQL 문서를 참조하십시오.

    note
    listen_address0.0.0.0 또는 *를 사용해야 하는 경우, Rails가 127.0.0.1을 통해 연결할 수 있도록 postgresql['md5_auth_cidr_addresses'] 설정에 127.0.0.1/32도 추가해야 합니다. 자세한 내용은 문제 5258을 참조하십시오.

    네트워크 구성에 따라 제안된 주소가 올바르지 않을 수 있습니다. 기본 사이트와 보조 사이트가 로컬 네트워크 또는 Amazon의 VPC와 같은 가상 네트워크를 통해 연결되는 경우,
    postgresql['md5_auth_cidr_addresses']보조 사이트의 개인 주소를 사용해야 합니다.

    /etc/gitlab/gitlab.rb를 편집하고 다음을 추가합니다. IP 주소를 네트워크 구성에 적합한 주소로 바꿉니다:

    ##  
    ## 기본 주소  
    ## - '<primary_node_ip>'를 Geo 기본 노드의 공용 또는 VPC 주소로 바꿉니다.  
    ##  
    postgresql['listen_address'] = '<primary_site_ip>'  
    
    ##  
    # 기본 및 보조 IP에서 PostgreSQL 클라이언트 인증을 허용합니다.  
    # 이러한 IP는 CIDR 형식으로 공용 또는 VPC 주소 일 수 있습니다.  
    ##  
    postgresql['md5_auth_cidr_addresses'] = ['<primary_site_ip>/32', '<secondary_site_ip>/32']  
    
    ##  
    ## 복제 설정  
    ##  
    # postgresql['max_replication_slots'] = 1 # Geo 보조 노드의 수에 따라 설정하십시오  
    # postgresql['max_wal_senders'] = 10  
    # postgresql['wal_keep_segments'] = 10  
    
  9. PostgreSQL이 개인 주소에서 수신 대기할 때까지 자동 데이터베이스 마이그레이션을 일시적으로 비활성화합니다. /etc/gitlab/gitlab.rb를 편집하고 구성을 false로 변경합니다:

    ## 자동 데이터베이스 마이그레이션 비활성화  
    gitlab_rails['auto_migrate'] = false  
    
  10. 선택 사항: 다른 보조 사이트를 추가하려면 해당 설정은 다음과 같습니다:

    postgresql['md5_auth_cidr_addresses'] = ['<primary_site_ip>/32', '<secondary_site_ip>/32', '<another_secondary_site_ip>/32']  
    

    데이터베이스 복제 요구 사항에 맞추어 wal_keep_segmentsmax_wal_senders를 수정할 수도 있습니다.
    자세한 내용은 PostgreSQL - 복제 문서를 참조하십시오.

  11. 파일을 저장하고 GitLab을 재구성하여 데이터베이스 수신 대기 변경 사항 및 복제 슬롯 변경 사항을 적용합니다:

    gitlab-ctl reconfigure  
    

    PostgreSQL이 변경 사항을 적용하려면 다시 시작합니다:

    gitlab-ctl restart postgresql  
    
  12. PostgreSQL이 다시 시작되고 개인 주소에서 수신 대기하는 이제 마이그레이션을 다시 활성화합니다.

    /etc/gitlab/gitlab.rb를 편집하고 구성을 true로 변경합니다:

    gitlab_rails['auto_migrate'] = true  
    

    파일을 저장하고 GitLab을 다시 구성합니다:

    gitlab-ctl reconfigure  
    
  13. 이제 PostgreSQL 서버가 원격 연결을 수락하도록 설정되었으므로
    netstat -plnt | grep 5432를 실행하여 PostgreSQL이 기본 사이트의 개인 주소에서 포트 5432를 수신 대기하고 있는지 확인합니다.

  14. GitLab이 다시 구성될 때 자동으로 인증서가 생성됩니다. 이 인증서는 도청자로부터 PostgreSQL 트래픽을 보호하는 데 자동으로 사용됩니다.
    능동적(“중간자”) 공격으로부터 보호하기 위해, 보조 사이트는 인증서를 서명한 CA의 복사본이 필요합니다.
    이 자체 서명된 인증서의 경우, 다음 명령을 실행하여 기본 사이트의 PostgreSQL server.crt 파일의 복사본을 만듭니다:

    cat ~gitlab-psql/data/server.crt  
    

    출력을 클립보드에 복사하거나 로컬 파일로 저장합니다. 이 데이터를 보조 사이트 설정 시 필요합니다! 인증서는 민감한 데이터가 아닙니다.

    그러나 이 인증서는 일반적인 PostgreSQL 공통 이름으로 생성됩니다. 이를 위해 데이터베이스 복제 시 verify-ca 모드를 사용해야 합니다. 그렇지 않으면 호스트 이름 불일치로 인해 오류가 발생합니다.

  15. 선택 사항. 자체 SSL 인증서를 생성하고
    PostgreSQL의 SSL 구성으로 수동 구성하여
    생성된 인증서 대신 사용할 수 있습니다.

    SSL 인증서와 키가 최소한 필요합니다. postgresql['ssl_cert_file']postgresql['ssl_key_file'] 값을 데이터베이스 SSL 문서에 따라 전체 경로로 설정합니다.

    이렇게 하면 데이터베이스 복제 시 verify-full SSL 모드를 사용할 수 있으며 CN의 전체 호스트 이름을 검증하는 추가 이점을 얻을 수 있습니다.

    앞으로는 위의 포인트에서 인증서 대신에 (postgresql['ssl_cert_file'])에 설정한 인증서를 사용할 수 있습니다.
    이를 통해 CN이 일치할 경우 복제 오류 없이 verify-full을 사용할 수 있습니다.

    기본 데이터베이스에서 /etc/gitlab/gitlab.rb를 열고 postgresql['ssl_ca_file'](CA 인증서)를 검색합니다.
    그 값을 클립보드에 복사하여 server.crt에 나중에 붙여넣습니다.

2단계. 세컨더리 서버 구성

  1. GitLab 세컨더리 사이트에 SSH로 접속하고 root로 로그인합니다:

    sudo -i
    
  2. 애플리케이션 서버와 Sidekiq를 중지합니다:

    gitlab-ctl stop puma
    gitlab-ctl stop sidekiq
    

    참고: 이 단계는 사이트가 완전히 구성되기 전에 아무 것도 실행하지 않도록 하는 데 중요합니다.

  3. 프라이머리 사이트의 PostgreSQL 서버에 대한 TCP 연결 확인:

    gitlab-rake gitlab:tcp_check[<primary_site_ip>,5432]
    

    참고: 이 단계가 실패하면 잘못된 IP 주소를 사용하고 있을 수 있거나 방화벽이 사이트에 대한 액세스를 차단하고 있을 수 있습니다. IP 주소를 확인하고, 공용 주소와 사설 주소의 차이에 주의하세요. 방화벽이 있는 경우 세컨더리 사이트가 포트 5432에서 프라이머리 사이트에 연결할 수 있도록 허용되어 있는지 확인하세요.

  4. 세컨더리 사이트에 server.crt 파일을 생성하고, 프라이머리 사이트 설정의 마지막 단계에서 받은 내용을 입력합니다:

    editor server.crt
    
  5. 세컨더리 사이트에서 PostgreSQL TLS 인증을 설정합니다:

    server.crt 파일을 설치합니다:

    install \
       -D \
       -o gitlab-psql \
       -g gitlab-psql \
       -m 0400 \
       -T server.crt ~gitlab-psql/.postgresql/root.crt
    

    PostgreSQL은 이제 TLS 연결을 검증할 때 해당 인증서만 인식합니다. 이 인증서는 개인 키에 대한 액세스 권한이 있는 사람만 복제할 수 있으며, 이는 프라이머리 사이트에만 존재합니다.

  6. gitlab-psql 사용자가 프라이머리 사이트의 데이터베이스에 연결할 수 있는지 테스트합니다 (기본 데이터베이스 이름은 Linux 패키지 설치 시 gitlabhq_production입니다):

    sudo \
       -u gitlab-psql /opt/gitlab/embedded/bin/psql \
       --list \
       -U gitlab_replicator \
       -d "dbname=gitlabhq_production sslmode=verify-ca" \
       -W \
       -h <primary_site_ip>
    

    참고: 수동으로 생성한 인증서를 사용하고 전체 호스트네임 검증의 혜택을 누리기 위해 sslmode=verify-full을 사용하려면 명령을 실행할 때 verify-caverify-full로 바꾸세요.

    프롬프트가 표시되면 첫 번째 단계에서 설정한 gitlab_replicator 사용자에 대한 평문 비밀번호를 입력하세요. 모든 것이 정확하게 작동하면 프라이머리 사이트의 데이터베이스 목록이 표시됩니다.

    여기서 연결 실패는 TLS 구성이 올바르지 않음을 나타냅니다. 프라이머리 사이트의 ~gitlab-psql/data/server.crt 내용이 세컨더리 사이트의 ~gitlab-psql/.postgresql/root.crt 내용과 일치하는지 확인하세요.

  7. /etc/gitlab/gitlab.rb를 편집하고 역할을 geo_secondary_role로 설정합니다 (자세한 내용은 Geo 역할을 참조):

    ##
    ## Geo Secondary role
    ## - Geo를 활성화하기 위해 종속 플래그 자동 구성
    ##
    roles(['geo_secondary_role'])
    
  8. PostgreSQL을 구성합니다:

    이 단계는 프라이머리 인스턴스를 구성한 방식과 유사합니다.

    /etc/gitlab/gitlab.rb를 편집하고 다음을 추가하며, IP 주소를 네트워크 구성에 적합한 주소로 바꿉니다:

    ##
    ## 세컨더리 주소
    ## - '<secondary_site_ip>'를 Geo 세컨더리 사이트의 공용 주소 또는 VPC 주소로 교체합니다
    ##
    postgresql['listen_address'] = '<secondary_site_ip>'
    postgresql['md5_auth_cidr_addresses'] = ['<secondary_site_ip>/32']
    
    ##
    ## 데이터베이스 자격 증명 비밀번호 (프라이머리 사이트에서 이전에 정의됨)
    ## - 프라이머리 사이트에 정의된 값을 여기에서 동일하게 복제합니다
    ##
    postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
    postgresql['sql_user_password'] = '<md5_hash_of_your_db_password>'
    gitlab_rails['db_password'] = '<your_db_password_here>'
    

    외부 PostgreSQL 인스턴스에 대한 추가 지침은 추가 지침을 참조하세요.

    이전 프라이머리 사이트를 다시 온라인으로 전환하여 세컨더리 사이트로 사용하려는 경우, roles(['geo_primary_role']) 또는 geo_primary_role['enable'] = true를 제거해야 합니다.

  9. 변경 사항이 적용되도록 GitLab을 재구성합니다:

    gitlab-ctl reconfigure
    
  10. IP 변경 사항이 적용되도록 PostgreSQL을 다시 시작합니다:

    gitlab-ctl restart postgresql
    

3단계. 복제 프로세스 시작하기

다음은 secondary 사이트의 데이터베이스를 primary 사이트의 데이터베이스에 연결하는 스크립트입니다. 이 스크립트는 데이터베이스를 복제하고 스트리밍 복제를 위해 필요한 파일을 생성합니다.

사용되는 디렉터리는 Linux 패키지 설치에서 설정된 기본값입니다. 기본값을 변경한 경우, 스크립트를 그에 맞게 구성하십시오 (디렉터리 및 경로를 교체).

경고: pg_basebackup을 실행하기 전에 모든 PostgreSQL 데이터를 제거하므로 secondary 사이트에서 이 작업을 실행하십시오.

  1. GitLab secondary 사이트에 SSH로 접속하고 root로 로그인합니다:

    sudo -i
    
  2. secondary 사이트에서 사용할 복제 슬롯 이름으로 데이터베이스 친화적인 이름을 선택합니다. 예를 들어, 도메인이 secondary.geo.example.com인 경우, 아래 명령어에서 표시된 것처럼 슬롯 이름으로 secondary_example을 사용합니다.

  3. 아래 명령어를 실행하여 백업/복원을 시작하고 복제를 시작합니다.

    경고: 각 Geo secondary 사이트는 고유한 복제 슬롯 이름을 가져야 합니다. 두 개의 secondaries 간에 동일한 슬롯 이름을 사용하면 PostgreSQL 복제가 중단됩니다.

    참고: 복제 슬롯 이름은 소문자, 숫자, 그리고 언더스코어 문자만 포함해야 합니다.

    요청 시, 첫 번째 단계에서 설정한 gitlab_replicator 사용자의 평문 비밀번호를 입력합니다.

    gitlab-ctl replicate-geo-database \
       --slot-name=<secondary_site_name> \
       --host=<primary_site_ip> \
       --sslmode=verify-ca
    

    참고: 사용자 지정 PostgreSQL 인증서를 생성한 경우, 추가 보안을 위해 --sslmode=verify-full(또는 sslmode 라인을 완전히 생략)을 사용해야 합니다. 그렇지 않으면, 자동으로 생성된 인증서를 사용할 때 verify-full이 실패하며, 이는 일반적인 PostgreSQL CN이 이 명령의 --host 값과 일치하지 않기 때문입니다.

    이 명령은 여러 추가 옵션을 받아들입니다. 모든 옵션 목록을 보려면 --help를 사용할 수 있지만, 다음은 몇 가지 팁입니다:

    • 기본 사이트에 단일 노드가 있는 경우, 기본 노드 호스트를 --host 매개변수로 사용합니다.
    • 기본 사이트가 외부 PostgreSQL 데이터베이스를 사용하는 경우, --host 매개변수를 조정해야 합니다:
      • PgBouncer 설정의 경우, 실제 PostgreSQL 데이터베이스 호스트를 직접 타겟으로 지정하고, PgBouncer 주소가 아닙니다.
      • Patroni 구성의 경우, 현재 Patroni 리더 호스트를 타겟으로 지정합니다.
      • 로드 밸런서를 사용하는 경우(예: HAProxy), 로드 밸런서가 항상 Patroni 리더로 라우팅되도록 구성된 경우에는 로드 밸런서를 타겟으로 할 수 있습니다. 그렇지 않으면 실제 데이터베이스 호스트를 타겟으로 해야 합니다.
      • 전용 PostgreSQL 노드가 있는 경우, 전용 데이터베이스 호스트를 직접 타겟으로 지정합니다.
    • --slot-nameprimary 데이터베이스에서 사용할 복제 슬롯 이름으로 변경합니다. 스크립트는 복제 슬롯이 존재하지 않을 경우 자동으로 생성하려고 시도합니다.
    • PostgreSQL이 비표준 포트에서 대기 중인 경우, --port=를 추가하십시오.
    • 데이터베이스가 30분 이내에 전송될 수 없을 정도로 큰 경우, 시간 초과를 늘려야 합니다. 예를 들어, 초기 복제가 한 시간 이하로 걸릴 것으로 예상되는 경우 --backup-timeout=3600을 사용합니다.
    • PostgreSQL TLS 인증을 완전히 건너뛰려면 --sslmode=disable을 전달하십시오 (예: 네트워크 경로가 안전하다고 확신하거나 사이트 간 VPN을 사용하고 있는 경우). 공용 인터넷에서는 안전하지 않습니다!
    • sslmode에 대한 자세한 내용을 보려면 PostgreSQL 문서를 참조하십시오. 위의 지침은 수동적인 엿듣기와 능동적인 “중간자” 공격자에 대한 보호를 보장하기 위해 신중하게 작성되었습니다.
    • 이전 사이트를 Geo secondary 사이트로 재사용하는 경우, 명령줄에 --force를 추가해야 합니다.
    • 프로덕션 머신이 아닌 경우, 백업 단계를 비활성화할 수 있습니다(이것이 원하는 것이라면) --skip-backup을 추가합니다.

복제 프로세스가 이제 완료되었습니다.

PgBouncer 지원 (선택 사항)

PgBouncer는 GitLab Geo와 함께 사용하여 PostgreSQL 연결을 풀링할 수 있으며, 이는 단일 인스턴스 설치에서도 성능을 향상시킬 수 있습니다.

GitLab을 Geo primary 사이트를 지원하는 노드 클러스터와 Geo secondary 사이트를 지원하는 두 개의 다른 노드를 포함하여 고가용성 구성으로 사용할 경우 PgBouncer를 사용해야 합니다. 두 개의 PgBouncer 노드가 필요합니다: 하나는 메인 데이터베이스용, 다른 하나는 추적 데이터베이스용입니다. 더 많은 정보는 관련 문서를 참조하세요.

복제 비밀번호 변경

PostgreSQL 인스턴스에 의해 관리되는 복제 사용자의 비밀번호를 변경하려면:

GitLab Geo primary 사이트에서:

  1. 복제 사용자의 기본값은 gitlab_replicator이며, /etc/gitlab/gitlab.rbpostgresql['sql_replication_user'] 설정에서 커스텀 복제 사용자를 설정한 경우, 다음 지침을 자신의 사용자에 맞게 조정해야 합니다.

    원하는 비밀번호에 대한 MD5 해시를 생성하십시오:

    sudo gitlab-ctl pg-password-md5 gitlab_replicator
    # Enter password: <your_replication_password_here>
    # Confirm password: <your_replication_password_here>
    # 950233c0dfc2f39c64cf30457c3b7f1e
    

    /etc/gitlab/gitlab.rb 파일을 수정하십시오:

    # `gitlab-ctl pg-password-md5 gitlab_replicator`로 생성된 해시를 입력하십시오
    postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
    
  2. 파일을 저장하고 PostgreSQL에서 복제 사용자의 비밀번호를 변경하기 위해 GitLab을 재구성하십시오:

    sudo gitlab-ctl reconfigure
    
  3. 복제 비밀번호 변경 사항을 적용하기 위해 PostgreSQL을 재시작하십시오:

    sudo gitlab-ctl restart postgresql
    

비밀번호가 모든 secondary 사이트에 업데이트되지 않은 경우, secondary 사이트의 PostgreSQL 로그에서는 다음과 같은 오류 메시지를 보고합니다:

FATAL:  could not connect to the primary server: FATAL:  password authentication failed for user "gitlab_replicator"

모든 GitLab Geo secondary 사이트에서:

  1. 첫 번째 단계는 구성 관점에서 필요하지 않습니다. 왜냐하면 해시된 'sql_replication_password'가 GitLab Geo secondary 사이트에서 사용되지 않기 때문입니다. 하지만 secondary 사이트가 GitLab Geo primary로 승격되어야 하는 경우, secondary 사이트 구성에서 'sql_replication_password'를 일치시켜야 합니다.

    /etc/gitlab/gitlab.rb 파일을 수정하십시오:

    # Geo primary에서 `gitlab-ctl pg-password-md5 gitlab_replicator`로 생성된 해시를 입력하십시오
    postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
    
  2. 초기 복제 설정 중, gitlab-ctl replicate-geo-database 명령은 두 위치에 복제 사용자 계정의 평문 비밀번호를 기록합니다:

    • gitlab-geo.conf: PostgreSQL 데이터 디렉토리에 의해 사용되며, 기본적으로 /var/opt/gitlab/postgresql/data/gitlab-geo.conf에 기록됩니다.
    • .pgpass: 기본적으로 /var/opt/gitlab/postgresql/.pgpass에 위치하며 gitlab-psql 사용자가 사용합니다.

    두 파일 모두에서 평문 비밀번호를 업데이트하고 PostgreSQL을 재시작하십시오:

    sudo gitlab-ctl restart postgresql
    

다중 노드 데이터베이스 복제

단일 PostgreSQL 노드를 Patroni로 마이그레이션

Patroni가 도입되기 전, Geo는 보조 사이트에 HA 설정을 위한 Linux 패키지 설치를 지원하지 않았습니다.

Patroni를 통해 이제 이 지원이 가능합니다. 기존 PostgreSQL을 Patroni로 마이그레이션하려면:

  1. 기본 사이트에 설정한 것과 유사하게 보조 사이트에 Consul 클러스터가 설정되어 있는지 확인합니다.

  2. 영구 복제 슬롯 구성.

  3. 내부 로드 밸런서 구성.

  4. PgBouncer 노드 구성

  5. 대기 클러스터 구성 해당 단일 노드 머신에서.

결국에는 단일 노드를 가진 _대기 클러스터_가 생성됩니다. 이를 통해 위의 지침을 따라 추가 Patroni 노드를 추가할 수 있습니다.

Patroni 지원

Patroni는 Geo의 공식 복제 관리 솔루션입니다. Patroni는 주요보조 Geo 사이트에서 고가용성 클러스터를 구축하는 데 사용할 수 있습니다.

보조 사이트에서 Patroni를 사용하는 것은 선택 사항이며 각 Geo 사이트에서 동일한 수의 노드를 사용할 필요는 없습니다.

기본 사이트에서 Patroni를 설정하는 방법에 대한 지침은 관련 문서를 참조하세요.

Geo 보조 사이트를 위한 Patroni 클러스터 구성

Geo 보조 사이트에서 주요 PostgreSQL 데이터베이스는 기본 사이트의 PostgreSQL 데이터베이스의 읽기 전용 복제본입니다.

운영 준비가 완료되고 안전한 설정을 위해 최소한 다음이 필요합니다:

  • 3 Consul 노드 (기본 및 보조 사이트)
  • 2 Patroni 노드 (기본 및 보조 사이트)
  • 1 PgBouncer 노드 (기본 및 보조 사이트)
  • 1 내부 로드 밸런서 (주요 사이트 전용)

내부 로드 밸런서는 새로운 리더가 선출될 때마다 Patroni 클러스터의 리더에 연결하기 위한 단일 엔드포인트를 제공합니다. 로드 밸런서는 보조 사이트에서의 계단식 복제를 활성화하는 데 필요합니다.

비밀번호 자격 증명 및 기타 데이터베이스 모범 사례를 사용하는 것을 잊지 마세요.

Step 1. 기본 사이트에서 Patroni 영구 복제 슬롯 구성

기본 데이터베이스에 지속적인 복제 슬롯을 설정하여 기본 데이터베이스에서 보조 노드의 Patroni 클러스터로 지속적으로 데이터 복제가 이루어지도록 합니다.

Patroni 클러스터가 있는 기본

보조 사이트에서 Patroni와 함께 데이터베이스 복제를 설정하려면 기본 사이트의 Patroni 클러스터에 _영구 복제 슬롯_을 구성하고 비밀번호 인증이 사용되도록 해야 합니다.

Patroni 인스턴스가 실행되고 있는 기본 사이트의 각 노드에서 Patroni 리더 인스턴스에서 시작하여:

  1. Patroni 인스턴스에 SSH로 접속하고 root로 로그인합니다:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb 파일을 편집하고 다음을 추가합니다:

    roles(['patroni_role'])
    
    consul['services'] = %w(postgresql)
    consul['configuration'] = {
      retry_join: %w[CONSUL_PRIMARY1_IP CONSUL_PRIMARY2_IP CONSUL_PRIMARY3_IP]
    }
    
    # 각 보조 노드에 대해 PostgreSQL slot_name 제약 조건을 따르는 고유한 이름의 항목이 필요합니다:
    #
    # 구성 구문은 다음과 같습니다: 'unique_slotname' => { 'type' => 'physical' },
    # 논리적 복제 유형에 대한 영구 복제 슬롯 설정을 지원하지 않습니다.
    patroni['replication_slots'] = {
      'geo_secondary' => { 'type' => 'physical' }
    }
    
    patroni['use_pg_rewind'] = true
    patroni['postgresql']['max_wal_senders'] = 8 # Patroni/예약 슬롯 수의 2배 사용(3 patronis + 1 reserved slot for a Geo secondary).
    patroni['postgresql']['max_replication_slots'] = 8 # Patroni/예약 슬롯 수의 2배 사용(3 patronis + 1 reserved slot for a Geo secondary).
    patroni['username'] = 'PATRONI_API_USERNAME'
    patroni['password'] = 'PATRONI_API_PASSWORD'
    patroni['replication_password'] = 'PLAIN_TEXT_POSTGRESQL_REPLICATION_PASSWORD'
    
    # 모든 patroni 노드를 allowlist에 추가합니다.
    patroni['allowlist'] = %w[
      127.0.0.1/32
      PATRONI_PRIMARY1_IP/32 PATRONI_PRIMARY2_IP/32 PATRONI_PRIMARY3_IP/32
      PATRONI_SECONDARY1_IP/32 PATRONI_SECONDARY2_IP/32 PATRONI_SECONDARY3_IP/32
    ]
    
    # 모든 보조 인스턴스를 나열합니다. 모든 인스턴스가 대기 리더가 될 수 있습니다.
    postgresql['md5_auth_cidr_addresses'] = %w[
      PATRONI_PRIMARY1_IP/32 PATRONI_PRIMARY2_IP/32 PATRONI_PRIMARY3_IP/32 PATRONI_PRIMARY_PGBOUNCER/32
      PATRONI_SECONDARY1_IP/32 PATRONI_SECONDARY2_IP/32 PATRONI_SECONDARY3_IP/32 PATRONI_SECONDARY_PGBOUNCER/32
    ]
    
    postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
    postgresql['sql_replication_password'] = 'POSTGRESQL_REPLICATION_PASSWORD_HASH'
    postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
    postgresql['listen_address'] = '0.0.0.0' # 여기서 공용 또는 VPC 주소를 사용할 수 있습니다.
    
  3. 변경 사항이 적용되도록 GitLab을 재구성합니다:

    gitlab-ctl reconfigure
    
단일 PostgreSQL 인스턴스가 있는 기본
  1. 단일 노드 인스턴스에 SSH로 접속하고 root로 로그인합니다:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb 파일을 편집하고 다음을 추가합니다:

    postgresql['max_wal_senders'] = 2 # 보조 사이트당 2개 사용 (초기 Patroni 복제를 위한 1개의 임시 슬롯 + Geo 보조를 위한 1개의 예약 슬롯)
    postgresql['max_replication_slots'] = 2 # 보조 사이트당 2개 사용 (초기 Patroni 복제를 위한 1개의 임시 슬롯 + Geo 보조를 위한 1개의 예약 슬롯)
    
  3. GitLab을 재구성합니다:

    gitlab-ctl reconfigure
    
  4. PostgreSQL 서비스를 재시작하여 새로운 변경 사항이 적용되도록 합니다:

    gitlab-ctl restart postgresql
    
  5. 데이터베이스 콘솔 시작

    gitlab-psql
    
  6. 기본 사이트에서 영구 복제 슬롯 구성

    select pg_create_physical_replication_slot('geo_secondary')
    
  7. 선택 사항: 기본 사이트에 PgBouncer가 없지만 보조 사이트에 있는 경우:

    기본 사이트에서 pgbouncer 사용자를 구성하고 Linux 패키지에 포함된 PgBouncer를 위한 필수 pg_shadow_lookup 함수를 추가합니다. 보조 서버의 PgBouncer는 여전히 보조 사이트의 PostgreSQL 노드에 연결할 수 있어야 합니다.

    --- 새로운 사용자 'pgbouncer' 생성
    CREATE USER pgbouncer;
    
    --- 비밀번호 설정/변경 및 복제 권한 부여
    ALTER USER pgbouncer WITH REPLICATION ENCRYPTED PASSWORD '<pgbouncer_password_from_secondary>';
    
    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;
    
Step 2. 기본 사이트에서 내부 로드 밸런서 구성하기

중복 리더가 기본 사이트에서 선출될 때마다 보조 사이트의 Standby Leader를 재구성하지 않도록 하려면 TCP 내부 로드 밸런서를 설정해야 합니다. 이 로드 밸런서는 Patroni 클러스터의 리더에 연결할 수 있는 단일 엔드포인트를 제공합니다.

Linux 패키지에는 로드 밸런서가 포함되어 있지 않습니다. HAProxy를 사용하여 이를 설정하는 방법은 다음과 같습니다.

다음 IP와 이름은 예시로 사용됩니다:

  • 10.6.0.21: Patroni 1 (patroni1.internal)
  • 10.6.0.22: Patroni 2 (patroni2.internal)
  • 10.6.0.23: Patroni 3 (patroni3.internal)
global
    log /dev/log local0
    log localhost local1 notice
    log stdout format raw local0

defaults
    log global
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions

frontend internal-postgresql-tcp-in
    bind *:5432
    mode tcp
    option tcplog

    default_backend postgresql

backend postgresql
    mode tcp
    option httpchk
    http-check expect status 200

    server patroni1.internal 10.6.0.21:5432 maxconn 100 check port 8008
    server patroni2.internal 10.6.0.22:5432 maxconn 100 check port 8008
    server patroni3.internal 10.6.0.23:5432 maxconn 100 check port 8008

추가 안내는 선호하는 로드 밸런서의 문서를 참조하세요.

Step 3. 보조 사이트에서 PgBouncer 노드 구성하기

생산 준비가 완료되고 고가용성 구성을 위해서는 최소한 세 개의 Consul 노드와 하나의 PgBouncer 노드가 필요합니다. 그러나 각 데이터베이스 노드마다 하나의 PgBouncer 노드를 두는 것이 권장됩니다. PgBouncer 서비스 노드가 하나 이상일 경우 내부 로드 밸런서(TCP)가 필요합니다. 내부 로드 밸런서는 PgBouncer 클러스터에 연결할 수 있는 단일 엔드포인트를 제공합니다. 자세한 내용은 해당 문서를 참조하세요.

보조 사이트에서 PgBouncer 인스턴스를 실행 중인 각 노드에서:

  1. PgBouncer 노드에 SSH로 로그인하고 root로 로그인합니다:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb를 편집하고 다음을 추가합니다:

    # Pgbouncer와 Consul 에이전트를 제외한 모든 구성 요소 비활성화
    roles(['pgbouncer_role'])
    
    # PgBouncer 구성
    pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
    pgbouncer['users'] = {
    'gitlab-consul': {
       # 다음 명령으로 생성: `gitlab-ctl pg-password-md5 gitlab-consul`
       password: 'GITLAB_CONSUL_PASSWORD_HASH'
     },
      'pgbouncer': {
        # 다음 명령으로 생성: `gitlab-ctl pg-password-md5 pgbouncer`
        password: 'PGBOUNCER_PASSWORD_HASH'
      }
    }
    
    # Consul 구성
    consul['watchers'] = %w(postgresql)
    consul['configuration'] = {
      retry_join: %w[CONSUL_SECONDARY1_IP CONSUL_SECONDARY2_IP CONSUL_SECONDARY3_IP]
    }
    consul['monitoring_service_discovery'] =  true
    
  3. 변경 사항을 적용하기 위해 GitLab을 재구성합니다:

    gitlab-ctl reconfigure
    
  4. Consul이 PgBouncer를 다시 로드할 수 있도록 .pgpass 파일을 생성합니다. 요청 시 PLAIN_TEXT_PGBOUNCER_PASSWORD를 두 번 입력합니다:

    gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
    
  5. PgBouncer 서비스를 다시 로드합니다:

    gitlab-ctl hup pgbouncer
    
4단계. 보조 사이트에서 대기 클러스터 구성

참고:
단일 PostgreSQL 인스턴스가 있는 보조 사이트를 Patroni 클러스터로 변환하는 경우 PostgreSQL 인스턴스에서 시작해야 합니다. 이는 Patroni 대기 리더 인스턴스가 되며, 필요에 따라 다른 복제본으로 전환할 수 있습니다.

보조 사이트에서 Patroni 인스턴스를 실행하는 각 노드에 대해:

  1. Patroni 노드에 SSH로 접속하여 root로 로그인합니다:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb를 편집하고 다음을 추가합니다:

    roles(['consul_role', 'patroni_role'])
    
    consul['enable'] = true
    consul['configuration'] = {
      retry_join: %w[CONSUL_SECONDARY1_IP CONSUL_SECONDARY2_IP CONSUL_SECONDARY3_IP]
    }
    consul['services'] = %w(postgresql)
    
    postgresql['md5_auth_cidr_addresses'] = [
      'PATRONI_SECONDARY1_IP/32', 'PATRONI_SECONDARY2_IP/32', 'PATRONI_SECONDARY3_IP/32', 'PATRONI_SECONDARY_PGBOUNCER/32',
      # 문서에 따라 데이터베이스에 접근할 필요가 있는 기타 인스턴스
    ]
    
    
    # patroni 노드를 허용 목록에 추가
    patroni['allowlist'] = %w[
      127.0.0.1/32
      PATRONI_SECONDARY1_IP/32 PATRONI_SECONDARY2_IP/32 PATRONI_SECONDARY3_IP/32
    ]
    
    patroni['standby_cluster']['enable'] = true
    patroni['standby_cluster']['host'] = 'INTERNAL_LOAD_BALANCER_PRIMARY_IP'
    patroni['standby_cluster']['port'] = INTERNAL_LOAD_BALANCER_PRIMARY_PORT
    patroni['standby_cluster']['primary_slot_name'] = 'geo_secondary' # 또는 이전에 설정한 고유 복제 슬롯 이름
    patroni['username'] = 'PATRONI_API_USERNAME'
    patroni['password'] = 'PATRONI_API_PASSWORD'
    patroni['replication_password'] = 'PLAIN_TEXT_POSTGRESQL_REPLICATION_PASSWORD'
    patroni['use_pg_rewind'] = true
    patroni['postgresql']['max_wal_senders'] = 5 # 하나의 복제본에 대해 최소 3개, 추가 복제본당 2개
    patroni['postgresql']['max_replication_slots'] = 5 # 하나의 복제본에 대해 최소 3개, 추가 복제본당 2개
    
    postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
    postgresql['sql_replication_password'] = 'POSTGRESQL_REPLICATION_PASSWORD_HASH'
    postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
    postgresql['listen_address'] = '0.0.0.0' # 여기에 공인 주소 또는 VPC 주소를 사용할 수 있습니다.
    
    gitlab_rails['db_password'] = 'POSTGRESQL_PASSWORD'
    gitlab_rails['enable'] = true
    gitlab_rails['auto_migrate'] = false
    

    patroni['standby_cluster']['host']patroni['standby_cluster']['port']를 구성할 때:
    - INTERNAL_LOAD_BALANCER_PRIMARY_IP는 기본 내부 로드 밸런서 IP를 가리켜야 합니다.
    - INTERNAL_LOAD_BALANCER_PRIMARY_PORT기본 Patroni 클러스터 리더를 위해 구성된 프론트엔드 포트 를 가리켜야 합니다. PgBouncer 프론트엔드 포트는 사용하지 마세요.

  3. 변경 사항이 적용되도록 GitLab을 재구성합니다.
    이 단계는 PostgreSQL 사용자 및 설정을 부트스트랩하는 데 필요합니다.

    • Patroni의 새 설치인 경우:

      gitlab-ctl reconfigure
      
    • 이전에 작동하던 Patroni 클러스터가 있었던 사이트에서 Patroni 대기 클러스터를 구성하는 경우:

      1. Patroni에 의해 관리되는 모든 노드에서 Patroni를 중지합니다. 캐스케이드 복제본 포함:

        gitlab-ctl stop patroni
        
      2. 복제 클러스터를 재생성하기 위해 리더 Patroni 노드에서 다음을 실행합니다:

        rm -rf /var/opt/gitlab/postgresql/data
        /opt/gitlab/embedded/bin/patronictl -c /var/opt/gitlab/patroni/patroni.yaml remove postgresql-ha
        gitlab-ctl reconfigure
        
      3. 기본 데이터베이스에서 복제 프로세스를 시작하기 위해 리더 Patroni 노드에서 Patroni를 시작합니다:

        gitlab-ctl start patroni
        
      4. Patroni 클러스터의 상태를 확인합니다:

        gitlab-ctl patroni members
        

        확인해야 할 사항:

        • 현재 Patroni 노드가 출력에 나타나는지 확인합니다.
        • 역할이 Standby Leader인지. 역할이 처음에는 Replica로 표시될 수 있습니다.
        • 상태가 Running인지. 상태가 처음에는 Creating replica로 표시될 수 있습니다.

        노드의 역할이 Standby Leader로 안정되고 상태가 Running이 될 때까지 기다립니다. 몇 분이 걸릴 수 있습니다.

      5. 리더 Patroni 노드가 Standby Leader이고 Running 상태일 때, 대기 클러스터의 다른 Patroni 노드를 시작합니다:

        gitlab-ctl start patroni
        

        다른 Patroni 노드는 새로운 대기 클러스터에 복제본으로 자동으로 참여하고 리더 Patroni 노드로부터 복제를 시작해야 합니다.

  4. 클러스터 상태를 확인합니다:

    gitlab-ctl patroni members
    

    모든 Patroni 노드가 Running 상태로 나열되어 있는지 확인합니다. 하나의 Standby Leader 노드와 여러 개의 Replica 노드가 있어야 합니다.

단일 추적 데이터베이스 노드를 Patroni로 마이그레이션

Patroni 도입 이전에는 Geo가 보조 사이트에서 HA 설정을 위한 Linux 패키지 설치에 대한 지원을 제공하지 않았습니다.

이제 Patroni를 통해 HA 설정을 지원할 수 있게 되었습니다. 그러나 Patroni의 일부 제한으로 인해 동일한 머신에서 두 개의 서로 다른 클러스터를 관리할 수 없습니다. 위의 동일한 지침을 따라 추적 데이터베이스를 위한 새로운 Patroni 클러스터를 설정해야 합니다.

보조 노드는 새 추적 데이터베이스를 채우며, 데이터 동기화는 필요하지 않습니다.

추적 PostgreSQL 데이터베이스를 위한 Patroni 클러스터 구성

Secondary Geo 사이트는 복제 상태를 추적하고 잠재적인 복제 문제로부터 자동 복구하기 위해 추적 데이터베이스로서 별도의 PostgreSQL 설치를 사용합니다.

단일 노드에서 Geo 추적 데이터베이스를 실행하려면 Geo 보조 사이트에서 Geo 추적 데이터베이스 구성을 참조하세요.

Linux 패키지는 고가용성 구성에서 Geo 추적 데이터베이스를 실행하는 것을 지원하지 않습니다. 특히, 장애 조치가 제대로 작동하지 않습니다. 기능 요청 문제를 참조하세요.

고가용성 구성에서 Geo 추적 데이터베이스를 실행하려면, 보조 사이트를 클라우드 관리 데이터베이스와 같은 외부 PostgreSQL 데이터베이스에 연결하거나 수동으로 구성된 Patroni 클러스터(우선 GitLab Linux 패키지에서 관리되지 않음)에 연결할 수 있습니다. 외부 PostgreSQL 인스턴스가 있는 Geo를 따르세요.

문제 해결

문제 해결 문서를 읽어보세요.