Linux 패키지 설치를 위한 PostgreSQL 복제 및 장애 조치

Tier: 프리미엄, 얼티메이트 Offering: Self-Managed

GitLab Self-Managed의 Free 사용자라면 클라우드 호스팅 솔루션을 사용하는 것을 고려해보십시오. 이 문서는 자체 컴파일된 설치에 대해 다루지 않습니다.

복제와 장애 조치가 설정의 일부가 아닌 경우 Linux 패키지에 대한 [데이터베이스 구성 문서]를 참조하십시오.

GitLab에 대한 PostgreSQL의 복제 및 장애 조치를 구성하기 전에 이 문서를 완전히 읽는 것이 좋습니다.

운영 체제 업그레이드

운영 체제를 다른 시스템으로 장애 조치하는 경우 [PostgreSQL 운영 체제 업그레이드에 대한 문서]를 읽으십시오. 운영 체제 업그레이드 시 지역 변경을 감안하지 않으면 데이터 손상이 발생할 수 있습니다.

아키텍처

복제 장애 조치를 위한 PostgreSQL 클러스터의 리눅스 패키지 권장 구성은 다음과 같습니다:

  • 최소 세 개의 PostgreSQL 노드
  • 최소 세 개의 Consul 서버 노드
  • 주요 데이터베이스 읽기 및 쓰기를 추적하고 처리하는 최소 세 개의 PgBouncer 노드
    • PgBouncer 노드 간의 요청을 균형있게 분배하는 내부 로드 밸런서 (TCP)
  • 데이터베이스 부하 분산 활성화
    • 각 PostgreSQL 노드에 구성된 로컬 PgBouncer 서비스. 이는 주요 기능을 추적하는 본 PgBouncer 클러스터와 별도입니다.

또한 네트워크 토폴로지를 고려해야 하며, 데이터베이스 및 GitLab 인스턴스 간에 중복 연결이 있어 네트워크가 단일 장애점이 되지 않도록하여야 합니다.

참고: PostgreSQL 12는 Linux 패키지 설치와 함께 제공됩니다. PostgreSQL 12의 클러스터링은 Patroni의 경우에만 지원되며, 따라서 Patroni는 복제 및 장애 조치에 필수적이 됩니다. 자세한 내용은 Patroni 섹션을 참조하십시오.

데이터베이스 노드

각 데이터베이스 노드는 네 가지 서비스를 실행합니다:

  • PostgreSQL: 데이터베이스 자체
  • Patroni: 클러스터 내의 다른 Patroni 서비스와 통신하고 리더 서버에 문제가 발생했을 때 장애 조치를 처리합니다. 장애 조치 절차는 다음을 포함합니다:
    • 클러스터의 새 리더를 선택합니다.
    • 새 노드를 리더로 승격합니다.
    • 나머지 서버에 새 리더 노드를 따르도록 지시합니다.
  • PgBouncer: 노드의 로컬 풀러. 데이터베이스 부하 분산의 일환으로 읽기 쿼리에 사용됩니다.
  • Consul 에이전트: Consul 클러스터의 현재 Patroni 상태를 저장하는 Consul 클러스터와 통신합니다. 이 에이전트는 데이터베이스 클러스터의 각 노드의 상태를 모니터링하고 Consul 클러스터의 서비스 정의에 대한 상태를 추적합니다.

Consul 서버 노드

Consul 서버 노드는 Consul 서버 서비스를 실행합니다. 이러한 노드는 Patroni 클러스터 부트스트랩 전에 퀴럼에 도달하고 리더가 선출되어야 합니다. 그렇지 않으면 데이터베이스 노드는 Consul 리더가 선출될 때까지 대기합니다.

PgBouncer 노드

각 PgBouncer 노드는 두 가지 서비스를 실행합니다:

  • PgBouncer: 데이터베이스 연결 풀러 자체
  • Consul 에이전트: Consul 클러스터의 PostgreSQL 서비스 정의 상태를 감시합니다. 그 상태가 변경되면 Consul은 새로운 PostgreSQL 리더 노드를 가리키도록 PgBouncer 구성을 업데이트하고 PgBouncer 서비스를 다시로드합니다.

연결 흐름

패키지의 각 서비스에는 기본 포트 집합이 함께 제공됩니다. 아래 나열된 연결에 대해 특정 방화벽 규칙을 설정해야 할 수 있습니다.

이 설정에는 여러 연결 흐름이 있습니다:

주요

  • 응용 프로그램 서버는 기본 포트을 통해 PgBouncer에 직접 연결하거나 다중 PgBouncer를 서비스하는 구성된 내부 로드 밸런서 (TCP)를 통해 연결합니다.
  • PgBouncer는 주요 데이터베이스 서버의 [PostgreSQL 기본 포트]에 연결합니다.

데이터베이스 부하 분산

최근에 변경되지 않고 모든 데이터베이스 노드에서 최신 상태인 데이터에 대한 읽기 쿼리를 위해:

  • 응용 프로그램 서버는 데이터베이스 노드의 각 로컬 PgBouncer 서비스에 기본 포트를 통해 라운드 로빈 접근 방식으로 연결합니다.
  • 로컬 PgBouncer는 로컬 데이터베이스 서버의 [PostgreSQL 기본 포트]에 연결합니다.

복제

  • Patroni는 작동 중인 PostgreSQL 프로세스 및 구성을 적극적으로 관리합니다.
  • PostgreSQL 보조 서버는 주요 데이터베이스 서버의 [PostgreSQL 기본 포트]로 연결합니다.
  • Consul 서버 및 에이전트는 서로의 [Consul 기본 포트]에 연결합니다.

## 설정

### 필수 정보

구성을 진행하기 전에 필요한 모든 정보를 수집해야 합니다.

#### 네트워크 정보

기본적으로 PostgreSQL은 어떤 네트워크 인터페이스에서도 수신 대기하지 않습니다. 다른 서비스에서 접근할 수 있도록 수신 대기할 IP 주소를 알아야 합니다. 마찬가지로 PostgreSQL 액세스는 네트워크 소스를 기반으로 제어됩니다.

이것이 필요한 이유입니다:

- 각 노드의 네트워크 인터페이스의 IP 주소입니다. 모든 인터페이스에서 수신 대기하도록 `0.0.0.0`으로 설정할 수 있습니다. 루프백 주소 `127.0.0.1`로 설정할 수는 없습니다.
- 네트워크 주소입니다. 이는 서브넷(즉, `192.168.0.0/255.255.255.0`)이나 클래스리스 인터도메인 라우팅 (CIDR)(`192.168.0.0/24`) 형식으로 설정할 수 있습니다.

#### Consul 정보

기본 설정을 사용하는 경우, 최소 구성에는 다음이 필요합니다:

- `CONSUL_USERNAME`. 리눅스 패키지 설치의 기본 사용자는 `gitlab-consul`입니다.
- `CONSUL_DATABASE_PASSWORD`. 데이터베이스 사용자의 암호입니다.
- `CONSUL_PASSWORD_HASH`. 이는 Consul 사용자명/암호 쌍에서 생성된 해시입니다. 다음과 같이 생성할 수 있습니다:

  ```shell
  sudo gitlab-ctl pg-password-md5 CONSUL_USERNAME
  • CONSUL_SERVER_NODES. Consul 서버 노드의 IP 주소 또는 DNS 레코드입니다.

서비스 자체에 대한 몇 가지 참고 사항:

  • 서비스는 기본적으로 시스템 계정에서 실행됩니다. 기본적으로 gitlab-consul입니다.
  • 다른 사용자명을 사용하는 경우, CONSUL_USERNAME 변수를 통해 지정해야 합니다.
  • 암호는 다음 위치에 저장됩니다:
    • /etc/gitlab/gitlab.rb: 해시값
    • /var/opt/gitlab/pgbouncer/pg_auth: 해시값
    • /var/opt/gitlab/consul/.pgpass: 평문

PostgreSQL 정보

PostgreSQL을 구성할 때 다음을 수행합니다:

  • 패트로니는 복제를 시작할 때 노드 당 하나의 추가 슬롯을 사용하므로 max_replication_slots를 데이터베이스 노드 수의 두 배로 설정합니다.
  • 클러스터에서 이용 가능한 복제 슬롯의 할당된 수보다 하나 더 max_wal_senders를 설정합니다. 이렇게 함으로써 복제가 모든 사용 가능한 데이터베이스 연결을 사용하는 것을 방지합니다.

이 문서에서는 3개의 데이터베이스 노드를 가정하므로, 이러한 구성이 됩니다:

patroni['postgresql']['max_replication_slots'] = 6
patroni['postgresql']['max_wal_senders'] = 7

앞서 언급했듯이, 데이터베이스와 인증할 수 있는 네트워크 서브넷을 준비해야 합니다. 또한 Consul 서버 노드의 IP 주소 또는 DNS 레코드를 준비해야 합니다.

응용 프로그램의 데이터베이스 사용자에 대한 다음 암호 정보가 필요합니다:

  • POSTGRESQL_USERNAME. 리눅스 패키지 설치의 기본 사용자는 gitlab입니다.
  • POSTGRESQL_USER_PASSWORD. 데이터베이스 사용자의 암호입니다.
  • POSTGRESQL_PASSWORD_HASH. 이는 사용자명/암호 쌍에서 생성된 해시입니다. 다음과 같이 생성할 수 있습니다:

    sudo gitlab-ctl pg-password-md5 POSTGRESQL_USERNAME
    

Patroni 정보

패트로니 API에 대한 다음 패스워드 정보가 필요합니다:

  • PATRONI_API_USERNAME. API에 대한 기본 인증을 위한 사용자명
  • PATRONI_API_PASSWORD. API에 대한 기본 인증을 위한 암호

PgBouncer 정보

기본 설정을 사용하는 경우, 최소 구성에는 다음이 필요합니다:

  • PGBOUNCER_USERNAME. 리눅스 패키지 설치의 기본 사용자는 pgbouncer입니다.
  • PGBOUNCER_PASSWORD. PgBouncer 서비스의 암호입니다.
  • PGBOUNCER_PASSWORD_HASH. 이는 PgBouncer 사용자명/암호 쌍에서 생성된 해시입니다. 다음과 같이 생성할 수 있습니다:

    sudo gitlab-ctl pg-password-md5 PGBOUNCER_USERNAME
    
  • PGBOUNCER_NODE은 PgBouncer를 실행 중인 노드의 IP 주소 또는 완전한 도메인 이름(FQDN)입니다.

서비스 자체에 대한 몇 가지 참고 사항:

  • 서비스는 데이터베이스와 동일한 시스템 계정에서 실행됩니다. 패키지에서 기본적으로 gitlab-psql입니다.
  • PgBouncer 서비스에 대해 기본 사용자 계정이 아닌 사용자 계정을 사용하는 경우(기본값은 pgbouncer), 해당 사용자명을 지정해야 합니다.
  • 암호는 다음 위치에 저장됩니다:
    • /etc/gitlab/gitlab.rb: 해시값 및 평문
    • /var/opt/gitlab/pgbouncer/pg_auth: 해시값

Linux 패키지 설치

먼저, Linux 패키지를 다운로드하고 설치하세요 각 노드에.

1단계에서 필요한 종속성을 설치하고, 2단계에서 GitLab 패키지 리포지토리를 추가하세요. GitLab 패키지를 설치할 때 EXTERNAL_URL 값을 제공하면 안 됩니다.

데이터베이스 노드 구성

  1. Consul 노드를 구성했는지 확인하세요.
  2. 다음 단계를 실행하기 전에 CONSUL_SERVER_NODES, PGBOUNCER_PASSWORD_HASH, POSTGRESQL_PASSWORD_HASH, db 노드 수, 및 네트워크 주소를 수집했는지 확인하세요.

패트로니 클러스터 구성

패트로니를 사용하려면 명시적으로 활성화해야 합니다 (patroni['enable'] = true).

wal_level, max_wal_senders 등 복제를 제어하는 모든 PostgreSQL 구성 항목은 엄격하게 패트로니에 의해 제어됩니다. 이러한 구성은 postgresql[...] 설정 키를 사용하여 만든 원래 설정을 재정의합니다. 따라서 복제 외에는 이러한 구성은 patroni['postgresql'][...] 하위로 분리되어 배치됩니다. 이러한 동작은 복제에 한정됩니다. Patroni는 postgresql[...] 설정 키로 만든 다른 PostgreSQL 구성을 준수합니다. 예를 들어, max_wal_senders는 기본적으로 5로 설정됩니다. 이를 변경하려면 patroni['postgresql']['max_wal_senders'] 설정 키로 설정해야 합니다.

다음은 예시입니다:

# 패트로니, PgBouncer 및 Consul만 활성화하고 모든 구성 요소 비활성화
roles(['patroni_role', 'pgbouncer_role'])

# PostgreSQL 구성
postgresql['listen_address'] = '0.0.0.0'

# 자동 데이터베이스 마이그레이션 비활성화
gitlab_rails['auto_migrate'] = false

# Consul 에이전트 구성
consul['services'] = %w(postgresql)

# START 사용자 구성
#  필수 정보 섹션에 설명된 실제 값으로 설정
#
# 생성된 md5 값으로 PGBOUNCER_PASSWORD_HASH 치환
postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
# 생성된 md5 값으로 POSTGRESQL_REPLICATION_PASSWORD_HASH 치환
postgresql['sql_replication_password'] = 'POSTGRESQL_REPLICATION_PASSWORD_HASH'
# 생성된 md5 값으로 POSTGRESQL_PASSWORD_HASH 치환
postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'

# 패트로니 Rest API 호출에 사용할 사용자명으로 PATRONI_API_USERNAME 치환 (모든 노드에서 동일한 사용자명 사용)
patroni['username'] = 'PATRONI_API_USERNAME'
# 패트로니 Rest API 호출에 사용할 암호로 PATRONI_API_PASSWORD 치환 (모든 노드에서 동일한 암호 사용)
patroni['password'] = 'PATRONI_API_PASSWORD'

# `max_replication_slots`를 데이터베이스 노드 수의 두 배로 설정합니다.
# 패트로니는 복제를 시작할 때 노드 당 하나의 추가 슬롯을 사용합니다.
patroni['postgresql']['max_replication_slots'] = X

# 클러스터의 복제 슬롯 수보다 하나 더 `max_wal_senders`를 설정합니다.
# 이를 통해 복제가 사용 가능한 모든 데이터베이스 연결을 소비하는 것을 방지합니다.
patroni['postgresql']['max_wal_senders'] = X+1

# 네트워크 주소에 대한 패트로니 노드 목록을 치환
# XXX.XXX.XXX.XXX/YY와 같이 네트워크 주소를 사용하십시오
patroni['allowlist'] = %w(XXX.XXX.XXX.XXX/YY 127.0.0.1/32)

# 네트워크 주소를 치환
postgresql['trust_auth_cidr_addresses'] = %w(XXX.XXX.XXX.XXX/YY 127.0.0.1/32)

# 데이터베이스 로드 밸런싱을 위한 로컬 PgBouncer 서비스
pgbouncer['databases'] = {
  gitlabhq_production: {
    host: "127.0.0.1",
    user: "PGBOUNCER_USERNAME",
    password: 'PGBOUNCER_PASSWORD_HASH'
  }
}

# 자리 표시자 치환:
#
# Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z
# CONSUL_SERVER_NODES로 수집한 주소로 치환
consul['configuration'] = {
  retry_join: %w(Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z)
}
#
# END user configuration

모든 데이터베이스 노드는 동일한 구성을 사용합니다. 리더 노드는 구성에서 결정되지 않으며, 리더 노드 또는 복제 노드를 위한 추가 또는 다른 구성이 없습니다.

노드 구성이 완료된 후 변경 사항이 적용되도록 각 노드에서 GitLab을 재구성해야 합니다.

일반적으로 Consul 클러스터가 준비되면 첫 번째 노드가 리더가 됩니다. 노드 재구성을 순차적으로 진행하지 않아도 됩니다. 병렬로 또는 순서에 상관없이 실행할 수 있습니다. 임의로 선택하면 사전에 결정된 리더가 없습니다.

모니터링 활성화

모니터링을 활성화하려면 모든 데이터베이스 서버에서 활성화해야 합니다.

  1. /etc/gitlab/gitlab.rb 파일을 생성/편집하고 다음 구성을 추가합니다:

    # Prometheus를 위한 서비스 디스커버리 활성화
    consul['monitoring_service_discovery'] = true
    
    # 익스포터가 수신해야 하는 네트워크 주소 설정
    node_exporter['listen_address'] = '0.0.0.0:9100'
    postgres_exporter['listen_address'] = '0.0.0.0:9187'
    
  2. 구성을 컴파일하려면 sudo gitlab-ctl reconfigure를 실행하세요.

Patroni API의 TLS 지원 활성화

기본적으로 Patroni REST API는 HTTP를 통해 제공됩니다. HTTPS를 사용하여 동일한 포트에서 TLS를 활성화할 수 있습니다.

TLS를 활성화하려면 PEM 형식의 인증서 및 개인 키 파일이 필요합니다. 두 파일 모두 PostgreSQL 사용자 (gitlab-psql이 기본값이거나 postgresql['username']으로 설정된 사용자)가 읽을 수 있어야 합니다:

patroni['tls_certificate_file'] = '/path/to/server/certificate.pem'
patroni['tls_key_file'] = '/path/to/server/key.pem'

서버의 개인 키가 암호화된 경우 복호화하는 비밀번호를 지정하세요:

patroni['tls_key_password'] = 'private-key-password' # 이것은 일반 텍스트 암호입니다.

자체 서명된 인증서나 내부 CA를 사용하는 경우 TLS 검증을 비활성화하거나 내부 CA의 인증서를 전달해야 합니다. 그렇지 않으면 gitlab-ctl patroni .... 명령을 사용할 때 예기치 않은 오류가 발생할 수 있습니다. Linux 패키지를 통해 Patroni API 클라이언트가 이 구성을 준수하도록 합니다.

TLS 인증서 검증은 기본적으로 활성화됩니다. 비활성화하려면:

patroni['tls_verify'] = false

또는 내부 CA의 PEM 형식의 인증서를 전달할 수 있습니다. 마찬가지로, 해당 파일은 PostgreSQL 사용자가 읽을 수 있어야 합니다:

patroni['tls_ca_file'] = '/path/to/ca.pem'

TLS가 활성화된 경우 API 서버와 클라이언트의 상호 인증이 가능합니다. 그 범위는 patroni['tls_client_mode'] 속성에 따라 다릅니다:

  • none (기본값): API에서는 어떠한 클라이언트 인증도 확인하지 않습니다.
  • optional: 클라이언트 인증은 모든 안전하지 않은 API 호출에 필요합니다.
  • required: 클라이언트 인증은 모든 API 호출에 필요합니다.

클라이언트 인증서는 patroni['tls_ca_file'] 속성으로 지정된 CA 인증서에 대해 확인됩니다. 따라서 상호 TLS 인증을 위한 이 속성이 필요합니다. 또한 PEM 형식의 클라이언트 인증서 및 개인 키 파일을 지정해야 합니다. 이 두 파일 모두 PostgreSQL 사용자가 읽을 수 있어야 합니다:

patroni['tls_client_mode'] = 'required'
patroni['tls_ca_file'] = '/path/to/ca.pem'

patroni['tls_client_certificate_file'] = '/path/to/client/certificate.pem'
patroni['tls_client_key_file'] = '/path/to/client/key.pem'

모든 Patroni 노드에서 서로 다른 인증서 및 키를 사용할 수 있습니다. 그러나 내부 CA 인증서(patroni['tls_ca_file']), TLS 인증서 검증(patroni['tls_verify']), 및 클라이언트 TLS 인증 모드(patroni['tls_client_mode'])는 각 노드에서 동일한 값을 가져야 합니다.

PgBouncer 노드 구성

  1. 다음 단계를 실행하기 전에 CONSUL_SERVER_NODES, CONSUL_PASSWORD_HASH, 및 PGBOUNCER_PASSWORD_HASH를 수집했는지 확인하세요.

  2. 각 노드에서 /etc/gitlab/gitlab.rb 구성 파일을 편집하고 # START user configuration 섹션에 아래와 같이 값으로 변경하세요:

    # PgBouncer와 Consul 에이전트를 제외한 모든 구성 비활성화
    roles(['pgbouncer_role'])
    
    # PgBouncer 구성
    pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
    
    # Consul 에이전트 구성
    consul['watchers'] = %w(postgresql)
    
    # START user configuration
    # 필수 정보 섹션에 설명된 대로 실제 값 설정
    # 'CONSUL_PASSWORD_HASH'를 생성된 md5 값으로, 'PGBOUNCER_PASSWORD_HASH'를 생성된 md5 값으로 대체
    pgbouncer['users'] = {
      'gitlab-consul': {
        password: 'CONSUL_PASSWORD_HASH'
      },
      'pgbouncer': {
        password: 'PGBOUNCER_PASSWORD_HASH'
      }
    }
    # 플레이스홀더 대체:
    #
    # Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z
    # CONSUL_SERVER_NODES에서 수집한 주소로 대체
    consul['configuration'] = {
      retry_join: %w(Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z)
    }
    #
    # END user configuration
    
  3. gitlab-ctl reconfigure을 실행하세요.

  4. Consul이 PgBouncer를 다시로드할 수 있도록 .pgpass 파일을 생성하세요. 묻힐 때 PGBOUNCER_PASSWORD를 두 번 입력하세요:

    gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
    
  5. 모니터링을 활성화

PgBouncer Checkpoint

  1. 각 노드가 현재 노드 리더와 통신하도록 확인하세요:

    gitlab-ctl pgb-console # 암호를 입력 요청 받으면 PGBOUNCER_PASSWORD를 입력하세요
    

    암호를 입력한 후 psql: ERROR: Auth failed라는 오류가 발생하면 이전에 올바른 형식으로 MD5 패스워드 해시를 생성했는지 확인하세요. 올바른 형식은 비밀번호와 사용자 이름을 연결하는 것입니다. 즉, PASSWORDUSERNAME. 예를 들어, Sup3rS3cr3tpgbouncerpgbouncer 사용자를 위해 MD5 패스워드 해시를 생성하는 데 필요한 텍스트입니다.

  2. 콘솔 프롬프트를 사용할 수 있게 되면 다음 쿼리를 실행하세요:

    show databases ; show clients ;
    

    출력은 다음과 유사해야 합니다:

            name         |  host       | port |      database       | force_user | pool_size | reserve_pool | pool_mode | max_connections | current_connections
    ---------------------+-------------+------+---------------------+------------+-----------+--------------+-----------+-----------------+---------------------
     gitlabhq_production | MASTER_HOST | 5432 | gitlabhq_production |            |        20 |            0 |           |               0 |                   0
     pgbouncer           |             | 6432 | pgbouncer           | pgbouncer  |         2 |            0 | statement |               0 |                   0
    (2 rows)
    
     type |   user    |      database       |  state  |   addr         | port  | local_addr | local_port |    connect_time     |    request_time     |    ptr    | link | remote_pid | tls
    ------+-----------+---------------------+---------+----------------+-------+------------+------------+---------------------+---------------------+-----------+------+------------+-----
     C    | pgbouncer | pgbouncer           | active  | 127.0.0.1      | 56846 | 127.0.0.1  |       6432 | 2017-08-21 18:09:59 | 2017-08-21 18:10:48 | 0x22b3880 |      |          0 |
    (2 rows)
    

내부 로드 밸런서 구성

권장 사항대로 하나 이상의 PgBouncer 노드를 실행 중이라면, 각각을 올바르게 제공하기 위해 TCP 내부 로드 밸런서를 설정해야 합니다. 이는 신뢰할 수 있는 TCP 로드 밸런서 중 어떤 것이든 사용하여 수행할 수 있습니다.

예를 들어, 다음은 HAProxy를 사용하여 수행하는 방법입니다:

global
    log /dev/log local0
    log localhost local1 notice
    log stdout format raw local0

defaults
    log global
    default-server inter 10s fall 3 rise 2
    balance leastconn

frontend internal-pgbouncer-tcp-in
    bind *:6432
    mode tcp
    option tcplog

    default_backend pgbouncer

backend pgbouncer
    mode tcp
    option tcp-check

    server pgbouncer1 <ip>:6432 check
    server pgbouncer2 <ip>:6432 check
    server pgbouncer3 <ip>:6432 check

자세한 지침은 선호하는 로드 밸런서의 설명서를 참조하십시오.

애플리케이션 노드 구성

애플리케이션 노드는 gitlab-rails 서비스를 실행합니다. 다른 속성이 설정되어 있을 수 있지만, 다음 사항을 설정해야 합니다.

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

    # 응용 프로그램 노드에서 PostgreSQL 비활성화
    postgresql['enable'] = false
    
    gitlab_rails['db_host'] = 'PGBOUNCER_NODE' or 'INTERNAL_LOAD_BALANCER'
    gitlab_rails['db_port'] = 6432
    gitlab_rails['db_password'] = 'POSTGRESQL_USER_PASSWORD'
    gitlab_rails['auto_migrate'] = false
    gitlab_rails['db_load_balancing'] = { 'hosts' => ['POSTGRESQL_NODE_1', 'POSTGRESQL_NODE_2', 'POSTGRESQL_NODE_3'] }
    
  2. 변경 사항이 적용되려면 GitLab을 다시 구성하십시오.

애플리케이션 노드 후 구성

모든 마이그레이션을 실행했는지 확인하십시오:

gitlab-rake gitlab:db:configure

참고: PgBouncer가 PostgreSQL에 연결하지 못하는 오류(rake aborted! 에러)가 발생하면, 데이터베이스 노드의 gitlab.rb에서 PgBouncer 노드의 IP 주소가 trust_auth_cidr_addresses에 누락된 경우일 수 있습니다. 계속하기 전에 PgBouncer 오류 ERROR: pgbouncer cannot connect to server를 참조하십시오.

백업

PgBouncer 연결을 통해 GitLab을 백업하거나 복원하지 마십시오. 이렇게 하면 GitLab 장애가 발생합니다.

이와 백업을 다시 구성하는 방법에 대해 자세히 읽어보십시오.

GitLab 실행 여부 확인

이 시점에서 GitLab 인스턴스가 실행 중이어야 합니다. 로그인하고 이슈를 생성하고 병합 요청을 만들 수 있는지 확인하십시오. 자세한 정보는 복제 및 장애 조치 문제 해결을 참조하십시오.

구성 예

이 부분에서는 여러 가지로 확장된 예제 구성을 설명합니다.

권장 구성 예제

이 예제는 세 개의 Consul 서버, 세 개의 PgBouncer 서버(관련된 내부 로드 밸런서 포함), 세 개의 PostgreSQL 서버, 그리고 하나의 애플리케이션 노드를 사용합니다.

모든 서버가 동일한 10.6.0.0/16 사설 네트워크 범위에서 시작되어 서로 해당 주소로 자유롭게 연결할 수 있습니다.

다음은 각 기계 및 할당된 IP의 목록과 설명입니다:

  • 10.6.0.11: Consul 1
  • 10.6.0.12: Consul 2
  • 10.6.0.13: Consul 3
  • 10.6.0.20: 내부 로드 밸런서
  • 10.6.0.21: PgBouncer 1
  • 10.6.0.22: PgBouncer 2
  • 10.6.0.23: PgBouncer 3
  • 10.6.0.31: PostgreSQL 1
  • 10.6.0.32: PostgreSQL 2
  • 10.6.0.33: PostgreSQL 3
  • 10.6.0.41: GitLab 애플리케이션

모든 암호는 toomanysecrets로 설정되어 있습니다. 이 패스워드 또는 파생된 해시를 사용하지 마십시오. 또한 GitLab의 external_urlhttp://gitlab.example.com입니다.

초기 구성 후 장애 조치가 발생하면 PostgreSQL 리더 노드가 이용 가능한 보조 노드 중 하나로 변경됩니다.

Consul 서버의 권장 구성 예제

각 서버에서 /etc/gitlab/gitlab.rb를 편집하십시오:

# Consul 이외의 모든 구성 요소 비활성화
roles(['consul_role'])

consul['configuration'] = {
  server: true,
  retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
}
consul['monitoring_service_discovery'] =  true

변경 사항이 적용되려면 GitLab을 다시 구성하십시오.

PgBouncer 서버의 권장 구성 예제

각 서버에서 /etc/gitlab/gitlab.rb를 편집하십시오:

# PgBouncer 및 Consul 에이전트 이외의 모든 구성 요소 비활성화
roles(['pgbouncer_role'])

# PgBouncer 구성
pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)

pgbouncer['users'] = {
  'gitlab-consul': {
    password: '5e0e3263571e3704ad655076301d6ebe'
  },
  'pgbouncer': {
    password: '771a8625958a529132abe6f1a4acb19c'
  }
}

consul['watchers'] = %w(postgresql)
consul['configuration'] = {
  retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
}
consul['monitoring_service_discovery'] =  true

변경 사항이 적용되려면 GitLab을 다시 구성하십시오.

내부로드 밸런서 설정

내부 로드 밸런서 (TCP)는 각 PgBouncer 노드를 제공하기 위해 설정해야 합니다 (이 예에서는 10.6.0.20의 IP에 있음). 이를 수행하는 방법의 예는 PgBouncer 내부 로드 밸런서 구성 섹션에서 찾을 수 있습니다.

PostgreSQL 서버의 권장 설정 예

데이터베이스 노드에서 /etc/gitlab/gitlab.rb을 편집합니다.

# Patroni, PgBouncer 및 Consul 외의 모든 구성 요소 비활성화
roles(['patroni_role', 'pgbouncer_role'])

# PostgreSQL 구성
postgresql['listen_address'] = '0.0.0.0'
postgresql['hot_standby'] = 'on'
postgresql['wal_level'] = 'replica'

# 자동 데이터베이스 마이그레이션 비활성화
gitlab_rails['auto_migrate'] = false

postgresql['pgbouncer_user_password'] = '771a8625958a529132abe6f1a4acb19c'
postgresql['sql_user_password'] = '450409b85a0223a214b5fb1484f34d0f'
patroni['username'] = 'PATRONI_API_USERNAME'
patroni['password'] = 'PATRONI_API_PASSWORD'
patroni['postgresql']['max_replication_slots'] = 6
patroni['postgresql']['max_wal_senders'] = 7

patroni['allowlist'] = = %w(10.6.0.0/16 127.0.0.1/32)
postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/16 127.0.0.1/32)

# 데이터베이스 로드 밸런싱을 위한 로컬 PgBouncer 서비스
pgbouncer['databases'] = {
  gitlabhq_production: {
    host: "127.0.0.1",
    user: "pgbouncer",
    password: '771a8625958a529132abe6f1a4acb19c'
  }
}

# Consul 에이전트 구성
consul['services'] = %w(postgresql)
consul['configuration'] = {
  retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
}
consul['monitoring_service_discovery'] =  true

변경 사항이 적용되려면 GitLab 다시 구성을 수행합니다.

권장 설정 예 수동 작업

구성을 배포한 후 다음 단계를 수행합니다:

  1. 기본 데이터베이스 노드 찾기:

    gitlab-ctl get-postgresql-primary
    
  2. 10.6.0.41에서 우리의 애플리케이션 서버:

    gitlab-consul 사용자의 PgBouncer 암호를 toomanysecrets로 설정하십시오.

    gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
    

    데이터베이스 마이그레이션 실행:

    gitlab-rake gitlab:db:configure
    

Patroni

Patroni는 PostgreSQL 고가용성을 위한 의견이 달라지는 솔루션입니다. PostgreSQL을 제어하고 그 구성을 재정의하며 수명주기를 관리합니다 (시작, 중지, 다시 시작). Patroni는 PostgreSQL 12+ 클러스터링 및 Geo 배포용 카스케이딩 복제에 대한 유일한 옵션입니다.

기본적인 아키텍처(위에서 언급됨)는 Patroni의 경우 변경되지 않습니다. 데이터베이스 노드 프로비저닝 시 Patroni에 대해 특별한 고려사항이 필요하지 않습니다. Patroni는 클러스터의 상태를 저장하고 리더를 선택하기 위해 Consul에 크게 의존합니다. Consul 클러스터에서의 장애 및 리더 선출은 Patroni 클러스터로 전파됩니다.

Patroni는 클러스터를 모니터링하고 장애 조치를 처리합니다. 주 노드가 실패하면 Consul과 협력하여 PgBouncer에 통지합니다. 실패시 Patroni는 이전 주 노드를 복제본으로 전환하고 자동으로 클러스터에 다시 참여시킵니다.

Patroni를 사용하면 연결 흐름이 약간 다릅니다. 각 노드의 Patroni는 클러스터에 참여하기 위해 Consul 에이전트에 연결합니다. 이후 이 포인트에서 노드가 주 또는 복제본인지를 결정합니다. 이 결정에 따라 Patroni는 직접 Unix 소켓을 통해 통신하는 PostgreSQL을 구성하고 시작합니다. 이는 Consul 클러스터가 기능하지 않거나 리더가 없는 경우에는 Patroni 및 이에 따라 PostgreSQL이 시작되지 않는다는 것을 의미합니다. Patroni는 또한 각 노드의 기본 포트를 통해 접근할 수 있는 REST API를 노출합니다. (../package_information/defaults.md)

복제 상태 확인

gitlab-ctl patroni members를 실행하여 클러스터 상태에 대한 요약을 쿼리합니다:

+ Cluster: postgresql-ha (6970678148837286213) ------+---------+---------+----+-----------+
| Member                              | Host         | Role    | State   | TL | Lag in MB |
+-------------------------------------+--------------+---------+---------+----+-----------+
| gitlab-database-1.example.com       | 172.18.0.111 | Replica | running |  5 |         0 |
| gitlab-database-2.example.com       | 172.18.0.112 | Replica | running |  5 |       100 |
| gitlab-database-3.example.com       | 172.18.0.113 | Leader  | running |  5 |           |
+-------------------------------------+--------------+---------+---------+----+-----------+

복제 상태를 확인하려면:

echo -e 'select * from pg_stat_wal_receiver\x\g\x \n select * from pg_stat_replication\x\g\x' | gitlab-psql

동일한 명령은 모든 세 개의 데이터베이스 서버에서 실행할 수 있습니다. 서버가 수행하는 역할에 따라 이것은 복제에 대한 가능한 정보를 반환합니다.

리더는 복제본당 하나의 기록을 반환해야 합니다:

-[ RECORD 1 ]----+------------------------------
pid              | 371
usesysid         | 16384
usename          | gitlab_replicator
application_name | gitlab-database-1.example.com
client_addr      | 172.18.0.111
client_hostname  |
client_port      | 42900
backend_start    | 2021-06-14 08:01:59.580341+00
backend_xmin     |
state            | streaming
sent_lsn         | 0/EA13220
write_lsn        | 0/EA13220
flush_lsn        | 0/EA13220
replay_lsn       | 0/EA13220
write_lag        |
flush_lag        |
replay_lag       |
sync_priority    | 0
sync_state       | async
reply_time       | 2021-06-18 19:17:14.915419+00

다음과 같은 경우 더 자세히 조사하십시오:

  • 누락되거나 추가된 레코드가 있는 경우.
  • reply_time이 현재가 아닌 경우.

lsn 필드는 현재 복제된 월(write-ahead-log) 세그먼트를 나타냅니다. 리더에서 현재 로그 시퀀스 번호(LSN)를 확인하려면 다음을 실행하십시오:

echo 'SELECT pg_current_wal_lsn();' | gitlab-psql

복제본이 동기화되지 않는 경우, gitlab-ctl patroni members는 누락된 데이터의 양을 나타내고 lag 필드는 경과된 시간을 나타냅니다.

리더가 반환해야 하는 것:

-[ RECORD 1 ]---------+-------------------------------------------------------------------------------------------------
pid                   | 391
status                | streaming
receive_start_lsn     | 0/D000000
receive_start_tli     | 5
received_lsn          | 0/EA13220
received_tli          | 5
last_msg_send_time    | 2021-06-18 19:16:54.807375+00
last_msg_receipt_time | 2021-06-18 19:16:54.807512+00
latest_end_lsn        | 0/EA13220
latest_end_time       | 2021-06-18 19:07:23.844879+00
slot_name             | gitlab-database-1.example.com
sender_host           | 172.18.0.113
sender_port           | 5432
conninfo              | user=gitlab_replicator host=172.18.0.113 port=5432 application_name=gitlab-database-1.example.com

리플리카가 반환해야 하는 것에 대해 PostgreSQL 문서에서 더 읽어보세요.

적절한 Patroni 복제 방법 선택

변경 전 반드시 Patroni 문서 를 주의 깊게 검토하여 몇 가지 옵션은 완전히 이해되지 않으면 잠재적인 데이터 손실의 위험을 가지고 있음을 참고하세요. 설정된 복제 모드 는 허용 가능한 데이터 손실량을 결정합니다.

경고: 복제는 백업 전략이 아닙니다! 신중하게 고려되고 테스트된 백업 솔루션이 대체할 수 있는 것은 없습니다.

리눅스 패키지 설치는 synchronous_commiton으로 기본 설정합니다.

postgresql['synchronous_commit'] = 'on'
gitlab['geo-postgresql']['synchronous_commit'] = 'on'

Patroni 장애 조치 동작 사용자 정의

리눅스 패키지 설치는 Patroni 복원 프로세스를 더 세밀하게 제어하기 위한 여러 옵션을 노출합니다.

각 옵션은 아래와 같이 /etc/gitlab/gitlab.rb의 기본값과 함께 표시됩니다.

patroni['use_pg_rewind'] = true
patroni['remove_data_directory_on_rewind_failure'] = false
patroni['remove_data_directory_on_diverged_timelines'] = false

상위 문서는 항상 최신 정보를 제공합니다, 하지만 아래 테이블은 기능에 대한 최소한의 개요를 제공해야 합니다.

설정 개요
use_pg_rewind 이전 클러스터 리더가 데이터베이스 클러스터에 다시 연결되기 전에 pg_rewind를 실행합니다.
remove_data_directory_on_rewind_failure pg_rewind가 실패하면 로컬 PostgreSQL 데이터 디렉터리를 제거하고 현재 클러스터 리더에서 다시 복제합니다.
remove_data_directory_on_diverged_timelines pg_rewind를 사용할 수 없고 이전 리더의 타임라인이 현재 타임라인에서 벗어났을 경우, 로컬 데이터 디렉토리를 삭제하고 현재 클러스터 리더에서 다시 복제합니다.

Patroni를 위한 데이터베이스 인증

Patroni는 PostgreSQL 인스턴스를 관리하기 위해 Unix 소켓을 사용합니다. 따라서 local 소켓으로부터의 연결은 신뢰할 수 있어야 합니다.

복제본은 리더와 통신하기 위해 복제 사용자(gitlab_replicator가 기본)를 사용합니다. 이 사용자를 위해 trustmd5 인증 중 하나를 선택할 수 있습니다. 만약 postgresql['sql_replication_password']를 설정하면 Patroni는 md5 인증을 사용하며, 그렇지 않으면 trust로 되돌아갑니다.

선택한 인증에 기반하여 postgresql['md5_auth_cidr_addresses']postgresql['trust_auth_cidr_addresses'] 설정에서 클러스터 CIDR을 명시해야 합니다.

Patroni 클러스터 상호작용

gitlab-ctl patroni members를 사용하여 클러스터 구성원의 상태를 확인할 수 있습니다. 각 노드의 상태를 확인하기 위해 gitlab-ctl patronicheck-leadercheck-replica라는 추가 서브 명령을 제공합니다. 이는 노드가 주(primary)인지 복제본(replica)인지를 나타냅니다.

Patroni가 활성화되면 PostgreSQL의 시작, 종료 및 재시작을 전적으로 제어합니다. 이는 특정 노드에서 PostgreSQL을 종료하려면 동일한 노드에서 Patroni를 종료해야 한다는 것을 의미합니다.

sudo gitlab-ctl stop patroni

리더 노드에서 Patroni 서비스를 중지하거나 다시 시작하면 자동 장애 조치가 트리거됩니다. Patroni의 구성을 다시 불러오거나 장애조치를 트리거하는 것 없이 PostgreSQL 프로세스를 다시 시작하려면 gitlab-ctl patronireload 또는 restart 서브 명령을 사용해야 합니다. 이 두 서브 명령은 동일한 patronictl 명령의 래퍼입니다.

Patroni 수동 장애 조치 절차

경고: GitLab 16.5 이전에는 PgBouncer 노드가 Patroni 노드와 함께 자동 장애 조치되지 않습니다. PgBouncer 서비스는 수동으로 다시 시작해야 합니다 .

Patroni는 자동 장애 조치를 지원하지만 수동으로도 수행할 수 있습니다. 여러분은 두 가지 약간 다른 옵션이 있습니다:

  • 장애 조치: 건강한 노드가 없을 때 수동 장애 조치를 수행할 수 있습니다. 어느 PostgreSQL 노드에서든 이 작업을 수행할 수 있습니다:

    sudo gitlab-ctl patroni failover
    
  • 스위치오버: 클러스터가 건강한 상태에서만 작동하며 스위치오버(즉시 발생할 수 있음)를 예약할 수 있습니다. 어느 PostgreSQL 노드에서든 이 작업을 수행할 수 있습니다:

    sudo gitlab-ctl patroni switchover
    

이에 대한 자세한 내용은 Patroni 문서를 참조하세요.

Geo 보조 사이트 고려 사항

Geo 보조 사이트가 PatroniPgBouncer를 사용하는 주 사이트에서 복제할 때 PgBouncer를 통한 복제는 지원되지 않습니다. 보조 사이트는 반드시 Patroni 클러스터의 리더 노드에서 직접 복제해야 합니다. Patroni 클러스터에서 자동 또는 수동 장애 조치가 발생하면 새로운 리더에서 복제하도록 보조 사이트를 수동으로 재지정해야 합니다:

sudo gitlab-ctl replicate-geo-database --host=<신규 리더 IP> --replication-slot=<슬롯 이름>

그렇지 않으면, 복제가 수행되지 않으며 원래 노드가 팔로워 노드로 다시 추가되더라도 동작하지 않습니다. 이는 보조 사이트의 데이터베이스를 다시 동기화하고 동기화할 데이터 양에 따라 오랜 시간이 걸릴 수 있습니다. 동기화 후에도 복제가 작동하지 않는 경우 gitlab-ctl reconfigure를 실행해야 할 수도 있습니다.

Patroni 클러스터 복구

이전 primary를 복제본으로 다시 복구하여 클러스터에 다시 연결하려면 다음과 같이 Patroni를 시작할 수 있습니다:

sudo gitlab-ctl start patroni

추가 구성 또는 개입이 필요하지 않습니다.

Patroni 유지 보수 절차

Patroni를 활성화하면 노드에서 계획된 유지 보수를 실행할 수 있습니다. Patroni가 없는 하나의 노드에서 유지 보수를 수행하려면 다음과 같이 유지 보수 모드로 전환할 수 있습니다.

sudo gitlab-ctl patroni pause

Patroni가 일시 중지된 상태에서는 PostgreSQL의 상태가 변경되지 않습니다. 완료한 후에는 Patroni를 다시 시작할 수 있습니다.

sudo gitlab-ctl patroni resume

더 자세한 내용은 이 주제에 대한 Patroni 문서를 참조하세요.

Patroni 클러스터에서 PostgreSQL 주요 버전 업그레이드

번들된 PostgreSQL 버전 및 각 릴리스의 기본 버전에 대한 목록은 Linux 패키지의 PostgreSQL 버전을 참조하세요.

PostgreSQL을 업그레이드하기 전에 고려해야 할 몇 가지 주요 사항은 다음과 같습니다.

  • Patroni 클러스터를 중지해야 합니다. 즉, 데이터베이스 업그레이드 기간 동안 또는 적어도 리더 노드가 업그레이드될 때까지 GitLab 배포가 중지됩니다. 이는 데이터베이스의 크기에 따라 중대한 다운타임이 될 수 있습니다.

  • PostgreSQL을 업그레이드하면 새로운 데이터 디렉터리와 새로운 제어 데이터가 생성됩니다. Patroni 입장에서는 이것이 다시 부트스트랩해야 하는 새로운 클러스터입니다. 따라서 업그레이드 절차의 일환으로 클러스터 상태(Consul에 저장된)가 지워집니다. 업그레이드가 완료되면 Patroni가 새로운 클러스터를 부트스트랩합니다. 이로써 클러스터 ID가 변경됩니다.

  • 리더와 복제본의 업그레이드 절차는 동일하지 않습니다. 각 노드에서 올바른 절차를 사용하는 것이 중요합니다.

  • 복제본 노드를 업그레이드하면 데이터 디렉터리가 삭제되고, 구성된 복제 메서드(pg_basebackup만 가능한 옵션)를 사용하여 리더에서 다시 동기화됩니다. 데이터베이스의 크기에 따라 복제본이 리더에 따라 잡기까지 시간이 소요될 수 있습니다.

  • 업그레이드 절차에 대한 개요는 Patroni 문서에 개략적으로 설명되어 있습니다. 여기에 몇 가지 조정이 가해진 절차를 구현하는 gitlab-ctl pg-upgrade을 사용할 수 있습니다.

위와 같은 사항을 고려하여 PostgreSQL 업그레이드를 신중하게 계획해야 합니다.

  1. 어느 노드가 리더이고 어느 노드가 복제본인지 확인합니다:

    gitlab-ctl patroni members
    

    참고: Geo 보조 사이트에서 Patroni 리더 노드를 standby leader라고 합니다.

  2. 복제본에서만 Patroni를 중지합니다.

    sudo gitlab-ctl stop patroni
    
  3. 응용 프로그램 노드에서 유지 보수 모드를 활성화합니다.

    sudo gitlab-ctl deploy-page up
    
  4. PostgreSQL을 리더 노드에서 업그레이드하고 업그레이드가 성공적으로 완료되었는지 확인합니다:

    # 기본 명령 시간 제한은 600초이며 '--timeout'으로 구성할 수 있습니다.
    sudo gitlab-ctl pg-upgrade
    

    참고: gitlab-ctl pg-upgrade은 노드의 역할을 감지하려고 시도합니다. 이 역할 감지가 작동하지 않거나 역할이 올바르게 감지되지 않았다고 믿는 경우 --leader 또는 --replica 인수를 사용하여 역할을 수동으로 재정의할 수 있습니다. 사용 가능한 옵션에 대한 자세한 정보는 gitlab-ctl pg-upgrade --help를 참조하세요.

  5. 리더 및 클러스터 상태를 확인합니다. 건강한 리더가 있는 경우에만 계속할 수 있습니다:

    gitlab-ctl patroni check-leader
    
    # 또는
    
    gitlab-ctl patroni members
    
  6. 응용 프로그램 노드에서 이제 유지 보수 모드를 비활성화합니다.

    sudo gitlab-ctl deploy-page down
    
  7. PostgreSQL을 복제본에서 업그레이드합니다(모두 병렬로 수행할 수 있습니다):

    sudo gitlab-ctl pg-upgrade
    

복제본을 업그레이드하는 동안 문제가 발생하는 경우, 이에 대한 해결책으로 문제 해결 섹션이 있을 수 있습니다.

참고: gitlab-ctl revert-pg-upgrade로 PostgreSQL 업그레이드를 되돌리는 경우에도 gitlab-ctl pg-upgrade와 동일한 고려 사항이 있습니다. 먼저 복제본을 중지한 후 리더를 되돌린 다음 복제본을 되돌려야 합니다.

Patroni 클러스터에서 PostgreSQL의 거의 무중단 업그레이드

Status: Experiment

Patroni를 사용하면 기존 클러스터를 중지하지 않고 주요 PostgreSQL 업그레이드를 수행할 수 있습니다. 그러나 이는 업그레이드된 PostgreSQL을 호스팅하기 위해 추가 리소스가 필요합니다. 이 절차를 실제로 실행하면 다음과 같은 단계를 거칩니다.

  • 새로운 버전의 PostgreSQL을 사용하는 새로운 Patroni 클러스터를 생성합니다.
  • 기존 클러스터에서 데이터를 마이그레이션합니다.

이 절차는 비침입적이며, 기존 클러스터에 영향을 미치지 않으며 클러스터를 끄기 전까지만 기존 클러스터에 영향을 미치지 않습니다. 그러나 이로 인해 시간과 리소스를 많이 소비할 수 있으므로 가용성과의 교환을 고려해야 합니다.

순서대로 수행할 단계는 다음과 같습니다.

  1. 새 클러스터를 위한 리소스 프로비저닝.
  2. 사전 점검.
  3. 새 클러스터의 리더 구성.
  4. 기존 리더에서 발행 시작.
  5. 기존 클러스터에서 데이터 복사.
  6. 기존 클러스터에서 데이터 복제.
  7. 새 클러스터 확장.
  8. 응용프로그램을 새 클러스터 사용으로 전환.
  9. 정리.

새 클러스터를 위한 리소스 프로비저닝

Patroni 노드를 위한 새로운 리소스 세트가 필요합니다. 새 Patroni 클러스터는 기존 클러스터와 정확히 같은 노드 수를 필요로 하지 않습니다. 요구 사항에 따라 다른 노드 수를 선택할 수 있습니다. 새 클러스터는 기존의 Consul 클러스터를 사용합니다(patroni['scope']가 다름) 및 PgBouncer 노드를 사용합니다.

기존 클러스터의 리더 노드가 새 클러스터의 노드에서 접근 가능한지 확인하세요.

사전 점검

우리는 Patroni 클러스터의 대부분 다운 타임을 지원하기 위해 PostgreSQL의 논리 복제를 의존합니다. 논리 복제 요구 사항을 충족해야 합니다. 특히 wal_levellogical이어야 합니다. wal_level을 확인하려면 기존 클러스터의 어떤 노드에서 gitlab-psql로 다음 명령을 실행하세요:

SHOW wal_level;

기본적으로 Patroni는 wal_levelreplica로 설정합니다. 이를 logical로 증가해야 합니다. wal_level을 변경하려면 PostgreSQL을 다시 시작해야 하므로 이 단계는 짧은 다운타임을 유발합니다(따라서 거의 없는 다운타임). 이를 Patroni leader 노드에서 수행하세요:

  1. 다음과 같이 gitlab.rb 파일을 편집하세요:

    patroni['postgresql']['wal_level'] = 'logical'
    
  2. gitlab-ctl reconfigure을 실행하세요. 이렇게 하면 구성이 작성되지만 PostgreSQL 서비스는 다시 시작되지 않습니다.
  3. gitlab-ctl patroni restart를 실행하여 PostgreSQL을 다시 시작하고 새 wal_level을 적용하세요. 장애 조치를 유발하지 않고 리스타트 주기 동안 클러스터 리더는 사용할 수 없습니다.
  4. gitlab-psqlSHOW wal_level을 실행하여 변경 사항을 확인하세요.

새 클러스터의 리더 구성

새 클러스터의 첫 번째 노드를 구성하세요. 이것은 새 클러스터의 리더가 됩니다. 기존 PostgreSQL 버전과 호환되는 경우 기존 클러스터의 구성을 사용할 수 있습니다. Patroni 클러스터 구성 문서를 참조하세요.

일반적인 구성에 추가하여 gitlab.rb에서 다음을 적용해야 합니다:

  1. 새 Patroni 클러스터가 다른 scope를 사용하도록 확인하세요. scope는 Consul에서 Patroni 설정의 네임 스페이스를 사용하여 기존 및 새 클러스터에 동일한 Consul 클러스터를 사용할 수 있게 합니다.

    patroni['scope'] = 'postgresql_new-ha'
    
  2. 기존 및 새 Patroni 클러스터가 Consul 에이전트가 PostgreSQL 서비스를 혼합하지 않도록 확인하세요. 이를 위해 다음과 같은 내부 속성을 사용해야 합니다:

    consul['internal']['postgresql_service_name'] = 'postgresql_new'
    

기존 리더에서 퍼블리셔 시작

기존 리더에서 이 SQL 문을 gitlab-psql로 실행하여 논리 복제 퍼블리셔를 시작하세요:

CREATE PUBLICATION patroni_upgrade FOR ALL TABLES;

기존 클러스터에서 데이터 복사

기존 클러스터의 리더에서 현재 데이터베이스를 덤프하려면 다음 명령을 실행하세요:

  1. 선택 사항. 전역 데이터베이스 객체 복사:

    pg_dumpall -h ${EXISTING_CLUSTER_LEADER} -U gitlab-psql -g | gitlab-psql
    

    역할과 같은 기존 데이터베이스 객체에 대한 오류를 무시할 수 있습니다. 이러한 객체는 노드가 처음 구성될 때 생성됩니다.

  2. 현재 데이터베이스 복사:

    pg_dump -h ${EXISTING_CLUSTER_LEADER} -U gitlab-psql -d gitlabhq_production -s | gitlab-psql
    

    데이터베이스 크기에 따라 이 명령의 완료에는 시간이 걸릴 수 있습니다.

pg_dumppg_dumpall 명령은 /opt/gitlab/embedded/bin에 있습니다. 이 명령에서 EXISTING_CLUSTER_LEADER는 기존 클러스터의 리더 노드의 호스트 주소입니다.

참고: gitlab-psql 사용자는 새 리더 노드에서 기존 리더를 인증할 수 있어야 합니다.

기존 클러스터에서 데이터 복제

초기 데이터 덤프를 취한 후 새 리더를 기존 클러스터의 최신 변경 사항과 동기화 상태로 유지해야 합니다. 새 리더에서 gitlab-psql로 이 SQL 문을 실행하여 기존 리더의 퍼블리케이션을 구독하세요:

CREATE SUBSCRIPTION patroni_upgrade
  CONNECTION 'host=EXISTING_CLUSTER_LEADER dbname=gitlabhq_production user=gitlab-psql'
  PUBLICATION patroni_upgrade;

이 문에서 EXISTING_CLUSTER_LEADER는 기존 클러스터의 리더 노드의 호스트 주소입니다. 또한 다른 매개변수를 사용하여 연결 문자열을 변경할 수 있습니다. 예를 들어 인증 비밀번호를 전달할 수 있습니다.

복제 상태를 확인하려면 다음 쿼리를 실행하세요:

  • 기존 리더(퍼블리셔)에서 SELECT * FROM pg_replication_slots WHERE slot_name = 'patroni_upgrade'.
  • 새 리더(구독자)에서 SELECT * FROM pg_stat_subscription.

새 클러스터 확장

새 클러스터의 다른 노드를 리더와 동일한 방식으로 구성하세요. patroni['scope']consul['internal']['postgresql_service_name']을 동일하게 사용하는지 확인하세요.

여기서 발생하는 일:

  • 애플리케이션은 여전히 기존 리더를 데이터베이스 백엔드로 사용합니다.
  • 논리 복제를 통해 새 리더가 동기화 유지됩니다.
  • 새 클러스터에 다른 노드를 추가할 때 Patroni가 노드로 복제를 처리합니다.

새 클러스터의 레플리카 노드가 초기화되고 복제 지연 상태에 있는지 확인하는 것이 좋습니다.

애플리케이션을 새 클러스터 사용으로 전환

이 시점까지 기존 클러스터에서 데이터를 잃지 않고 업그레이드 프로시저를 중지할 수 있습니다. 애플리케이션의 데이터베이스 백엔드를 중지하고 새 클러스터로 변경하면 이전 클러스터에 새 업데이트는 도착하지 않습니다. 이전 클러스터는 새 클러스터에 뒤처집니다. 이후, 복구는 새 클러스터의 노드에서 수행해야 합니다.

모든 PgBouncer 노드에서 다음을 수행하세요:

  1. 다음과 같이 gitlab.rb 파일을 편집하세요:

    consul['watchers'] = %w(postgresql_new)
    consul['internal']['postgresql_service_name'] = 'postgresql_new'
    
  2. gitlab-ctl reconfigure를 실행하세요.

정리

이러한 단계를 완료한 후, 이제는 이전 Patroni 클러스터의 리소스를 정리할 수 있습니다. 이제 더 이상 필요하지 않습니다. 그러나 리소스를 제거하기 전에 새 리더 노드에서 gitlab-psqlDROP SUBSCRIPTION patroni_upgrade를 실행하여 논리 복제 구독을 제거해야 합니다.