Consul 설정 방법

Tier: 프리미엄, 얼티밋 Offering: Self-managed

Consul 클러스터는 서버 및 클라이언트 에이전트로 구성됩니다. 서버는 자체 노드에서 실행되고 클라이언트는 서버와 통신하는 다른 노드에서 실행됩니다.

GitLab 프리미엄에는 Consul의 번들 버전이 포함되어 있어 /etc/gitlab/gitlab.rb을 사용하여 관리할 수 있는 서비스 네트워킹 솔루션이 제공됩니다.

전제 조건

Consul 설정 전에:

  1. 참조 아키텍처 문서를 검토하여 가져야 할 Consul 서버 노드의 수를 결정하세요.
  2. 필요한 경우 방화벽에서 적절한 포트가 열려 있는지 확인하세요.

Consul 노드 구성

각각의 Consul 서버 노드에서:

  1. 선호하는 플랫폼을 선택하여 설치 지침을 따르되 EXTERNAL_URL 값을 제공하지 마십시오.
  2. /etc/gitlab/gitlab.rb을 편집하고 retry_join 섹션에 기술된 값을 대체하여 다음을 추가하세요. 아래 예에서는 세 개의 노드가 있으며, 두 노드는 IP로 표시되고 하나는 FQDN으로 표시됩니다. 두 가지 표기법 중 하나를 사용할 수 있습니다.

    # Consul 빼고 다른 모든 컴포넌트를 비활성화
    roles ['consul_role']
    
    # Consul 노드: FQDN이나 IP로 구분하여 사용
    consul['configuration'] = {
      server: true,
      retry_join: %w(10.10.10.1 consul1.gitlab.example.com 10.10.10.2)
    }
    
    # 자동 마이그레이션 비활성화
    gitlab_rails['auto_migrate'] = false
    
  3. 변경 사항이 적용되려면 GitLab 재구성을 실행하세요.
  4. 다음 명령을 실행하여 Consul이 올바르게 구성되었는지 확인하고 모든 서버 노드가 통신하는지 확인하세요.

    sudo /opt/gitlab/embedded/bin/consul members
    

    결과는 다음과 유사해야 합니다.

    Node                 Address               Status  Type    Build  Protocol  DC
    CONSUL_NODE_ONE      XXX.XXX.XXX.YYY:8301  alive   server  0.9.2  2         gitlab_consul
    CONSUL_NODE_TWO      XXX.XXX.XXX.YYY:8301  alive   server  0.9.2  2         gitlab_consul
    CONSUL_NODE_THREE    XXX.XXX.XXX.YYY:8301  alive   server  0.9.2  2         gitlab_consul
    

    결과에서 상태가 alive가 아닌 노드가 나오거나 세 노드 중 어느 것이 누락된 경우 문제 해결 섹션을 참조하세요.

Consul 노드 보안

Consul 노드 간 통신을 보안하는 두 가지 방법이 있습니다. TLS 또는 gossip 암호화를 사용할 수 있습니다.

TLS 암호화

기본적으로 Consul 클러스터에 대해 TLS가 활성화되지 않습니다. 기본 구성 옵션과 기본값은 다음과 같습니다.

consul['use_tls'] = false
consul['tls_ca_file'] = nil
consul['tls_certificate_file'] = nil
consul['tls_key_file'] = nil
consul['tls_verify_client'] = nil

이러한 구성 옵션은 클라이언트 및 서버 노드에 적용됩니다.

Consul 노드에서 TLS를 활성화하려면 consul['use_tls'] = true로 시작해야 합니다. 노드의 역할(서버 또는 클라이언트) 및 TLS 환경에 따라 추가 구성을 제공해야 합니다.

  • 서버 노드에서는 적어도 tls_ca_file, tls_certificate_file, 및 tls_key_file을 지정해야 합니다.
  • 클라이언트 노드에서는 기본적으로 클라이언트 TLS 인증이 비활성화되어 있으며(기본적으로 활성화되어 있음), tls_ca_file을 최소한 지정해야 합니다. 그렇지 않으면 클라이언트 TLS 인증을 통해 클라이언트 TLS 인증서 및 키를 전달해야 합니다(tls_certificate_file, tls_key_file).

기본적으로 서버는 mTLS를 사용하고 HTTPS 및 HTTP(그리고 TLS 및 비-TLS RPC)에서 수신 대기합니다. 클라이언트가 TLS 인증을 사용하도록 회원을 기대합니다. consul['tls_verify_client'] = false로 클라이언트 TLS 인증을 비활성화할 수 있습니다.

한편, 클라이언트는 발신 연결에 대해 TLS만 사용하며 수신 요청에 대해 HTTP(및 비-TLS RPC)에서만 수신 대기합니다. 클라이언트 Consul 에이전트가 수신 연결에 대해 TLS를 사용하도록 강제합니 다. consul['https_port']를 음수가 아닌 정수로 설정하여 클라이언트 Consul 에이전트가 수신 연결에 대해 TLS를 사용하도록 강제할 수 있습니다(8501은 Consul의 기본 HTTPS 포트입니다). 이를 위해 tls_certificate_filetls_key_file를 전달해야 합니다. 서버 노드가 클라이언트 TLS 인증을 사용하는 경우 클라이언트 TLS 인증서 및 키가 TLS 인증 및 수신 HTTPS 연결에 모두 사용됩니다.

Consul 클라이언트 노드는 기본적으로 TLS 클라이언트 인증을 사용하지 않으며(서버와 대조적) 명시적으로 consul['tls_verify_client'] = true로 설정해야합니다.

TLS 암호화의 몇 가지 예는 다음과 같습니다.

최소한의 TLS 지원

다음 예에서 서버는 클라이언트 TLS 인증을 사용하지 않고 수신 연결에 대해 TLS를 사용합니다.

Consul 서버 노드
  1. /etc/gitlab/gitlab.rb 편집:

    consul['enable'] = true
    consul['configuration'] = {
      'server' => true
    }
    
    consul['use_tls'] = true
    consul['tls_ca_file'] = '/path/to/ca.crt.pem'
    consul['tls_certificate_file'] = '/path/to/server.crt.pem'
    consul['tls_key_file'] = '/path/to/server.key.pem'
    consul['tls_verify_client'] = false
    
  2. GitLab 재구성:

    sudo gitlab-ctl reconfigure
    
Consul 클라이언트 노드

다음은 예를 들어 Patroni 노드에서 구성할 수 있습니다.

  1. /etc/gitlab/gitlab.rb 편집:

    consul['enable'] = true
    consul['use_tls'] = true
    consul['tls_ca_file'] = '/path/to/ca.crt.pem'
    patroni['consul']['url'] = 'http://localhost:8500'
    
  2. GitLab 재구성:

    sudo gitlab-ctl reconfigure
    

Patroni는 로컬 Consul 에이전트와 통신하며 수신 연결에 TLS를 사용하지 않습니다. 따라서 patroni['consul']['url']에 HTTP URL을 사용합니다.

기본 TLS 지원

다음 예에서 서버는 상호 TLS 인증을 사용합니다.

콘설 서버 노드
  1. /etc/gitlab/gitlab.rb를 편집하십시오:

    consul['enable'] = true
    consul['configuration'] = {
      'server' => true
    }
    
    consul['use_tls'] = true
    consul['tls_ca_file'] = '/path/to/ca.crt.pem'
    consul['tls_certificate_file'] = '/path/to/server.crt.pem'
    consul['tls_key_file'] = '/path/to/server.key.pem'
    
  2. GitLab을 다시 구성하십시오:

    sudo gitlab-ctl reconfigure
    
콘설 클라이언트 노드

다음은 예를 들어 Patroni 노드에서 구성할 수 있습니다.

  1. /etc/gitlab/gitlab.rb를 편집하십시오:

    consul['enable'] = true
    consul['use_tls'] = true
    consul['tls_ca_file'] = '/path/to/ca.crt.pem'
    consul['tls_certificate_file'] = '/path/to/client.crt.pem'
    consul['tls_key_file'] = '/path/to/client.key.pem'
    patroni['consul']['url'] = 'http://localhost:8500'
    
  2. GitLab을 다시 구성하십시오:

    sudo gitlab-ctl reconfigure
    

Patroni는 로컬 콘설 에이전트와 통신할 때 TLS를 사용하지 않지만, TLS 인증은 콘설 서버 노드로부터입니다. 따라서 patroni['consul']['url']에 HTTP URL이 있습니다.

완전한 TLS 지원

다음 예에서 클라이언트와 서버 모두 상호 TLS 인증을 사용합니다.

콘설 서버, 클라이언트, 그리고 Patroni 클라이언트 인증서는 상호 TLS 인증을 위해 동일한 CA에서 발급받아야 합니다.

콘설 서버 노드
  1. /etc/gitlab/gitlab.rb를 편집하십시오:

    consul['enable'] = true
    consul['configuration'] = {
      'server' => true
    }
    
    consul['use_tls'] = true
    consul['tls_ca_file'] = '/path/to/ca.crt.pem'
    consul['tls_certificate_file'] = '/path/to/server.crt.pem'
    consul['tls_key_file'] = '/path/to/server.key.pem'
    
  2. GitLab을 다시 구성하십시오:

    sudo gitlab-ctl reconfigure
    
콘설 클라이언트 노드

다음은 예를 들어 Patroni 노드에서 구성할 수 있습니다.

  1. /etc/gitlab/gitlab.rb를 편집하십시오:

    consul['enable'] = true
    consul['use_tls'] = true
    consul['tls_verify_client'] = true
    consul['tls_ca_file'] = '/path/to/ca.crt.pem'
    consul['tls_certificate_file'] = '/path/to/client.crt.pem'
    consul['tls_key_file'] = '/path/to/client.key.pem'
    consul['https_port'] = 8501
    
    patroni['consul']['url'] = 'https://localhost:8501'
    patroni['consul']['cacert'] = '/path/to/ca.crt.pem'
    patroni['consul']['cert'] = '/opt/tls/patroni.crt.pem'
    patroni['consul']['key'] = '/opt/tls/patroni.key.pem'
    patroni['consul']['verify'] = true
    
  2. GitLab을 다시 구성하십시오:

    sudo gitlab-ctl reconfigure
    

Gossip 암호화

Gossip 프로토콜은 콘설 에이전트 간의 통신을 안전하게 보호하는 데 사용될 수 있습니다. 기본적으로 암호화가 비활성화되어 있으며, 암호화를 활성화하려면 공유 암호화 키가 필요합니다. 편리하게도, gitlab-ctl consul keygen 명령을 사용하여 키를 생성할 수 있습니다. 이 키는 32바이트 길이여야 하며, Base 64로 인코딩되어야 하며 모든 에이전트에 공유되어야 합니다.

다음 옵션은 클라이언트와 서버 노드 모두에서 작동합니다.

Gossip 프로토콜을 활성화하려면:

  1. /etc/gitlab/gitlab.rb를 편집하십시오:

    consul['encryption_key'] = <base-64-key>
    consul['encryption_verify_incoming'] = true
    consul['encryption_verify_outgoing'] = true
    
  2. GitLab을 다시 구성하십시오:

    sudo gitlab-ctl reconfigure
    

기존 데이터 센터에서 암호화를 활성화하려면, 롤링 업데이트를 위해 이러한 옵션을 수동으로 설정하십시오.

콘설 노드 업그레이드

콘설 노드를 업그레이드하려면 GitLab 패키지를 업그레이드하십시오.

노드는 다음과 같아야 합니다:

  • 리눅스 패키지를 업그레이드하기 전에 건강한 클러스터의 멤버여야 합니다.
  • 한 번에 한 노드씩 업그레이드되어야 합니다.

각 노드에서 다음 명령을 실행하여 클러스터의 기존 건강 문제를 식별하십시오. 클러스터가 건강하면 빈 배열이 반환됩니다:

curl "http://127.0.0.1:8500/v1/health/state/critical"

콘설 버전이 변경되었으면, gitlab-ctl reconfigure의 끝에 콘설을 새 버전을 사용하도록 다시 시작해야 한다는 알림이 표시됩니다.

하나의 노드씩 콘설을 다시 시작하십시오:

sudo gitlab-ctl restart consul

콘설 노드는 raft 프로토콜을 사용하여 통신합니다. 현재 리더 노드가 오프라인 상태이면 리더 선출이 있어야 합니다. 클러스터 전체에 동기화를 용이하게 하기 위해 리더 노드가 존재해야 합니다. 너무 많은 노드가 동시에 오프라인 상태가 되면, 클러스터는 합의가 결여되어 리더를 선출하지 못합니다. broken consensus에 의해 리더를 선출하지 못하게 됩니다.

클러스터에서 문제가 해결되지 않는 경우 트러블슈팅 섹션을 참고하십시오. 장애 복구는 특히 중요할 수 있습니다.

GitLab은 콘설을 사용하여 재생성이 쉬운 일시적 데이터만 저장합니다. 번들로 제공된 콘설이 GitLab 이외의 프로세스에서 사용되지 않았다면, 처음부터 클러스터를 재구축할 수 있습니다.

콘설 트러블슈팅

다음은 문제 해결 시 해당 기능 몇 가지 작업입니다. 다음 명령을 사용하여 오류 로그를 확인할 수 있습니다:

sudo gitlab-ctl tail consul

클러스터 멤버십 확인

클러스터의 구성원을 확인하려면 클러스터의 모든 멤버에서 다음을 실행하십시오:

sudo /opt/gitlab/embedded/bin/consul members

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

Node            Address               Status  Type    Build  Protocol  DC
consul-b        XX.XX.X.Y:8301        alive   server  0.9.0  2         gitlab_consul
consul-c        XX.XX.X.Y:8301        alive   server  0.9.0  2         gitlab_consul
consul-c        XX.XX.X.Y:8301        alive   server  0.9.0  2         gitlab_consul
db-a            XX.XX.X.Y:8301        alive   client  0.9.0  2         gitlab_consul
db-b            XX.XX.X.Y:8301        alive   client  0.9.0  2         gitlab_consul

이상적으로 모든 노드의 Statusalive여야 합니다.

Consul 재시작

Consul을 재시작해야 하는 경우, 쿼럼을 유지하기 위해 제어된 방식으로 수행하는 것이 중요합니다. 쿼럼이 손실된 경우 클러스터를 복구하려면 outage recovery 프로세스를 따릅니다.

안전을 위해 클러스터가 손상되지 않도록 보장하기 위해 한 번에 한 노드에서만 Consul을 재시작하는 것이 좋습니다. 더 큰 클러스터의 경우 한 번에 여러 노드를 재시작하는 것이 가능합니다. 동시에 허용할 수 있는 장애 번호에 대한 자세한 내용은 Consul consensus 문서를 참조하십시오. 이는 클러스터가 견딜 수 있는 동시 재시작 횟수입니다.

Consul을 재시작하려면:

sudo gitlab-ctl restart consul

Consul 노드 간 통신 불가능

기본적으로 Consul은 0.0.0.0bind를 시도하지만, 다른 Consul 노드가 해당 노드와 통신하기 위해 첫 번째 개인 IP 주소를 광고합니다. 다른 노드가 이 주소에서 노드와 통신할 수 없는 경우 클러스터는 실패 상태입니다.

이 문제가 발생하는 경우 gitlab-ctl tail consul에서 다음과 같은 메시지가 출력됩니다:

2017-09-25_19:53:39.90821     2017/09/25 19:53:39 [WARN] raft: no known peers, aborting election
2017-09-25_19:53:41.74356     2017/09/25 19:53:41 [ERR] agent: failed to sync remote state: No cluster leader

이를 해결하려면:

  1. 다른 모든 노드가 해당 노드로 접근할 수 있는 주소를 각 노드에서 선택합니다.
  2. /etc/gitlab/gitlab.rb를 업데이트합니다.

    consul['configuration'] = {
      ...
      bind_addr: 'IP 주소'
    }
    
  3. GitLab을 다시 구성합니다.

    gitlab-ctl reconfigure
    

에러가 계속되는 경우 영향을 받는 노드에서 Consul 데이터베이스를 지우고 재초기화해야 할 수 있습니다.

Consul 시작되지 않음 - 여러 개인 IP

노드에 여러 개인 IP가 있는 경우, Consul은 광고할 개인 주소를 알지 못하여 시작 직후 즉시 종료됩니다.

gitlab-ctl tail consul에 다음과 같은 메시지가 출력됩니다:

2017-11-09_17:41:45.52876 ==> Starting Consul agent...
2017-11-09_17:41:45.53057 ==> Error creating agent: Failed to get advertise address: Multiple private IPs found. Please configure one.

이를 해결하려면:

  1. 다른 모든 노드가 해당 노드로 접근할 수 있는 주소를 노드에서 선택합니다.
  2. /etc/gitlab/gitlab.rb를 업데이트합니다.

    consul['configuration'] = {
      ...
      bind_addr: 'IP 주소'
    }
    
  3. GitLab을 다시 구성합니다.

    gitlab-ctl reconfigure
    

장애 복구

쿼럼을 깰 만큼 충분한 수의 Consul 노드를 손실한 경우, 클러스터는 실패한 것으로 간주되어 수동 개입 없이 작동할 수 없습니다. 이 경우 노드를 처음부터 다시 생성하거나 복구를 시도할 수 있습니다.

처음부터 다시 생성

기본적으로 GitLab은 다시 생성할 수 있는 Consul 노드에 아무 것도 저장하지 않습니다. Consul 데이터베이스를 지우고 다시 초기화하려면:

sudo gitlab-ctl stop consul
sudo rm -rf /var/opt/gitlab/consul/data
sudo gitlab-ctl start consul

이후에 노드가 다시 시작되고 다른 서버 에이전트들이 다시 참여합니다. 그 후에 클라이언트 에이전트들도 다시 참여해야 합니다.

그들이 참여하지 않는 경우, 영향을 받는 클라이언트에서도 Consul 데이터를 삭제해야 할 수 있습니다:

sudo rm -rf /var/opt/gitlab/consul/data

실패한 노드 복구

Consul을 사용하여 다른 데이터를 저장하고 실패한 노드를 복구하려는 경우, 실패한 클러스터를 복구하기 위해 Consul 가이드에 따릅니다.