InfoGrab DocsInfoGrab Docs

레퍼런스 아키텍처: 최대 500 RPS 또는 25,000명의 사용자

요약

- Offering: GitLab Self-Managed 이 페이지는 초당 500개 요청(RPS)의 최대 부하를 목표로 설계된 GitLab 레퍼런스 아키텍처를 설명합니다. 전체 레퍼런스 아키텍처 목록은 사용 가능한 레퍼런스 아키텍처를 참조하세요.


레퍼런스 아키텍처: 최대 500 RPS 또는 25,000명의 사용자#

  - 
  Tier: Premium, Ultimate

- Offering: GitLab Self-Managed

이 페이지는 초당 500개 요청(RPS)의 최대 부하를 목표로 설계된 GitLab 레퍼런스 아키텍처를 설명합니다. 이는 실제 데이터를 기반으로 한 수동 및 자동화 방식의 최대 25,000명의 사용자에 해당하는 일반적인 최대 부하입니다.

전체 레퍼런스 아키텍처 목록은 사용 가능한 레퍼런스 아키텍처를 참조하세요.

이 아키텍처를 배포하기 전에 먼저 [주요 문서](/19.2/administration/reference_architectures/)를 읽어보시기 바라며,

특히 시작하기 전에사용할 아키텍처 결정하기 섹션을 확인하세요.

  • 타깃 부하: API: 500 RPS, Web: 50 RPS, Git (Pull): 50 RPS, Git (Push): 10 RPS

  • 고가용성: 예 (HA를 위해 Praefect는 서드파티 PostgreSQL 솔루션 필요)

  • 클라우드 네이티브 하이브리드 대안:

  • 어떤 레퍼런스 아키텍처를 사용해야 할지 모르시겠나요? 이 가이드에서 자세한 내용을 확인하세요

서비스 노드 수 구성 GCP 예시1 AWS 예시1 Azure 예시1
외부 로드 밸런서4 1 8 vCPU, 7.2 GB 메모리 n1-highcpu-8 c5n.2xlarge F8s v2
Consul2 3 2 vCPU, 1.8 GB 메모리 n1-highcpu-2 c5.large F2s v2
PostgreSQL2 3 16 vCPU, 60 GB 메모리 n1-standard-16 m5.4xlarge D16s v3
PgBouncer2 3 2 vCPU, 1.8 GB 메모리 n1-highcpu-2 c5.large F2s v2
내부 로드 밸런서4 1 8 vCPU, 7.2 GB 메모리 n1-highcpu-8 c5n.2xlarge F8s v2
Redis/Sentinel - 캐시3 3 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge D4s v3
Redis/Sentinel - 영구3 3 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge D4s v3
Gitaly67 3 32 vCPU, 120 GB 메모리 n1-standard-32 m5.8xlarge D32s v3
Praefect6 3 4 vCPU, 3.6 GB 메모리 n1-highcpu-4 c5.xlarge F4s v2
Praefect PostgreSQL2 1+ 2 vCPU, 1.8 GB 메모리 n1-highcpu-2 c5.large F2s v2
Sidekiq8 4 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge D4s v3
GitLab Rails8 5 32 vCPU, 28.8 GB 메모리 n1-highcpu-32 c5.9xlarge F32s v2
모니터링 노드 1 4 vCPU, 3.6 GB 메모리 n1-highcpu-4 c5.xlarge F4s v2
오브젝트 스토리지5 - - - - -

각주:

-->

  • 머신 유형 예시는 설명 목적으로 제공됩니다. 이러한 유형은 검증 및 테스트에 사용되지만 규범적인 기본값으로 의도된 것이 아닙니다. 나열된 요구 사항을 충족하는 다른 머신 유형으로의 전환이 지원되며, 가용한 경우 ARM 변형도 포함됩니다. 자세한 내용은 지원되는 머신 유형을 참조하세요.

  • 신뢰할 수 있는 서드파티 외부 PaaS PostgreSQL 솔루션에서 선택적으로 실행할 수 있습니다. 자세한 내용은 자체 PostgreSQL 인스턴스 제공을 참조하세요.

  • 신뢰할 수 있는 서드파티 외부 PaaS Redis 솔루션에서 선택적으로 실행할 수 있습니다. 자세한 내용은 자체 Redis 인스턴스 제공을 참조하세요.

Redis는 기본적으로 단일 스레드이며 CPU 코어 수 증가로부터 크게 이점을 얻지 못합니다. 이 규모의 아키텍처에서는 최적의 성능을 달성하기 위해 지정된 대로 별도의 캐시와 영구 인스턴스를 사용하는 것이 강력히 권장됩니다.

  • 고가용성(HA) 기능을 제공할 수 있는 신뢰할 수 있는 서드파티 로드 밸런서 또는 서비스(LB PaaS)와 함께 실행하는 것이 권장됩니다. 또한 크기는 선택한 로드 밸런서와 네트워크 대역폭 등 추가 요소에 따라 달라집니다. 자세한 내용은 로드 밸런서를 참조하세요.

  • 신뢰할 수 있는 클라우드 제공업체 또는 자체 관리형 솔루션에서 실행해야 합니다. 자세한 내용은 오브젝트 스토리지 구성을 참조하세요.

  • Gitaly 클러스터(Praefect)는 장애 허용성의 이점을 제공하지만 설정 및 관리의 추가적인 복잡성이 따릅니다. Gitaly 클러스터 배포 전 기존 기술적 제한 사항 및 고려 사항을 검토하세요. 샤드된 Gitaly를 원하는 경우 이전 테이블의 Gitaly에 나열된 것과 동일한 사양을 사용하세요.

  • Gitaly 사양은 정상 상태에서의 사용 패턴과 리포지터리 크기의 높은 백분위수를 기반으로 합니다. 그러나 대형 모노리포(수 기가바이트보다 큰 경우)나 추가 워크로드가 있는 경우 Git 및 Gitaly 성능에 상당한 영향을 미칠 수 있으며 추가적인 조정이 필요할 수 있습니다.

  • 해당 컴포넌트가 상태 데이터를 저장하지 않기 때문에 Auto Scaling Groups(ASG)에 배치할 수 있습니다. 그러나 마이그레이션Mailroom과 같은 특정 컴포넌트는 하나의 노드에서만 실행될 수 있어 쿠버네티스에서 더 잘 처리되기 때문에, 일반적으로 클라우드 네이티브 하이브리드 설정이 선호됩니다.

    인스턴스 구성이 포함된 모든 PaaS 솔루션의 경우, 탄력적인 클라우드 아키텍처 관행에 맞추기 위해 세 개의 서로 다른 가용 영역에 최소 세 개의 노드를 구현하는 것이 권장됩니다.

    @startuml 25k skinparam linetype ortho

card "External Load Balancer" as elb #6a9be7 card "Internal Load Balancer" as ilb #9370DB

together { collections "GitLab Rails x5" as gitlab #32CD32 collections "Sidekiq x4" as sidekiq #ff8dd1 }

together { card "Prometheus" as monitor #7FFFD4 collections "Consul x3" as consul #e76a9b }

card "Gitaly Cluster" as gitaly_cluster { collections "Praefect x3" as praefect #FF8C00 collections "Gitaly x3" as gitaly #FF8C00 card "Praefect PostgreSQL*\n//Non fault-tolerant//" as praefect_postgres #FF8C00

praefect -[#FF8C00]-> gitaly praefect -[#FF8C00]> praefect_postgres }

card "Database" as database { collections "PGBouncer x3" as pgbouncer #4EA7FF card "PostgreSQL //Primary//" as postgres_primary #4EA7FF collections "PostgreSQL //Secondary// x2" as postgres_secondary #4EA7FF

pgbouncer -[#4EA7FF]-> postgres_primary postgres_primary .[#4EA7FF]> postgres_secondary }

card "redis" as redis { collections "Redis Persistent x3" as redis_persistent #FF6347 collections "Redis Cache x3" as redis_cache #FF6347

redis_cache -[hidden]-> redis_persistent }

cloud "Object Storage" as object_storage #white

elb -[#6a9be7]-> gitlab elb -[#6a9be7,norank]--> monitor

gitlab -[#32CD32,norank]--> ilb gitlab -[#32CD32]r-> object_storage gitlab -[#32CD32]----> redis gitlab .[#32CD32]----> database gitlab -[hidden]-> monitor gitlab -[hidden]-> consul

sidekiq -[#ff8dd1,norank]--> ilb sidekiq -[#ff8dd1]r-> object_storage sidekiq -[#ff8dd1]----> redis sidekiq .[#ff8dd1]----> database sidekiq -[hidden]-> monitor sidekiq -[hidden]-> consul

ilb -[#9370DB]--> gitaly_cluster ilb -[#9370DB]--> database ilb -[hidden]--> redis ilb -[hidden]u-> consul ilb -[hidden]u-> monitor

consul .[#e76a9b]u-> gitlab consul .[#e76a9b]u-> sidekiq consul .[#e76a9b]r-> monitor consul .[#e76a9b]-> database consul .[#e76a9b]-> gitaly_cluster consul .[#e76a9b,norank]--> redis

monitor .[#7FFFD4]u-> gitlab monitor .[#7FFFD4]u-> sidekiq monitor .[#7FFFD4]> consul monitor .[#7FFFD4]-> database monitor .[#7FFFD4]-> gitaly_cluster monitor .[#7FFFD4,norank]--> redis monitor .[#7FFFD4]> ilb monitor .[#7FFFD4,norank]u--> elb

@enduml

요구사항#

시작하기 전에 레퍼런스 아키텍처의 요구사항을 확인하세요.

테스트 방법론#

500 RPS / 25k 사용자 레퍼런스 아키텍처는 가장 일반적인 워크플로를 수용하도록 설계되었습니다. GitLab은 다음 엔드포인트 처리량 타깃을 기준으로 정기적으로 스모크 및 성능 테스트를 실시합니다:

엔드포인트 유형 타깃 처리량
API 500 RPS
Web 50 RPS
Git (Pull) 50 RPS
Git (Push) 10 RPS

이 타깃은 CI 파이프라인 및 기타 워크로드를 포함하여 지정된 사용자 수에 대한 전체 환경 부하를 반영하는 실제 고객 데이터를 기반으로 합니다. 이는 일반적인 워크로드 구성을 나타냅니다. 비정형 워크로드 패턴에 대한 안내는 RPS 구성 이해하기를 참고하세요.

테스트 방법론에 대한 자세한 내용은 검증 및 테스트 결과 섹션을 참고하세요.

성능 고려사항#

환경에 다음과 같은 상황이 있는 경우 추가적인 조정이 필요할 수 있습니다:

이러한 경우 자세한 내용은 환경 확장하기를 참고하세요. 이러한 고려사항이 해당될 수 있다고 판단되면, 필요한 추가 안내를 위해 저희에게 문의하세요.

로드 밸런서 구성#

테스트 환경에서는 다음을 사용합니다:

  • Linux 패키지 환경을 위한 HAProxy

  • Cloud Native Hybrid를 위한 Gateway API 또는 Ingress 구현이 포함된 클라우드 제공업체 동등 솔루션

컴포넌트 설정#

GitLab 및 해당 컴포넌트를 최대 500 RPS 또는 25,000 사용자를 수용하도록 설정하려면:

서버들은 동일한 10.6.0.0/24 사설 네트워크 대역에서 시작되며, 해당 주소로 서로 자유롭게 연결할 수 있습니다.

다음 목록은 각 서버에 대한 설명과 할당된 IP를 포함합니다:

  • 10.6.0.10: External Load Balancer

  • 10.6.0.11: Consul 1

  • 10.6.0.12: Consul 2

  • 10.6.0.13: Consul 3

  • 10.6.0.21: PostgreSQL primary

  • 10.6.0.22: PostgreSQL secondary 1

  • 10.6.0.23: PostgreSQL secondary 2

  • 10.6.0.31: PgBouncer 1

  • 10.6.0.32: PgBouncer 2

  • 10.6.0.33: PgBouncer 3

  • 10.6.0.40: Internal Load Balancer

  • 10.6.0.51: Redis - Cache Primary

  • 10.6.0.52: Redis - Cache Replica 1

  • 10.6.0.53: Redis - Cache Replica 2

  • 10.6.0.61: Redis - Persistent Primary

  • 10.6.0.62: Redis - Persistent Replica 1

  • 10.6.0.63: Redis - Persistent Replica 2

  • 10.6.0.91: Gitaly 1

  • 10.6.0.92: Gitaly 2

  • 10.6.0.93: Gitaly 3

  • 10.6.0.131: Praefect 1

  • 10.6.0.132: Praefect 2

  • 10.6.0.133: Praefect 3

  • 10.6.0.141: Praefect PostgreSQL 1 (non HA)

  • 10.6.0.101: Sidekiq 1

  • 10.6.0.102: Sidekiq 2

  • 10.6.0.103: Sidekiq 3

  • 10.6.0.104: Sidekiq 4

  • 10.6.0.111: GitLab application 1

  • 10.6.0.112: GitLab application 2

  • 10.6.0.113: GitLab application 3

  • 10.6.0.114: GitLab application 4

  • 10.6.0.115: GitLab application 5

  • 10.6.0.151: Prometheus

외부 로드 밸런서 구성#

다중 노드 GitLab 구성에서는 애플리케이션 서버로 트래픽을 라우팅하기 위한 외부 로드 밸런서가 필요합니다.

어떤 로드 밸런서를 사용할지, 또는 정확한 구성 방법은 GitLab 문서의 범위를 벗어나지만, 일반적인 요구 사항에 대한 자세한 내용은 로드 밸런서를 참고하세요. 이 섹션에서는 선택한 로드 밸런서에 대해 구성해야 하는 세부 사항에 집중합니다.

준비 상태 확인#

외부 로드 밸런서가 내장 모니터링 엔드포인트를 통해 정상 작동하는 서비스로만 트래픽을 라우팅하도록 설정하세요. 준비 상태 확인은 확인 대상 노드에 추가 구성이 필요하며, 그렇지 않으면 외부 로드 밸런서가 연결할 수 없습니다.

포트#

기본으로 사용하는 포트는 아래 테이블에 나와 있습니다.

LB Port Backend Port Protocol
80 80 HTTP (1)
443 443 TCP or HTTPS (1) (2)
22 22 TCP
  • (1): 웹 터미널 지원을 위해 로드 밸런서가 WebSocket 연결을 올바르게 처리해야 합니다. HTTP 또는 HTTPS 프록싱을 사용할 경우, 로드 밸런서는 ConnectionUpgrade hop-by-hop 헤더를 통과시키도록 구성해야 합니다. 자세한 내용은 웹 터미널 통합 가이드를 참고하세요.

  • (2): 포트 443에 HTTPS 프로토콜을 사용할 경우, 로드 밸런서에 SSL 인증서를 추가해야 합니다. SSL을 GitLab 애플리케이션 서버에서 종료하려면 TCP 프로토콜을 사용하세요.

커스텀 도메인 지원과 함께 GitLab Pages를 사용하는 경우 추가적인 포트 구성이 필요합니다. GitLab Pages는 별도의 가상 IP 주소가 필요합니다. /etc/gitlab/gitlab.rbpages_external_url이 새 가상 IP 주소를 가리키도록 DNS를 구성하세요. 다음을 참고하세요.

자세한 내용은 GitLab Pages 문서를 참조하세요.

LB 포트 백엔드 포트 프로토콜
80 상황에 따라 다름 (1) HTTP
443 상황에 따라 다름 (1) TCP (2)
  • (1): GitLab Pages의 백엔드 포트는 gitlab_pages['external_http']gitlab_pages['external_https'] 설정에 따라 달라집니다. 자세한 내용은 GitLab Pages 문서를 참조하세요.

  • (2): GitLab Pages의 443 포트는 항상 TCP 프로토콜을 사용해야 합니다. 사용자가 커스텀 SSL로 커스텀 도메인을 구성할 수 있는데, 로드 밸런서에서 SSL이 종료되면 이것이 불가능해집니다.

대체 SSH 포트#

일부 조직에서는 SSH 포트 22를 개방하는 것을 금지하는 정책을 운영합니다. 이 경우, 사용자가 443 포트로 SSH를 사용할 수 있도록 대체 SSH 호스트명을 구성하는 것이 도움이 될 수 있습니다. 대체 SSH 호스트명을 사용하려면 앞서 설명한 GitLab HTTP 구성과 비교하여 새로운 가상 IP 주소가 필요합니다.

대체 SSH 호스트명(예: altssh.gitlab.example.com)에 대한 DNS를 구성합니다.

LB 포트 백엔드 포트 프로토콜
443 22 TCP

SSL#

다음으로 결정해야 할 사항은 환경에서 SSL을 어떻게 처리할지입니다. 몇 가지 옵션이 있습니다:

애플리케이션 노드에서 SSL 종료#

로드 밸런서가 443 포트의 연결을 HTTP(S) 프로토콜 대신 TCP로 통과시키도록 구성합니다. 이렇게 하면 연결이 애플리케이션 노드의 NGINX 서비스로 변형 없이 전달됩니다. NGINX가 SSL 인증서를 보유하고 443 포트에서 수신 대기합니다.

SSL 인증서 관리 및 NGINX 구성에 대한 자세한 내용은 HTTPS 문서를 참조하세요.

로드 밸런서에서 백엔드 SSL 없이 SSL 종료#

로드 밸런서가 TCP 대신 HTTP(S) 프로토콜을 사용하도록 구성합니다. 그러면 로드 밸런서가 SSL 인증서 관리 및 SSL 종료를 담당합니다.

로드 밸런서와 GitLab 간의 통신이 보안이 적용되지 않으므로 추가 구성이 필요합니다. 자세한 내용은 프록시된 SSL 문서를 참조하세요.

로드 밸런서에서 백엔드 SSL과 함께 SSL 종료#

로드 밸런서가 'TCP' 대신 'HTTP(S)' 프로토콜을 사용하도록 구성합니다. 로드 밸런서가 최종 사용자에게 표시되는 SSL 인증서 관리를 담당합니다.

이 시나리오에서는 로드 밸런서와 NGINX 간의 트래픽도 보안이 적용됩니다. 연결이 전 구간에서 보안이 적용되므로 프록시된 SSL에 대한 구성을 추가할 필요가 없습니다. 단, SSL 인증서를 구성하기 위해 GitLab에 구성을 추가해야 합니다. SSL 인증서 관리 및 NGINX 구성에 대한 자세한 내용은 HTTPS 문서를 참조하세요.

구성 요소 설정으로 돌아가기

내부 로드 밸런서 구성#

내부 로드 밸런서는 GitLab 환경에서 필요한 내부 연결(예: PgBouncerGitaly Cluster(Praefect)에 대한 연결)의 부하를 분산하는 데 사용됩니다.

외부 로드 밸런서와는 별개의 노드이며, 외부에서 접근할 수 없어야 합니다.

다음 IP를 예시로 사용합니다:

  • 10.6.0.40: 내부 로드 밸런서

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 10.6.0.31:6432 check
    server pgbouncer2 10.6.0.32:6432 check
    server pgbouncer3 10.6.0.33:6432 check

# Praefect load balancing (skip both sections below if using DNS service discovery for Praefect)
# For more information, see https://docs.gitlab.com/administration/gitaly/praefect/configure/#service-discovery
frontend internal-praefect-tcp-in
    bind *:2305
    mode tcp
    option tcplog
    option clitcpka

    default_backend praefect

backend praefect
    mode tcp
    option tcp-check
    option srvtcpka

    server praefect1 10.6.0.131:2305 check
    server praefect2 10.6.0.132:2305 check
    server praefect3 10.6.0.133:2305 check

자세한 안내는 사용 중인 로드 밸런서의 문서를 참조하세요.

구성 요소 설정으로 돌아가기

구성 요소 설정으로 돌아가기

Consul 구성#

다음으로, Consul 서버를 설정합니다.

Consul은 반드시 3개 이상의 홀수 노드로 배포해야 합니다. 이는 노드가 쿼럼의 일부로 투표를 수행할 수 있도록 하기 위함입니다.

다음 IP는 예시로 사용됩니다:

  • 10.6.0.11: Consul 1

  • 10.6.0.12: Consul 2

  • 10.6.0.13: Consul 3

Consul을 구성하려면:

Consul을 호스팅할 서버에 SSH로 접속합니다.

원하는 Linux 패키지를 다운로드하여 설치합니다. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제에 맞는 GitLab을 설치해야 합니다. 현재 설치된 것과 동일한 버전과 유형(Community 또는 Enterprise Edition)을 선택하세요.

/etc/gitlab/gitlab.rb를 편집하여 다음 내용을 추가합니다:

roles(['consul_role'])

## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   server: true,
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체합니다. 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

변경 사항을 적용하려면 GitLab을 재구성합니다.

다른 모든 Consul 노드에 대해 위 단계를 반복하며, 올바른 IP를 설정했는지 확인합니다.

세 번째 Consul 서버 프로비저닝이 완료되면 Consul 리더가 선출됩니다. Consul 로그 sudo gitlab-ctl tail consul을 확인하면 ...[INFO] consul: New leader elected: ...가 표시됩니다.

현재 Consul 멤버(서버, 클라이언트)를 나열할 수 있습니다:

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

GitLab 서비스가 실행 중인지 확인할 수 있습니다:

sudo gitlab-ctl status

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

run: consul: (pid 30074) 76834s; run: log: (pid 29740) 76844s
run: logrotate: (pid 30925) 3041s; run: log: (pid 29649) 76861s
run: node-exporter: (pid 30093) 76833s; run: log: (pid 29663) 76855s

구성 요소 설정으로 돌아가기

PostgreSQL 구성#

이 섹션에서는 GitLab과 함께 사용할 고가용성 PostgreSQL 클러스터 구성 방법을 안내합니다.

직접 PostgreSQL 인스턴스 제공#

Linux 패키지에 번들된 PostgreSQL, PgBouncer, Consul 서비스 디스커버리 구성 요소 대신, PostgreSQL용 타사 외부 서비스를 사용할 수 있습니다.

지원되는 PostgreSQL 버전을 실행하는 신뢰할 수 있는 공급자를 사용하세요. 다음 서비스가 잘 작동하는 것으로 알려져 있습니다:

고가용성 및 데이터베이스 로드 밸런싱에 대한 지침을 포함한 자세한 내용은 다음을 참조하세요:

서드 파티 외부 서비스를 사용하는 경우:

Linux 패키지를 사용한 독립형 PostgreSQL#

복제(replication) 및 장애 조치(failover)를 갖춘 PostgreSQL 클러스터에 권장되는 Linux 패키지 구성에는 다음이 필요합니다:

최소 세 개의 PostgreSQL 노드.

최소 세 개의 Consul 서버 노드.

기본 데이터베이스 읽기 및 쓰기를 추적하고 처리하는 최소 세 개의 PgBouncer 노드.

PgBouncer 노드 간 요청을 분산하는 내부 로드 밸런서(TCP).

데이터베이스 로드 밸런싱 활성화.

각 PostgreSQL 노드에 구성할 로컬 PgBouncer 서비스. 이는 기본(primary)을 추적하는 메인 PgBouncer 클러스터와는 별도입니다.

다음 IP는 예시로 사용됩니다:

  • 10.6.0.21: PostgreSQL primary

  • 10.6.0.22: PostgreSQL secondary 1

  • 10.6.0.23: PostgreSQL secondary 2

먼저 각 노드에 Linux 패키지를 설치해야 합니다. GitLab 패키지 리포지터리를 추가하고 선택한 운영 체제에 맞는 GitLab을 설치하되, EXTERNAL_URL 값은 지정하지 않습니다.

PostgreSQL 노드#

PostgreSQL 노드 중 하나에 SSH로 접속합니다.

PostgreSQL 사용자 이름/비밀번호 쌍의 비밀번호 해시를 생성합니다. 기본 사용자 이름인 gitlab을 사용한다고 가정합니다(권장). 명령 실행 시 비밀번호와 확인을 입력하라는 메시지가 표시됩니다. 이 명령의 출력 값을 다음 단계에서 <postgresql_password_hash> 값으로 사용합니다:

sudo gitlab-ctl pg-password-md5 gitlab

PgBouncer 사용자 이름/비밀번호 쌍의 비밀번호 해시를 생성합니다. 기본 사용자 이름인 pgbouncer를 사용한다고 가정합니다(권장). 명령 실행 시 비밀번호와 확인을 입력하라는 메시지가 표시됩니다. 이 명령의 출력 값을 다음 단계에서 <pgbouncer_password_hash> 값으로 사용합니다:

sudo gitlab-ctl pg-password-md5 pgbouncer

PostgreSQL 복제 사용자 이름/비밀번호 쌍의 비밀번호 해시를 생성합니다. 기본 사용자 이름인 gitlab_replicator를 사용한다고 가정합니다(권장). 명령 실행 시 비밀번호와 확인을 입력하라는 메시지가 표시됩니다. 이 명령의 출력 값을 다음 단계에서 <postgresql_replication_password_hash> 값으로 사용합니다:

sudo gitlab-ctl pg-password-md5 gitlab_replicator

Consul 데이터베이스 사용자 이름/비밀번호 쌍의 비밀번호 해시를 생성합니다. 기본 사용자 이름인 gitlab-consul을 사용한다고 가정합니다(권장). 명령 실행 시 비밀번호와 확인을 입력하라는 메시지가 표시됩니다. 이 명령의 출력 값을 다음 단계에서 <consul_password_hash> 값으로 사용합니다:

sudo gitlab-ctl pg-password-md5 gitlab-consul

모든 데이터베이스 노드에서 /etc/gitlab/gitlab.rb를 편집하여 # START user configuration 섹션에 표시된 값을 교체합니다:

# Disable all components except Patroni, PgBouncer and Consul
roles(['patroni_role', 'pgbouncer_role'])

# PostgreSQL configuration
postgresql['listen_address'] = '0.0.0.0'

# Sets `max_replication_slots` to double the number of database nodes.
# Patroni uses one extra slot per node when initiating the replication.
patroni['postgresql']['max_replication_slots'] = 6

# Set `max_wal_senders` to one more than the number of replication slots in the cluster.
# This is used to prevent replication from using up all of the
# available database connections.
patroni['postgresql']['max_wal_senders'] = 7

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

# Configure the Consul agent
consul['services'] = %w(postgresql)
## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

# START user configuration
# Please set the real values as explained in Required Information section
#
# Replace PGBOUNCER_PASSWORD_HASH with a generated md5 value
postgresql['pgbouncer_user_password'] = '<pgbouncer_password_hash>'
# Replace POSTGRESQL_REPLICATION_PASSWORD_HASH with a generated md5 value
postgresql['sql_replication_password'] = '<postgresql_replication_password_hash>'
# Replace POSTGRESQL_PASSWORD_HASH with a generated md5 value
postgresql['sql_user_password'] = '<postgresql_password_hash>'

# Set up basic authentication for the Patroni API (use the same username/password in all nodes).
patroni['username'] = '<patroni_api_username>'
patroni['password'] = '<patroni_api_password>'

# Replace 10.6.0.0/24 with Network Address
postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/24 127.0.0.1/32)

# Local PgBouncer service for Database Load Balancing
pgbouncer['databases'] = {
   gitlabhq_production: {
      host: "127.0.0.1",
      user: "pgbouncer",
      password: '<pgbouncer_password_hash>'
   }
}

# Set the network addresses that the exporters will listen on for monitoring
node_exporter['listen_address'] = '0.0.0.0:9100'
postgres_exporter['listen_address'] = '0.0.0.0:9187'

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}
#
# END user configuration

Patroni가 장애 조치를 관리하는 PostgreSQL은 기본적으로 pg_rewind를 사용하여 충돌을 처리합니다. 대부분의 장애 조치 처리 방법과 마찬가지로, 이 방법은 데이터 손실로 이어질 가능성이 낮지만 존재합니다. 자세한 내용은 다양한 Patroni 복제 방법을 참조하세요.

  • 처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하고, 이 서버에서 동일한 이름의 파일을 추가하거나 교체합니다. 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

  • 변경 사항을 적용하려면 GitLab을 재구성합니다.

고급 구성 옵션을 지원하며 필요한 경우 추가할 수 있습니다.

구성 요소 설정으로 돌아가기

PostgreSQL 사후 구성#

기본 사이트의 Patroni 노드 중 하나에 SSH로 접속합니다:

리더 및 클러스터 상태를 확인합니다:

gitlab-ctl patroni members

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

| Cluster       | Member                            |  Host     | Role   | State   | TL  | Lag in MB | Pending restart |
|---------------|-----------------------------------|-----------|--------|---------|-----|-----------|-----------------|
| postgresql-ha |      | 10.6.0.21 | Leader | running | 175 |           | *               |
| postgresql-ha |  | 10.6.0.22 |        | running | 175 | 0         | *               |
| postgresql-ha |  | 10.6.0.23 |        | running | 175 | 0         | *               |

노드의 ‘State’ 칼럼이 “running”으로 표시되지 않는 경우, 계속 진행하기 전에 PostgreSQL 복제 및 장애 조치 트러블슈팅 섹션을 확인하세요.

구성 요소 설정으로 돌아가기

PgBouncer 구성#

이제 PostgreSQL 서버가 모두 설정되었으므로, 기본 데이터베이스에 대한 읽기/쓰기를 추적하고 처리하기 위해 PgBouncer를 구성해 보겠습니다.

PgBouncer는 단일 스레드이므로 CPU 코어 수를 늘려도 성능이 크게 향상되지 않습니다.

자세한 내용은 스케일링 문서를 참조하세요.

예시로 다음 IP를 사용합니다:

  • 10.6.0.31: PgBouncer 1

  • 10.6.0.32: PgBouncer 2

  • 10.6.0.33: PgBouncer 3

각 PgBouncer 노드에서 /etc/gitlab/gitlab.rb를 편집하고, <consul_password_hash><pgbouncer_password_hash>이전에 설정한 비밀번호 해시로 교체합니다:

# Disable all components except Pgbouncer and Consul agent
roles(['pgbouncer_role'])

# Configure PgBouncer
pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
pgbouncer['users'] = {
   'gitlab-consul': {
      password: '<consul_password_hash>'
   },
   'pgbouncer': {
      password: '<pgbouncer_password_hash>'
   }
}

# Configure Consul agent
consul['watchers'] = %w(postgresql)
consul['configuration'] = {
retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
}

# Enable service discovery for Prometheus
consul['monitoring_service_discovery'] = true

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하고, 이 서버에서 동일한 이름의 파일을 추가하거나 교체합니다. 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

변경 사항을 적용하려면 GitLab을 재구성합니다.

execute[generate databases.ini] 오류가 발생하면, 이는 기존의 알려진 이슈로 인한 것입니다. 다음 단계 이후 두 번째 reconfigure를 실행하면 해결됩니다.

Consul이 PgBouncer를 다시 로드할 수 있도록 .pgpass 파일을 만듭니다. 요청 시 PgBouncer 비밀번호를 두 번 입력합니다:

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

이전 단계에서 발생할 수 있는 오류를 해결하기 위해 GitLab을 다시 재구성합니다.

각 노드가 현재 Primary와 통신하고 있는지 확인합니다:

gitlab-ctl pgb-console # You will be prompted for PGBOUNCER_PASSWORD

콘솔 프롬프트가 나타나면 다음 쿼리를 실행합니다:

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)

구성 요소 설정으로 돌아가기

Redis 구성#

확장 가능한 환경에서 Redis를 사용하는 경우, 장애 조치 절차를 감시하고 자동으로 시작하는 Redis Sentinel 서비스와 함께 Primary x Replica 토폴로지를 사용할 수 있습니다.

  • Redis 클러스터는 각각 3개 이상의 홀수 노드로 배포해야 합니다. 이는 Redis Sentinel이 쿼럼의 일부로 투표를 진행할 수 있도록 하기 위함입니다. 이 규칙은 클라우드 제공업체 서비스와 같이 Redis를 외부에서 구성하는 경우에는 적용되지 않습니다.

  • Redis는 기본적으로 단일 스레드이며 CPU 코어 수를 늘려도 성능이 크게 향상되지 않습니다. 이 규모의 아키텍처에서는 최적의 성능을 달성하기 위해 명시된 대로 별도의 캐시(Cache) 및 영구(Persistent) 인스턴스를 사용하는 것을 강력히 권장합니다. 자세한 내용은 스케일링 문서를 참조하세요.

    Redis는 Sentinel과 함께 사용할 경우 인증이 필요합니다. 자세한 내용은 Redis 보안 문서를 참조하세요. Redis 비밀번호와 엄격한 방화벽 규칙을 조합하여 Redis 서비스를 보호하는 것을 권장합니다. 토폴로지와 아키텍처를 완전히 이해하기 위해 GitLab에서 Redis를 구성하기 전에 Redis Sentinel 문서를 읽어 보실 것을 강력히 권장합니다.

Redis 설정의 요구 사항은 다음과 같습니다:

  • 모든 Redis 노드는 서로 통신할 수 있어야 하며, Redis(6379) 및 Sentinel(26379) 포트에서 수신 연결을 허용해야 합니다(기본값을 변경하지 않는 경우).

  • GitLab 애플리케이션을 호스팅하는 서버는 Redis 노드에 접근할 수 있어야 합니다.

  • 방화벽을 사용하여 외부 네트워크(인터넷)에서 노드에 접근하지 못하도록 보호합니다.

이 섹션에서는 GitLab과 함께 사용할 두 개의 외부 Redis 클러스터를 구성하는 방법을 안내합니다. 다음 IP가 예시로 사용됩니다:

  • 10.6.0.51: Redis - 캐시 Primary

  • 10.6.0.52: Redis - 캐시 Replica 1

  • 10.6.0.53: Redis - 캐시 Replica 2

  • 10.6.0.61: Redis - 영구 Primary

  • 10.6.0.62: Redis - 영구 Replica 1

  • 10.6.0.63: Redis - 영구 Replica 2

자체 Redis 인스턴스 제공#

다음 지침을 참고하여 Redis 캐시 및 영구 인스턴스에 타사 외부 서비스를 선택적으로 사용할 수 있습니다:

  • 신뢰할 수 있는 제공업체 또는 솔루션을 사용해야 합니다. Google MemorystoreAWS ElastiCache는 정상 작동하는 것으로 알려져 있습니다.

  • Redis 클러스터 모드는 특별히 지원되지 않으며, HA가 있는 Redis Standalone은 지원됩니다.

  • 설정에 따라 Redis 제거 정책을 설정해야 합니다.

자세한 내용은 인프라 및 서비스를 참조하세요.

Redis 캐시 클러스터 구성#

이 섹션에서는 새 Redis 캐시 인스턴스를 설치하고 설정합니다.

Primary와 Replica Redis 노드 모두 redis['password']에 동일한 비밀번호가 정의되어 있어야 합니다. 장애 조치 중 언제든지 Sentinel은 노드를 재구성하고 해당 노드의 상태를 Primary에서 Replica로(또는 그 반대로) 변경할 수 있습니다.

Primary Redis 캐시 노드 구성#

Primary Redis 서버에 SSH로 접속합니다.

원하는 Linux 패키지를 다운로드하고 설치합니다. GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 합니다.

선택한 운영 체제용 패키지를 설치합니다. 현재 설치 버전과 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택하세요.

/etc/gitlab/gitlab.rb 파일을 편집하고 다음 내용을 추가합니다:

# Specify server role as 'redis_sentinel_role' 'redis_master_role'
roles ['redis_sentinel_role', 'redis_master_role', 'consul_role']

# Set IP bind address and Quorum number for Redis Sentinel service
sentinel['bind'] = '0.0.0.0'
sentinel['quorum'] = 2

# IP address pointing to a local IP that the other machines can reach.
# You can also set bind to '0.0.0.0' which listen in all interfaces.
# If you really must bind to an external accessible IP, make
# sure you add extra firewall rules to prevent unauthorized access.
redis['bind'] = '10.6.0.51'

# Define a port so Redis can listen for TCP requests which will allow other
# machines to connect to it.
redis['port'] = 6379

# Port of primary Redis server for Sentinel, uncomment to change to non default.
# Defaults to `6379`.
# redis['master_port'] = 6379

# Set up password authentication for Redis (use the same password in all nodes).
redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_FIRST_CLUSTER'

# Must be the same in every Redis node.
redis['master_name'] = 'gitlab-redis-cache'

# The IP of this primary Redis node.
redis['master_ip'] = '10.6.0.51'

# Set the Redis Cache instance as an LRU
# 90% of available RAM in MB
redis['maxmemory'] = '13500mb'
redis['maxmemory_policy'] = "allkeys-lru"
redis['maxmemory_samples'] = 5

## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'
redis_exporter['listen_address'] = '0.0.0.0:9121'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체합니다. 이 노드가 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

변경 사항을 적용하려면 GitLab을 재구성하세요.

복제본 Redis 캐시 노드 구성#

복제본 Redis 서버에 SSH로 접속합니다.

원하는 Linux 패키지를 다운로드하고 설치합니다. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제용 GitLab을 설치해야 합니다. 현재 설치 버전과 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택하세요.

/etc/gitlab/gitlab.rb 파일을 편집하고 이전 섹션의 기본 노드와 동일한 내용을 추가하되, redis_master_noderedis_replica_node로 대체합니다:

# Specify server role as 'redis_replica_role' and enable Consul agent
roles ['redis_sentinel_role', 'redis_replica_role', 'consul_role']

# Set IP bind address and Quorum number for Redis Sentinel service
sentinel['bind'] = `0.0.0.0`
sentinel['quorum'] = 2

# IP address pointing to a local IP that the other machines can reach.
# Set bind to '0.0.0.0' to listen on all interfaces.
# If you really must bind to an external accessible IP, make
# sure you add extra firewall rules to prevent unauthorized access.
redis['bind'] = '10.6.0.52'

# Define a port so Redis can listen for TCP requests which will allow other
# machines to connect to it.
redis['port'] = 6379

## Port of primary Redis server for Sentinel, uncomment to change to non default. Defaults
## to `6379`.
#redis['master_port'] = 6379

# Set up password authentication for Redis and replicas (use the same password in all nodes).
redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_FIRST_CLUSTER'

# Must be the same in every Redis node
redis['master_name'] = 'gitlab-redis-cache'

# The IP of the primary Redis node.
redis['master_ip'] = '10.6.0.51'

# Set the Redis Cache instance as an LRU
# 90% of available RAM in MB
redis['maxmemory'] = '13500mb'
redis['maxmemory_policy'] = "allkeys-lru"
redis['maxmemory_samples'] = 5

## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'
redis_exporter['listen_address'] = '0.0.0.0:9121'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하세요. 이 서버가 처음 구성하는 Linux 패키지 노드인 경우 이 단계를 건너뛸 수 있습니다.

변경 사항이 적용되도록 GitLab을 재구성하세요.

나머지 모든 복제본 노드에 대해 동일한 단계를 반복하고, IP가 올바르게 설정되어 있는지 확인하세요.

고급 구성 옵션이 지원되며 필요에 따라 추가할 수 있습니다.

구성 요소 설정으로 돌아가기

Redis Persistent 클러스터 구성#

이 섹션에서는 새로운 Redis Persistent 인스턴스를 설치하고 설정합니다.

기본 Redis 노드와 복제본 Redis 노드 모두 redis['password']에 동일한 비밀번호를 정의해야 합니다. 페일오버가 발생하면 언제든지 Sentinel이 노드를 재구성하여 기본(primary)에서 복제본(replica)으로 상태를 변경할 수 있습니다(반대의 경우도 마찬가지).

기본 Redis Persistent 노드 구성#

기본(Primary) Redis 서버에 SSH로 접속하세요.

원하는 Linux 패키지를 다운로드하여 설치하세요. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제에 GitLab을 설치하세요. 현재 설치와 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택하세요.

/etc/gitlab/gitlab.rb를 편집하고 다음 내용을 추가하세요:

# Specify server roles as 'redis_sentinel_role' and 'redis_master_role'
roles ['redis_sentinel_role', 'redis_master_role', 'consul_role']

# Set IP bind address and Quorum number for Redis Sentinel service
sentinel['bind'] = '0.0.0.0'
sentinel['quorum'] = 2

# IP address pointing to a local IP that the other machines can reach to.
# You can also set bind to '0.0.0.0' which listen in all interfaces.
# If you really must bind to an external accessible IP, make
# sure you add extra firewall rules to prevent unauthorized access.
redis['bind'] = '10.6.0.61'

# Define a port so Redis can listen for TCP requests which will allow other
# machines to connect to it.
redis['port'] = 6379

## Port of primary Redis server for Sentinel, uncomment to change to non default. Defaults
## to `6379`.
#redis['master_port'] = 6379

# Set up password authentication for Redis and replicas (use the same password in all nodes).
redis['password'] = 'REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER'
redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER'

## Must be the same in every Redis node
redis['master_name'] = 'gitlab-redis-persistent'

## The IP of this primary Redis node.
redis['master_ip'] = '10.6.0.61'

## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'
redis_exporter['listen_address'] = '0.0.0.0:9121'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하세요. 이 서버가 처음 구성하는 Linux 패키지 노드인 경우 이 단계를 건너뛸 수 있습니다.

변경 사항이 적용되도록 GitLab을 재구성하세요.

복제본 Redis Persistent 노드 구성#

복제본(replica) Redis Persistent 서버에 SSH로 접속하세요.

원하는 Linux 패키지를 다운로드하여 설치하세요. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제에 GitLab을 설치하세요. 현재 설치와 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택하세요.

/etc/gitlab/gitlab.rb를 편집하고 다음 내용을 추가하세요:

# Specify server role as 'redis_replica_role' and enable Consul agent
roles ['redis_sentinel_role', 'redis_replica_role', 'consul_role']

# Set IP bind address and Quorum number for Redis Sentinel service
sentinel['bind'] = '0.0.0.0'
sentinel['quorum'] = 2

# IP address pointing to a local IP that the other machines can reach to.
# You can also set bind to '0.0.0.0' which listen in all interfaces.
# If you really must bind to an external accessible IP, make
# sure you add extra firewall rules to prevent unauthorized access.
redis['bind'] = '10.6.0.62'

# Define a port so Redis can listen for TCP requests which will allow other
# machines to connect to it.
redis['port'] = 6379

## Port of primary Redis server for Sentinel, uncomment to change to non default. Defaults
## to `6379`.
#redis['master_port'] = 6379

# The same password for Redis authentication you set up for the primary node.
redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER'

## Must be the same in every Redis node
redis['master_name'] = 'gitlab-redis-persistent'

# The IP of the primary Redis node.
redis['master_ip'] = '10.6.0.61'

## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'
redis_exporter['listen_address'] = '0.0.0.0:9121'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하십시오. 이 서버가 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

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

다른 모든 복제본 노드에 대해 단계를 반복하고, IP가 올바르게 설정되어 있는지 확인하십시오.

고급 구성 옵션이 지원되며 필요에 따라 추가할 수 있습니다.

구성 요소 설정으로 돌아가기

Gitaly Cluster (Praefect) 구성#

Gitaly Cluster (Praefect)는 GitLab이 제공하고 권장하는 Git 리포지터리 저장을 위한 내결함성 솔루션입니다. 이 구성에서 모든 Git 리포지터리는 클러스터의 모든 Gitaly 노드에 저장되며, 그 중 하나가 기본(primary)으로 지정되고, 기본 노드가 다운되면 자동으로 장애 조치(failover)가 수행됩니다.

Gitaly 사양은 정상 상태의 사용 패턴과 리포지터리 크기의 높은 백분위수를 기반으로 합니다.

그러나 대형 모노리포(수 기가바이트 이상) 또는 추가 워크로드가 있는 경우, 이는 환경의 성능에 상당한 영향을 미칠 수 있으며 추가 조정이 필요할 수 있습니다. 해당 사항이 있다고 판단되면 필요에 따라 추가 지침을 위해 문의하십시오.

Gitaly Cluster (Praefect)는 내결함성의 이점을 제공하지만, 설정과 관리의 복잡성이 추가됩니다. Gitaly Cluster (Praefect) 배포 전 기술적 제한 사항 및 고려 사항을 검토하십시오.

다음에 대한 지침은 아래를 참고하십시오:

권장 클러스터 설정에는 다음 구성 요소가 포함됩니다:

  • Gitaly 노드 3개: Git 리포지터리의 복제 스토리지.

  • Praefect 노드 3개: Gitaly Cluster (Praefect)의 라우터 및 트랜잭션 관리자.

  • Praefect PostgreSQL 노드 1개: Praefect용 데이터베이스 서버. Praefect 데이터베이스 연결의 고가용성을 위해 서드파티 솔루션이 필요합니다.

  • 로드 밸런싱: Praefect 노드에 대한 트래픽의 균등 분산. 대부분의 설정에 권장되는 TCP 로드 밸런서 또는 고급 구성을 위한 서비스 디스커버리 DNS를 사용할 수 있습니다. 자세한 내용은 Praefect의 로드 밸런싱을 참조하십시오.

이 섹션에서는 권장 표준 설정을 순서대로 구성하는 방법을 설명합니다. 더 고급 설정은 독립형 Gitaly Cluster (Praefect) 문서를 참조하십시오.

Praefect의 로드 밸런싱#

TCP 로드 밸런서 또는 서비스 디스커버리 DNS를 사용하여 Praefect 노드에 트래픽을 분산할 수 있습니다. TCP 로드 밸런서는 모든 배포 시나리오에서 작동하므로 대부분의 설정에 권장됩니다.

TCP 로드 밸런서#

기존 TCP 로드 밸런서(예: HAProxy 또는 AWS ELB)는 Praefect 노드에 트래픽을 분산합니다. 이 방식은:

  • 모든 배포 시나리오(Omnibus, Cloud Native Hybrid)에서 작동합니다

  • 간단한 설정 및 운영 관리를 제공합니다

  • TLS 및 비TLS 구성을 모두 지원합니다

  • 연결이 특정 노드에 몰릴 수 있어 불균등한 트래픽 분산이 발생할 수 있습니다

  • 노드 재시작 후 트래픽 재분산에 시간이 더 걸릴 수 있습니다

구성 지침은 로드 밸런서를 참조하십시오.

서비스 디스커버리 DNS#

서비스 디스커버리는 DNS를 사용하여 Praefect 노드 주소를 검색하며, 클라이언트가 사용 가능한 모든 노드에 걸쳐 요청을 균등하게 분산할 수 있도록 합니다. 이 방식은:

  • 모든 Praefect 노드에 트래픽을 균등하게 분산합니다

  • 노드가 추가되거나 재시작될 때 트래픽을 자동으로 재분산합니다

  • DNS 인프라(예: Consul, CoreDNS 또는 유사한 도구)가 필요합니다

  • TLS 사용 시 GitLab 18.9 이상이 필요합니다

  • Linux 패키지(Omnibus) 설치에서만 사용 가능합니다

구성 지침은 서비스 디스커버리를 참조하십시오.

Praefect PostgreSQL 구성#

Gitaly Cluster (Praefect)의 라우팅 및 트랜잭션 관리자인 Praefect는 Gitaly Cluster (Praefect) 상태 데이터를 저장하기 위한 자체 데이터베이스 서버가 필요합니다.

고가용성 설정을 원하는 경우, Praefect는 서드파티 PostgreSQL 데이터베이스가 필요합니다. 내장 솔루션은 현재 개발 중입니다.

Linux 패키지를 사용한 Praefect 비-HA PostgreSQL 독립형#

다음 IP는 예시로 사용됩니다:

  • 10.6.0.141: Praefect PostgreSQL

먼저 Praefect PostgreSQL 노드에 Linux 패키지를 설치하십시오. 선택한 운영 체제에 맞는 GitLab 패키지 리포지터리를 추가하고 GitLab을 설치하되, EXTERNAL_URL 값은 제공하지 마십시오.

Praefect PostgreSQL 노드에 SSH로 접속합니다.

Praefect PostgreSQL 사용자에 사용할 강력한 비밀번호를 생성합니다. 이 비밀번호를 <praefect_postgresql_password>로 기록해 두십시오.

Praefect PostgreSQL 사용자 이름/비밀번호 쌍의 비밀번호 해시를 생성합니다. 여기서는 기본 사용자 이름인 praefect를 사용한다고 가정합니다(권장). 이 명령은 비밀번호 <praefect_postgresql_password>와 확인을 요청합니다. 다음 단계에서 <praefect_postgresql_password_hash> 값으로 이 명령의 출력값을 사용하세요:

sudo gitlab-ctl pg-password-md5 praefect

/etc/gitlab/gitlab.rb를 편집하여 # START user configuration 섹션에 명시된 값을 교체합니다:

# Disable all components except PostgreSQL and Consul
roles(['postgres_role', 'consul_role'])

# PostgreSQL configuration
postgresql['listen_address'] = '0.0.0.0'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

# Configure the Consul agent
## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

# START user configuration
# Please set the real values as explained in Required Information section
#
# Replace PRAEFECT_POSTGRESQL_PASSWORD_HASH with a generated md5 value
postgresql['sql_user_password'] = "<praefect_postgresql_password_hash>"

# Replace XXX.XXX.XXX.XXX/YY with Network Address
postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/24 127.0.0.1/32)

# Set the network addresses that the exporters will listen on for monitoring
node_exporter['listen_address'] = '0.0.0.0:9100'
postgres_exporter['listen_address'] = '0.0.0.0:9187'

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}
#
# END user configuration

첫 번째로 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체합니다. 이 서버가 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛰어도 됩니다.

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

사후 구성을 따릅니다.

구성 요소 설정으로 돌아가기

Praefect HA PostgreSQL 서드파티 솔루션#

앞서 언급했듯이, 완전한 고가용성을 목표로 한다면 Praefect 데이터베이스에 서드파티 PostgreSQL 솔루션을 사용하는 것이 권장됩니다.

PostgreSQL HA를 위한 서드파티 솔루션은 다양합니다. 선택한 솔루션은 Praefect와 함께 작동하기 위해 다음 조건을 갖춰야 합니다:

  • 페일오버 시에도 변경되지 않는 모든 연결에 대한 정적 IP.

  • LISTEN SQL 기능이 지원되어야 합니다.

    서드파티 설정을 사용하면, 복제를 올바르게 처리하기 위해 별도의 데이터베이스 인스턴스가 필요한 Geo를 사용하는 경우가 아니라면, Praefect의 데이터베이스를 편의상 기본 GitLab 데이터베이스와 동일한 서버에 함께 배치할 수 있습니다. 이 설정에서는 영향이 최소화되므로 기본 데이터베이스 설정의 사양을 변경할 필요가 없습니다.

    이를 위해 신뢰할 수 있는 제공업체나 솔루션을 사용해야 합니다. Google Cloud SQLAmazon RDS는 작동이 확인되어 있습니다. 그러나 Amazon Aurora는 14.4.0부터 기본적으로 활성화된 로드 밸런싱과 호환되지 않습니다.

자세한 내용은 인프라 및 서비스를 참조하세요.

데이터베이스 설정이 완료되면 사후 구성을 따릅니다.

Praefect PostgreSQL 사후 구성#

Praefect PostgreSQL 서버 설정이 완료된 후, Praefect가 사용할 사용자와 데이터베이스를 구성해야 합니다.

사용자 이름은 praefect, 데이터베이스 이름은 praefect_production으로 지정하는 것을 권장하며, 이는 PostgreSQL에서 표준적인 방법으로 구성할 수 있습니다. 사용자의 비밀번호는 이전에 <praefect_postgresql_password>로 구성한 비밀번호와 동일합니다.

Linux 패키지 PostgreSQL 설정에서의 적용 방법은 다음과 같습니다:

Praefect PostgreSQL 노드에 SSH로 접속합니다.

관리자 권한으로 PostgreSQL 서버에 연결합니다. gitlab-psql 사용자는 Linux 패키지에서 기본으로 추가되므로 여기서 사용합니다. template1 데이터베이스는 모든 PostgreSQL 서버에 기본으로 생성되므로 사용합니다.

/opt/gitlab/embedded/bin/psql -U gitlab-psql -d template1 -h POSTGRESQL_SERVER_ADDRESS

<praefect_postgresql_password>를 교체하여 새 사용자 praefect를 생성합니다:

CREATE ROLE praefect WITH LOGIN CREATEDB PASSWORD '<praefect_postgresql_password>';

이번에는 praefect 사용자로 PostgreSQL 서버에 재접속합니다:

/opt/gitlab/embedded/bin/psql -U praefect -d template1 -h POSTGRESQL_SERVER_ADDRESS

새 데이터베이스 praefect_production을 생성합니다:

CREATE DATABASE praefect_production WITH ENCODING=UTF8;

컴포넌트 설정으로 돌아가기

Praefect 구성#

Praefect는 Gitaly Cluster(Praefect)의 라우터이자 트랜잭션 매니저로, Gitaly로의 모든 연결은 이를 통해 이루어집니다. 이 섹션에서는 Praefect 구성 방법을 설명합니다.

Praefect는 3개 이상의 홀수 노드로 배포해야 합니다. 이는 노드들이 쿼럼의 일부로 투표할 수 있도록 하기 위함입니다.

Praefect는 클러스터 전반의 통신을 보호하기 위해 여러 시크릿 토큰이 필요합니다:

  • <praefect_external_token>: Gitaly Cluster(Praefect)에 호스팅된 리포지터리에 사용되며, 이 토큰을 가진 Gitaly 클라이언트만 접근할 수 있습니다.

  • <praefect_internal_token>: Gitaly Cluster(Praefect) 내부의 복제 트래픽에 사용됩니다. praefect_external_token과 구분되는 이유는 Gitaly 클라이언트가 Gitaly Cluster(Praefect)의 내부 노드에 직접 접근할 수 없어야 하기 때문입니다. 직접 접근 시 데이터 손실이 발생할 수 있습니다.

  • <praefect_postgresql_password>: 이전 섹션에서 정의한 Praefect PostgreSQL 비밀번호도 이 설정의 일부로 필요합니다.

Gitaly Cluster(Praefect) 노드는 Praefect에서 virtual storage로 구성됩니다. 각 스토리지에는 클러스터를 구성하는 각 Gitaly 노드의 세부 정보가 포함됩니다. 각 스토리지에는 이름이 부여되며, 이 이름은 구성의 여러 영역에서 사용됩니다. 이 가이드에서 스토리지 이름은 default입니다. 또한 이 가이드는 신규 설치를 기준으로 작성되었으므로, 기존 환경을 Gitaly Cluster(Praefect)를 사용하도록 업그레이드하는 경우 다른 이름을 사용해야 할 수 있습니다. 자세한 내용은 Praefect 문서를 참조하세요.

다음 IP 주소를 예시로 사용합니다:

  • 10.6.0.131: Praefect 1

  • 10.6.0.132: Praefect 2

  • 10.6.0.133: Praefect 3

각 Praefect 노드를 구성하려면 다음 단계를 수행합니다:

Praefect 서버에 SSH로 접속합니다.

원하는 Linux 패키지를 다운로드하여 설치합니다. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제에 GitLab을 설치해야 합니다.

/etc/gitlab/gitlab.rb 파일을 편집하여 Praefect를 구성합니다:

[GitLab에서 기본 리포지터리 스토리지가 필요하므로](/19.2/administration/gitaly/configure_gitaly/#gitlab-requires-a-default-repository-storage) `virtual_storages`에서 `default` 항목을 제거할 수 없습니다.
  • All reference architecture pages -->
# Avoid running unnecessary services on the Praefect server
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 Configuration
praefect['enable'] = true

# Prevent database migrations from running on upgrade automatically
praefect['auto_migrate'] = false
gitlab_rails['auto_migrate'] = false

# Configure the Consul agent
consul['enable'] = true
## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] = true

# START user configuration
# Please set the real values as explained in Required Information section
#

praefect['configuration'] = {
   # ...
   listen_addr: '0.0.0.0:2305',
   auth: {
      # ...
      #
      # Praefect External Token
      # This is needed by clients outside the cluster (like GitLab Shell) to communicate with the Praefect cluster
      token: '<praefect_external_token>',
   },
   # Praefect Database Settings
   database: {
      # ...
      host: '10.6.0.141',
      port: 5432,
      dbname: 'praefect_production',
      user: 'praefect',
      password: '<praefect_postgresql_password>',
   },
   # Praefect Virtual Storage config
   # Name of storage hash must match storage name in gitlab_rails['repositories_storages'] on GitLab
   # server ('praefect') and in gitaly['configuration'][:storage] on Gitaly nodes ('gitaly-1')
   virtual_storage: [
      {
         # ...
         name: 'default',
         node: [
            {
               storage: 'gitaly-1',
               address: 'tcp://10.6.0.91:8075',
               token: '<praefect_internal_token>'
            },
            {
               storage: 'gitaly-2',
               address: 'tcp://10.6.0.92:8075',
               token: '<praefect_internal_token>'
            },
            {
               storage: 'gitaly-3',
               address: 'tcp://10.6.0.93:8075',
               token: '<praefect_internal_token>'
            },
         ],
      },
   ],
   # Set the network address Praefect will listen on for monitoring
   prometheus_listen_addr: '0.0.0.0:9652',
}

# Set the network address the node exporter will listen on for monitoring
node_exporter['listen_address'] = '0.0.0.0:9100'

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}
#
# END user configuration

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버에 동일한 이름의 파일을 추가하거나 교체하세요. 처음으로 Linux 패키지 노드를 구성하는 경우라면 이 단계를 건너뛸 수 있습니다.

Praefect는 메인 GitLab 애플리케이션과 마찬가지로 일부 데이터베이스 마이그레이션을 실행해야 합니다. 이를 위해 마이그레이션을 실행할 Praefect 노드 하나만 선택해야 하며, 이를 Deploy Node라고 합니다. 이 노드는 다음과 같이 다른 노드들보다 먼저 구성해야 합니다:

/etc/gitlab/gitlab.rb 파일에서 praefect['auto_migrate'] 설정 값을 false에서 true로 변경하세요.

데이터베이스 마이그레이션이 reconfigure 시에만 실행되고 업그레이드 시 자동으로 실행되지 않도록 하려면 다음을 실행하세요:

sudo touch /etc/gitlab/skip-auto-reconfigure
  • 변경 사항을 적용하고 Praefect 데이터베이스 마이그레이션을 실행하려면 GitLab을 reconfigure하세요.

다른 모든 Praefect 노드에서 변경 사항을 적용하려면 GitLab을 reconfigure하세요.

Gitaly 구성#

클러스터를 구성하는 Gitaly 서버 노드는 데이터와 부하에 따라 달라지는 요구 사항이 있습니다.

Gitaly 사양은 사용 패턴과 정상 상태의 리포지터리 크기의 상위 백분위수를 기반으로 합니다.

그러나 대규모 모노레포(수 기가바이트 이상) 또는 추가 워크로드가 있는 경우, 환경 성능에 큰 영향을 미칠 수 있으며 추가 조정이 필요할 수 있습니다. 해당하는 경우 필요한 추가 안내를 위해 저희에게 문의하세요.

Gitaly는 Gitaly 스토리지에 대한 특정 디스크 요구 사항이 있습니다.

Gitaly의 네트워크 트래픽은 기본적으로 암호화되지 않으므로 Gitaly 서버는 공용 인터넷에 노출되어서는 안 됩니다. Gitaly 서버에 대한 접근을 제한하기 위해 방화벽 사용을 강력히 권장합니다. 또 다른 옵션으로 TLS 사용이 있습니다.

Gitaly를 구성할 때 다음 사항에 유의하세요:

  • gitaly['configuration'][:storage]는 특정 Gitaly 노드의 스토리지 경로를 반영하도록 구성해야 합니다.

  • auth_tokenpraefect_internal_token과 동일해야 합니다.

다음 IP는 예시로 사용됩니다:

  • 10.6.0.91: Gitaly 1

  • 10.6.0.92: Gitaly 2

  • 10.6.0.93: Gitaly 3

각 노드에서:

원하는 Linux 패키지를 다운로드하고 설치하세요. 선택한 운영 체제에 맞는 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치하되, EXTERNAL_URL 값은 제공하지 마세요.

Gitaly 서버 노드의 /etc/gitlab/gitlab.rb 파일을 편집하여 스토리지 경로를 구성하고, 네트워크 리스너를 활성화하며, 토큰을 구성하세요:

  • 모든 레퍼런스 아키텍처 페이지 -->
# https://docs.gitlab.com/omnibus/roles/#gitaly-roles
roles(["gitaly_role"])

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

# Configure the gitlab-shell API callback URL. Without this, `git push` will
# fail. This can be your 'front door' GitLab URL or an internal load
# balancer.
gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'

# Configure the Consul agent
consul['enable'] = true
## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] = true

# START user configuration
# Please set the real values as explained in Required Information section
#
## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network address that the node exporter will listen on for monitoring
node_exporter['listen_address'] = '0.0.0.0:9100'

gitaly['configuration'] = {
   # Make Gitaly accept connections on all network interfaces. You must use
   # firewalls to restrict access to this address/port.
   # Comment out following line if you only want to support TLS connections
   listen_addr: '0.0.0.0:8075',
   # Set the network address that Gitaly will listen on for monitoring
   prometheus_listen_addr: '0.0.0.0:9236',
   auth: {
      # Gitaly Auth Token
      # Should be the same as praefect_internal_token
      token: '<praefect_internal_token>',
   },
   pack_objects_cache: {
      # Gitaly Pack-objects cache
      # Recommended to be enabled for improved performance but can notably increase disk I/O
      # Refer to https://docs.gitlab.com/administration/gitaly/configure_gitaly/#pack-objects-cache for more info
      enabled: true,
   },
}

#
# END user configuration

각 서버에 다음 내용을 /etc/gitlab/gitlab.rb에 추가합니다:

Gitaly 노드 1:

gitaly['configuration'] = {
   # ...
   storage: [
      {
         name: 'gitaly-1',
         path: '/var/opt/gitlab/git-data/repositories',
      },
   ],
}

Gitaly 노드 2:

gitaly['configuration'] = {
   # ...
   storage: [
      {
         name: 'gitaly-2',
         path: '/var/opt/gitlab/git-data/repositories',
      },
   ],
}

Gitaly 노드 3:

gitaly['configuration'] = {
   # ...
   storage: [
      {
         name: 'gitaly-3',
         path: '/var/opt/gitlab/git-data/repositories',
      },
   ],
}

첫 번째로 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체합니다. 처음으로 구성하는 Linux 패키지 노드라면 이 단계를 건너뛰어도 됩니다.

파일을 저장한 다음 GitLab을 재구성합니다.

Gitaly Cluster (Praefect) TLS 지원#

Praefect는 TLS 암호화를 지원합니다. 보안 연결을 수신하는 Praefect 인스턴스와 통신하려면 다음을 수행해야 합니다:

  • GitLab 구성에서 해당 스토리지 항목의 gitaly_addresstls:// URL 스킴을 사용합니다.

  • 인증서는 자동으로 제공되지 않으므로 직접 준비해야 합니다. 각 Praefect 서버에 해당하는 인증서를 해당 Praefect 서버에 설치해야 합니다.

또한 인증서 또는 인증 기관(CA)을 모든 Gitaly 서버와 Praefect와 통신하는 모든 Praefect 클라이언트에 설치해야 합니다. 아래에서 설명하는 GitLab 사용자 정의 인증서 구성 절차를 따르십시오.

다음 사항에 유의하세요:

  • 인증서에는 Praefect 서버에 접근하는 데 사용하는 주소가 명시되어야 합니다. 인증서에 호스트명 또는 IP 주소를 Subject Alternative Name으로 추가해야 합니다.

  • Praefect 서버를 암호화되지 않은 수신 주소 listen_addr와 암호화된 수신 주소 tls_listen_addr로 동시에 구성할 수 있습니다. 이를 통해 필요한 경우 암호화되지 않은 트래픽에서 암호화된 트래픽으로 점진적으로 전환할 수 있습니다. 암호화되지 않은 리스너를 비활성화하려면 praefect['configuration'][:listen_addr] = nil로 설정합니다.

  • 내부 로드 밸런서는 TLS 연결을 처리하도록 구성해야 합니다. 로드 밸런서가 암호화된 트래픽을 종료하지 않고 백엔드로 전달하는 TLS 패스스루(passthrough)를 지원하도록 구성하세요. 패스스루/직접 서버 반환(DSR) 로드 밸런서는 사용하지 마십시오. 로드 밸런서는 올바른 로드 밸런싱 및 헬스 체크를 유지하기 위해 연결을 적극적으로 프록시해야 합니다.

TLS로 Praefect를 구성하려면:

Praefect 서버용 인증서를 생성합니다.

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

/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',
   },
}

파일을 저장하고 재구성하세요.

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

sudo cp cert.pem /etc/gitlab/trusted-certs/

Praefect 클라이언트(Gitaly 서버 제외)에서 /etc/gitlab/gitlab.rbgitlab_rails['repositories_storages']를 다음과 같이 편집하세요:

gitlab_rails['repositories_storages'] = {
  "default" => {
    "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:3305',
    "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
  }
}

파일을 저장하고 GitLab을 재구성하세요.

컴포넌트 설정으로 돌아가기

Sidekiq 구성#

Sidekiq은 Redis, PostgreSQL, Gitaly 인스턴스에 대한 연결이 필요합니다. 또한 권장 사항에 따라 오브젝트 스토리지에 대한 연결도 필요합니다.

데이터 오브젝트에 NFS 대신 오브젝트 스토리지 사용이 권장되므로, 다음 예시에는 오브젝트 스토리지 구성이 포함되어 있습니다.

환경의 Sidekiq job 처리가 긴 큐로 인해 느리다면 그에 맞게 스케일 조정할 수 있습니다. 자세한 내용은 스케일링 문서를 참조하세요.

Container Registry, SAML, LDAP 등 추가 GitLab 기능을 구성할 때는 Rails 구성 외에 Sidekiq 구성도 함께 업데이트하세요. 자세한 내용은 외부 Sidekiq 문서를 참조하세요.

다음 Sidekiq 노드는 예시로 사용됩니다:

  • 10.6.0.101: Sidekiq 1

  • 10.6.0.102: Sidekiq 2

  • 10.6.0.103: Sidekiq 3

  • 10.6.0.104: Sidekiq 4

각 Sidekiq 노드를 구성하려면 다음 단계를 수행하세요:

Sidekiq 서버에 SSH로 접속합니다.

PostgreSQL, Gitaly, Redis 포트에 접근 가능한지 확인합니다:

telnet  5432 # PostgreSQL
telnet  8075 # Gitaly
telnet  6379 # Redis

원하는 Linux 패키지를 다운로드하고 설치하세요. GitLab 패키지 리포지터리만 추가하고, 선택한 운영 체제에 맞는 GitLab만 설치하세요.

/etc/gitlab/gitlab.rb를 생성하거나 편집하고 다음 구성을 사용하세요:

# https://docs.gitlab.com/omnibus/roles/#sidekiq-roles
roles(["sidekiq_role"])

# External URL
## This should match the URL of the external load balancer
external_url 'https://gitlab.example.com'

# Redis
## Redis connection details
## First cluster that will host the cache data
gitlab_rails['redis_cache_instance'] = 'redis://:@gitlab-redis-cache'

gitlab_rails['redis_cache_sentinels'] = [
  {host: '10.6.0.51', port: 26379},
  {host: '10.6.0.52', port: 26379},
  {host: '10.6.0.53', port: 26379},
]

## Second cluster that hosts all other persistent data
redis['master_name'] = 'gitlab-redis-persistent'
redis['master_password'] = ''

gitlab_rails['redis_sentinels'] = [
  {host: '10.6.0.61', port: 26379},
  {host: '10.6.0.62', port: 26379},
  {host: '10.6.0.63', port: 26379},
]

# Gitaly Cluster
## gitlab_rails['repositories_storages'] gets configured for the Praefect virtual storage
## TCP load balancer (recommended for most setups):
gitlab_rails['repositories_storages'] = {
  "default" => {
    "gitaly_address" => "tcp://10.6.0.40:2305", # internal load balancer IP
    "gitaly_token" => '<praefect_external_token>'
  }
}

## Alternatively, use service discovery DNS (requires DNS infrastructure):
# gitlab_rails['repositories_storages'] = {
#   "default" => {
#     "gitaly_address" => "dns:PRAEFECT_SERVICE_DISCOVERY_ADDRESS:2305",
#     "gitaly_token" => '<praefect_external_token>'
#   }
# }

# PostgreSQL
gitlab_rails['db_host'] = '10.6.0.20' # internal load balancer IP
gitlab_rails['db_port'] = 6432
gitlab_rails['db_password'] = '<postgresql_user_password>'
gitlab_rails['db_load_balancing'] = { 'hosts' => ['10.6.0.21', '10.6.0.22', '10.6.0.23'] } # PostgreSQL IPs

## Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

# Sidekiq
sidekiq['listen_address'] = "0.0.0.0"

## Set number of Sidekiq queue processes to the same number as available CPUs
sidekiq['queue_groups'] = ['*'] * 4

# Monitoring
consul['enable'] = true
consul['monitoring_service_discovery'] =  true

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

## Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'

## Add the monitoring node's IP address to the monitoring whitelist
gitlab_rails['monitoring_whitelist'] = ['10.6.0.151/32', '127.0.0.0/8']

# Object Storage
# This is an example for configuring Object Storage on GCP
# Replace this config with your chosen Object Storage provider as desired
gitlab_rails['object_store']['enabled'] = true
gitlab_rails['object_store']['connection'] = {
  'provider' => 'Google',
  'google_project' => '<gcp-project-name>',
  'google_json_key_location' => '<path-to-gcp-service-account-key>'
}
gitlab_rails['object_store']['objects']['artifacts']['bucket'] = "<gcp-artifacts-bucket-name>"
gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = "<gcp-external-diffs-bucket-name>"
gitlab_rails['object_store']['objects']['lfs']['bucket'] = "<gcp-lfs-bucket-name>"
gitlab_rails['object_store']['objects']['uploads']['bucket'] = "<gcp-uploads-bucket-name>"
gitlab_rails['object_store']['objects']['packages']['bucket'] = "<gcp-packages-bucket-name>"
gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = "<gcp-dependency-proxy-bucket-name>"
gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = "<gcp-terraform-state-bucket-name>"

gitlab_rails['backup_upload_connection'] = {
  'provider' => 'Google',
  'google_project' => '<gcp-project-name>',
  'google_json_key_location' => '<path-to-gcp-service-account-key>'
}
gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"

gitlab_rails['ci_secure_files_object_store_enabled'] = true
gitlab_rails['ci_secure_files_object_store_remote_directory'] = "<gcp-ci_secure_files-bucket-name>"

gitlab_rails['ci_secure_files_object_store_connection'] = {
   'provider' => 'Google',
   'google_project' => '<gcp-project-name>',
   'google_json_key_location' => '<path-to-gcp-service-account-key>'
}

첫 번째로 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하세요. 이 서버가 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

데이터베이스 마이그레이션이 업그레이드 시 자동으로 실행되지 않고 reconfigure 시에만 실행되도록 하려면 다음을 실행하세요:

sudo touch /etc/gitlab/skip-auto-reconfigure

마이그레이션은 GitLab Rails 사후 구성 섹션에 명시된 대로 단일 지정 노드에서만 처리해야 합니다.

변경 사항을 적용하려면 GitLab을 재구성하세요.

컴포넌트 설정으로 돌아가기

GitLab Rails 구성#

이 섹션에서는 GitLab 애플리케이션(Rails) 컴포넌트를 구성하는 방법을 설명합니다.

Rails는 Redis, PostgreSQLGitaly 인스턴스에 대한 연결이 필요합니다. 또한 권장 사항에 따라 오브젝트 스토리지에 대한 연결도 필요합니다.

[데이터 오브젝트에 NFS 대신 오브젝트 스토리지 사용이 권장되므로](/19.2/administration/object_storage/), 다음

예시에는 오브젝트 스토리지 구성이 포함되어 있습니다.

다음 IP가 예시로 사용됩니다:

  • 10.6.0.111: GitLab 애플리케이션 1

  • 10.6.0.112: GitLab 애플리케이션 2

  • 10.6.0.113: GitLab 애플리케이션 3

  • 10.6.0.114: GitLab 애플리케이션 4

  • 10.6.0.115: GitLab 애플리케이션 5

각 노드에서 다음을 수행하세요:

원하는 Linux 패키지를 다운로드하여 설치하세요. 선택한 운영 체제에 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 합니다.

/etc/gitlab/gitlab.rb를 편집하고 다음 구성을 사용하세요. 노드 간 링크 일관성을 유지하기 위해, 애플리케이션 서버의 external_url은 사용자가 GitLab에 접근할 때 사용하는 외부 URL을 가리켜야 합니다. 이는 GitLab 애플리케이션 서버로 트래픽을 라우팅하는 외부 로드 밸런서의 URL입니다:

external_url 'https://gitlab.example.com'

# gitlab_rails['repositories_storages'] gets configured for the Praefect virtual storage
# TCP load balancer (recommended for most setups):
gitlab_rails['repositories_storages'] = {
  "default" => {
    "gitaly_address" => "tcp://10.6.0.40:2305", # internal load balancer IP
    "gitaly_token" => '<praefect_external_token>'
  }
}

# Alternatively, use service discovery DNS (requires DNS infrastructure):
# gitlab_rails['repositories_storages'] = {
#   "default" => {
#     "gitaly_address" => "dns:PRAEFECT_SERVICE_DISCOVERY_ADDRESS:2305",
#     "gitaly_token" => '<praefect_external_token>'
#   }
# }

## Disable components that will not be on the GitLab application server
roles(['application_role'])
gitaly['enable'] = false
sidekiq['enable'] = false

## PostgreSQL connection details
# Disable PostgreSQL on the application node
postgresql['enable'] = false
gitlab_rails['db_host'] = '10.6.0.20' # internal load balancer IP
gitlab_rails['db_port'] = 6432
gitlab_rails['db_password'] = '<postgresql_user_password>'
gitlab_rails['db_load_balancing'] = { 'hosts' => ['10.6.0.21', '10.6.0.22', '10.6.0.23'] } # PostgreSQL IPs

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

## Redis connection details
## First cluster that will host the cache data
gitlab_rails['redis_cache_instance'] = 'redis://:@gitlab-redis-cache'

gitlab_rails['redis_cache_sentinels'] = [
  {host: '10.6.0.51', port: 26379},
  {host: '10.6.0.52', port: 26379},
  {host: '10.6.0.53', port: 26379},
]

## Second cluster that hosts all other persistent data
redis['master_name'] = 'gitlab-redis-persistent'
redis['master_password'] = ''

gitlab_rails['redis_sentinels'] = [
  {host: '10.6.0.61', port: 26379},
  {host: '10.6.0.62', port: 26379},
  {host: '10.6.0.63', port: 26379},
]

# Set the network addresses that the exporters used for monitoring will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'
gitlab_workhorse['prometheus_listen_addr'] = '0.0.0.0:9229'
puma['listen'] = '0.0.0.0'

# Add the monitoring node's IP address to the monitoring whitelist and allow it to
# scrape the NGINX metrics
gitlab_rails['monitoring_whitelist'] = ['10.6.0.151/32', '127.0.0.0/8']
nginx['status']['options']['allow'] = ['10.6.0.151/32', '127.0.0.0/8']

#############################
###     Object storage    ###
#############################

# This is an example for configuring Object Storage on GCP
# Replace this config with your chosen Object Storage provider as desired
gitlab_rails['object_store']['enabled'] = true
gitlab_rails['object_store']['connection'] = {
  'provider' => 'Google',
  'google_project' => '<gcp-project-name>',
  'google_json_key_location' => '<path-to-gcp-service-account-key>'
}
gitlab_rails['object_store']['objects']['artifacts']['bucket'] = "<gcp-artifacts-bucket-name>"
gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = "<gcp-external-diffs-bucket-name>"
gitlab_rails['object_store']['objects']['lfs']['bucket'] = "<gcp-lfs-bucket-name>"
gitlab_rails['object_store']['objects']['uploads']['bucket'] = "<gcp-uploads-bucket-name>"
gitlab_rails['object_store']['objects']['packages']['bucket'] = "<gcp-packages-bucket-name>"
gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = "<gcp-dependency-proxy-bucket-name>"
gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = "<gcp-terraform-state-bucket-name>"

gitlab_rails['backup_upload_connection'] = {
  'provider' => 'Google',
  'google_project' => '<gcp-project-name>',
  'google_json_key_location' => '<path-to-gcp-service-account-key>'
}
gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"
gitlab_rails['ci_secure_files_object_store_enabled'] = true
gitlab_rails['ci_secure_files_object_store_remote_directory'] = "<gcp-ci_secure_files-bucket-name>"

gitlab_rails['ci_secure_files_object_store_connection'] = {
   'provider' => 'Google',
   'google_project' => '<gcp-project-name>',
   'google_json_key_location' => '<path-to-gcp-service-account-key>'
}

TLS 지원이 포함된 Gitaly를 사용하는 경우, tcp 대신 tlsgitlab_rails['repositories_storages'] 항목이 구성되어 있는지 확인하세요:

# TCP load balancer with TLS (recommended for most setups):
gitlab_rails['repositories_storages'] = {
  "default" => {
    "gitaly_address" => "tls://10.6.0.40:3305", # internal load balancer IP
    "gitaly_token" => '<praefect_external_token>'
  }
}

# Alternatively, use service discovery DNS with TLS (requires DNS infrastructure and GitLab 18.9+):
# gitlab_rails['repositories_storages'] = {
#   "default" => {
#     "gitaly_address" => "dns+tls://DNS_SERVER_ADDRESS:53/PRAEFECT_SERVICE_DISCOVERY_ADDRESS:3305",
#     "gitaly_token" => '<praefect_external_token>'
#   }
# }

인증서를 /etc/gitlab/trusted-certs에 복사하세요:

sudo cp cert.pem /etc/gitlab/trusted-certs/

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하세요. 처음 구성하는 Linux 패키지 노드인 경우 이 단계를 건너뛸 수 있습니다.

처음 구성한 Rails 노드에서 SSH 호스트 키(/etc/ssh/ssh_host_*_key* 형식의 모든 파일)를 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하세요. 이를 통해 사용자가 로드 밸런싱된 Rails 노드에 접속할 때 호스트 불일치 오류가 발생하지 않도록 합니다. 처음 구성하는 Linux 패키지 노드인 경우 이 단계를 건너뛸 수 있습니다.

업그레이드 시 자동으로 실행되지 않고 reconfigure 중에만 데이터베이스 마이그레이션이 실행되도록 하려면 다음을 실행하세요:

sudo touch /etc/gitlab/skip-auto-reconfigure

GitLab Rails 사후 구성 섹션에 설명된 대로 지정된 단일 노드만 마이그레이션을 처리해야 합니다.

변경 사항을 적용하려면 GitLab을 Reconfigure하세요.

증분 로깅을 활성화하세요.

노드가 Gitaly에 연결할 수 있는지 확인하세요:

sudo gitlab-rake gitlab:gitaly:check

그런 다음 로그를 tail하여 요청을 확인하세요:

sudo gitlab-ctl tail gitaly

선택 사항으로, Gitaly 서버에서 Gitaly가 내부 API로 콜백을 수행할 수 있는지 확인하세요:

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을 실행하세요.

이전 예시와 같이 external_urlhttps를 지정하면 GitLab은 SSL 인증서가 /etc/gitlab/ssl/에 있을 것으로 예상합니다. 인증서가 없으면 NGINX가 시작되지 않습니다. 자세한 내용은 HTTPS 문서를 참조하세요.

GitLab Rails 사후 구성#

설치 및 업데이트 중 데이터베이스 마이그레이션을 실행할 애플리케이션 노드 하나를 지정하세요. GitLab 데이터베이스를 초기화하고 모든 마이그레이션이 실행되었는지 확인하세요:

sudo gitlab-rake gitlab:db:configure

이 작업을 수행하려면 Rails 노드가 PgBouncer를 우회하여 기본 데이터베이스에 직접 연결하도록 구성해야 합니다. 마이그레이션이 완료된 후에는 PgBouncer를 통해 연결을 전달하도록 노드를 다시 구성해야 합니다.

데이터베이스에서 승인된 SSH 키의 빠른 조회를 구성하세요.

구성 요소 설정으로 돌아가기

Prometheus 구성#

Linux 패키지를 사용하여 Prometheus를 실행하는 독립형 모니터링 노드를 구성할 수 있습니다.

다음 IP를 예시로 사용합니다:

  • 10.6.0.151: Prometheus

모니터링 노드를 구성하려면:

Monitoring 노드에 SSH로 접속합니다.

원하는 Linux 패키지를 다운로드하고 설치합니다. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제용 GitLab을 설치해야 합니다.

/etc/gitlab/gitlab.rb를 편집하고 다음 내용을 추가합니다:

roles(['monitoring_role', 'consul_role'])

external_url 'http://gitlab.example.com'

# Prometheus
prometheus['listen_address'] = '0.0.0.0:9090'
prometheus['monitor_kubernetes'] = false

# Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
}

# Configure Prometheus to scrape services not covered by discovery
prometheus['scrape_configs'] = [
   {
      'job_name': 'pgbouncer',
      'static_configs' => [
         'targets' => [
         "10.6.0.31:9188",
         "10.6.0.32:9188",
         "10.6.0.33:9188",
         ],
      ],
   },
   {
      'job_name': 'praefect',
      'static_configs' => [
         'targets' => [
         "10.6.0.131:9652",
         "10.6.0.132:9652",
         "10.6.0.133:9652",
         ],
      ],
   },
]

nginx['enable'] = false

파일을 저장하고 GitLab을 재구성합니다.

컴포넌트 설정으로 돌아가기

오브젝트 스토리지 구성#

GitLab은 다양한 유형의 데이터를 저장하기 위해 오브젝트 스토리지 서비스 사용을 지원합니다. 데이터 오브젝트의 경우 NFS보다 오브젝트 스토리지를 권장하며, 오브젝트 스토리지가 일반적으로 성능, 안정성, 확장성 면에서 훨씬 뛰어나기 때문에 대규모 설정에서도 더 적합합니다. 자세한 내용은 인프라 및 서비스를 참조하세요.

GitLab에서 오브젝트 스토리지 구성을 지정하는 방법은 두 가지입니다:

가능한 경우 아래 예시에서는 통합 형식을 사용합니다.

GitLab에서는 데이터 유형별로 별도의 버킷을 사용하는 방식을 권장합니다. 이렇게 하면 GitLab이 저장하는 다양한 유형의 데이터 간에 충돌이 발생하지 않습니다. 향후 단일 버킷 사용을 지원할 계획이 있습니다.

컴포넌트 설정으로 돌아가기

증분 로깅 활성화#

GitLab Runner는 job 로그를 청크 단위로 반환하며, 통합 오브젝트 스토리지를 사용하는 경우에도 Linux 패키지는 기본적으로 /var/opt/gitlab/gitlab-ci/builds 경로의 디스크에 임시로 캐시합니다. 기본 구성에서 이 디렉터리는 모든 GitLab Rails 및 Sidekiq 노드에서 NFS를 통해 공유되어야 합니다.

NFS를 통한 job 로그 공유는 지원되지만, NFS 노드를 배포하지 않은 경우 증분 로깅을 활성화하여 NFS 사용 필요성을 피할 수 있습니다(NFS 노드가 배포되지 않은 경우 필수). 증분 로깅은 job 로그의 임시 캐싱에 디스크 공간 대신 Redis를 사용합니다.

고급 검색 구성#

Elasticsearch를 활용하고 고급 검색을 활성화하면 전체 GitLab 인스턴스에서 더 빠르고 강력한 코드 검색을 수행할 수 있습니다.

Elasticsearch 클러스터 설계 및 요구 사항은 특정 데이터에 따라 달라집니다. 인스턴스와 함께 Elasticsearch 클러스터를 설정하는 방법에 대한 권장 모범 사례는 최적의 클러스터 구성 선택을 참조하세요.

컴포넌트 설정으로 돌아가기

Helm Charts를 사용한 Cloud Native Hybrid 레퍼런스 아키텍처 (대안)#

쿠버네티스에서 특정 GitLab 컴포넌트를 실행하는 대안적 방법도 있습니다. 다음 서비스가 지원됩니다:

  • GitLab Rails

  • Sidekiq

  • NGINX

  • Toolbox

  • Migrations

  • Prometheus

하이브리드 설치는 클라우드 네이티브 배포와 전통적인 컴퓨팅 배포 방식의 장점을 모두 활용합니다. 이를 통해 상태 비저장 컴포넌트는 클라우드 네이티브 워크로드 관리의 이점을 누릴 수 있으며, 상태 저장 컴포넌트는 Linux 패키지 설치를 사용하는 컴퓨팅 VM에 배포되어 더 높은 영속성의 이점을 얻을 수 있습니다.

쿠버네티스와 백엔드 컴포넌트 간에 동기화할 GitLab 시크릿에 대한 안내를 포함한 설정 지침은 Helm 차트 고급 구성 문서를 참조하세요.

이것은 **고급** 설정입니다. 쿠버네티스에서 서비스를 실행하는 것은 복잡한 작업으로 잘 알려져 있습니다.

이 설정은 쿠버네티스에 대한 충분한 실무 지식과 경험이 있는 경우에만 권장됩니다. 이 섹션의 나머지 내용은 이를 전제로 합니다.

Gitaly의 쿠버네티스 가용성, 제한 사항 및 배포 고려 사항에 대한 자세한 내용은 Gitaly on Kubernetes를 참조하세요.

클러스터 토폴로지#

다음 표와 다이어그램은 앞서 설명한 일반적인 환경과 동일한 형식을 사용하여 하이브리드 환경을 자세히 설명합니다.

먼저 쿠버네티스에서 실행되는 컴포넌트입니다. 이들은 여러 노드 그룹에 걸쳐 실행되지만, 최소 CPU 및 메모리 요구 사항이 충족되는 한 전체 구성을 원하는 대로 변경할 수 있습니다.

컴포넌트 노드 그룹 타깃 노드 풀 합계 GCP 예시 AWS 예시
Webservice 140 vCPU175 GB memory (request)245 GB memory (limit) 5 x n1-standard-32 5 x c5.9xlarge
Sidekiq 12.6 vCPU28 GB memory (request)56 GB memory (limit) 4 x n1-standard-4 4 x m5.xlarge
Supporting services 8 vCPU30 GB memory 2 x n1-standard-4 2 x m5.xlarge
  • 이 설정에서는 Google Kubernetes Engine (GKE)Amazon Elastic Kubernetes Service (EKS)를 정기적으로 테스트하고 권장합니다. 다른 쿠버네티스 서비스도 작동할 수 있지만, 결과는 다를 수 있습니다.

  • 머신 유형 예시는 설명 목적으로 제공됩니다. 이 유형들은 검증 및 테스트에서 사용되지만, 규범적인 기본값으로 의도된 것은 아닙니다. 요구 사항을 충족하는 다른 머신 유형으로 전환하는 것이 지원됩니다. 자세한 내용은 지원되는 머신 유형을 참조하세요.

  • WebserviceSidekiq 타깃 노드 풀 합계는 GitLab 컴포넌트 전용으로 제공됩니다. 선택한 쿠버네티스 제공업체의 시스템 프로세스에는 추가 리소스가 필요합니다. 제공된 예시는 이를 고려한 것입니다.

  • Supporting 타깃 노드 풀 합계는 GitLab 배포를 지원하는 여러 리소스 및 요구 사항에 따라 추가로 배포할 수 있는 리소스를 수용하기 위해 일반적으로 제공됩니다. 다른 노드 풀과 마찬가지로 선택한 쿠버네티스 제공업체의 시스템 프로세스에도 리소스가 필요합니다. 제공된 예시는 이를 고려한 것입니다.

  • 프로덕션 배포에서는 Pod를 특정 노드에 할당할 필요가 없습니다. 그러나 복원력 있는 클라우드 아키텍처 관행에 맞게 각 풀에서 여러 가용 영역에 걸쳐 여러 노드를 배치하는 것을 권장합니다.

  • 효율성을 위해 Cluster Autoscaler와 같은 오토스케일링을 활성화하는 것이 권장되지만, 지속적인 성능 보장을 위해 Webservice 및 Sidekiq Pod의 최소 기준을 75%로 타깃팅하는 것이 일반적으로 권장됩니다.

다음은 Linux 패키지(또는 해당하는 경우 외부 PaaS 서비스)를 사용하는 정적 컴퓨팅 VM에서 실행되는 백엔드 컴포넌트입니다:

서비스 노드 수 구성 GCP 예시1 AWS 예시1
Consul2 3 2 vCPU, 1.8 GB memory n1-highcpu-2 c5.large
PostgreSQL2 3 16 vCPU, 60 GB memory n1-standard-16 m5.4xlarge
PgBouncer2 3 2 vCPU, 1.8 GB memory n1-highcpu-2 c5.large
Internal load balancer4 1 8 vCPU, 7.2 GB memory n1-highcpu-8 c5.2xlarge
Redis/Sentinel - Cache3 3 4 vCPU, 15 GB memory n1-standard-4 m5.xlarge
Redis/Sentinel - Persistent3 3 4 vCPU, 15 GB memory n1-standard-4 m5.xlarge
Gitaly67 3 32 vCPU, 120 GB memory n1-standard-32 m5.8xlarge
Praefect6 3 4 vCPU, 3.6 GB memory n1-highcpu-4 c5.xlarge
Praefect PostgreSQL2 1+ 2 vCPU, 1.8 GB memory n1-highcpu-2 c5.large
Object storage5 - - - -

각주:

-->

  • 머신 유형 예시는 설명 목적으로 제공됩니다. 이 유형들은 검증 및 테스트에서 사용되지만, 규범적인 기본값으로 의도된 것은 아닙니다. 나열된 요구 사항을 충족하는 다른 머신 유형으로 전환하는 것이 지원되며, 가능한 경우 ARM 변형도 포함됩니다. 자세한 내용은 지원되는 머신 유형을 참조하세요.

  • 신뢰할 수 있는 타사 외부 PaaS PostgreSQL 솔루션에서 선택적으로 실행할 수 있습니다. 자세한 내용은 직접 PostgreSQL 인스턴스 제공을 참조하세요.

  • 신뢰할 수 있는 타사 외부 PaaS Redis 솔루션에서 선택적으로 실행할 수 있습니다. 자세한 내용은 직접 Redis 인스턴스 제공을 참조하세요.

Redis는 기본적으로 단일 스레드로 동작하며 CPU 코어 수 증가에 따른 이점이 크지 않습니다. 이 규모의 아키텍처에서는 최적의 성능을 위해 지정된 대로 별도의 캐시 및 영속 인스턴스를 사용하는 것이 강력히 권장됩니다.

  • 신뢰할 수 있는 타사 로드 밸런싱 서비스(LB PaaS)에서 선택적으로 실행할 수 있습니다. 자세한 내용은 인프라 및 서비스를 참조하세요.

  • 신뢰할 수 있는 클라우드 제공업체 또는 Self-managed 솔루션에서 실행해야 합니다. 자세한 내용은 오브젝트 스토리지 구성을 참조하세요.

  • Gitaly 클러스터(Praefect)는 장애 허용의 이점을 제공하지만, 설정 및 관리가 더 복잡합니다. Gitaly 클러스터(Praefect) 배포 전 기술적 제한 사항 및 고려 사항을 검토하세요. 샤딩된 Gitaly를 사용하려면 이전 표의 Gitaly 항목과 동일한 사양을 사용하세요.

  • Gitaly 사양은 양호한 상태의 사용 패턴과 리포지터리 크기의 높은 백분위수를 기준으로 합니다. 그러나 대형 모노리포(수 기가바이트 이상) 또는 추가 워크로드가 있는 경우, Git 및 Gitaly 성능에 상당한 영향을 미칠 수 있으며 추가 조정이 필요할 수 있습니다.

    인스턴스 구성이 포함된 모든 PaaS 솔루션의 경우, 복원력 있는 클라우드 아키텍처 관행에 맞게 세 개의 서로 다른 가용 영역에 최소 세 개의 노드를 구현하는 것을 권장합니다.

    @startuml 25k skinparam linetype ortho

card "Kubernetes via Helm Charts" as kubernetes { card "External Load Balancer" as elb #6a9be7

together { collections "Webservice" as gitlab #32CD32 collections "Sidekiq" as sidekiq #ff8dd1 }

card "Supporting Services" as support }

card "Internal Load Balancer" as ilb #9370DB collections "Consul x3" as consul #e76a9b

card "Gitaly Cluster" as gitaly_cluster { collections "Praefect x3" as praefect #FF8C00 collections "Gitaly x3" as gitaly #FF8C00 card "Praefect PostgreSQL*\n//Non fault-tolerant//" as praefect_postgres #FF8C00

praefect -[#FF8C00]-> gitaly praefect -[#FF8C00]> praefect_postgres }

card "Database" as database { collections "PGBouncer x3" as pgbouncer #4EA7FF card "PostgreSQL (Primary)" as postgres_primary #4EA7FF collections "PostgreSQL (Secondary) x2" as postgres_secondary #4EA7FF

pgbouncer -[#4EA7FF]-> postgres_primary postgres_primary .[#4EA7FF]> postgres_secondary }

card "redis" as redis { collections "Redis Persistent x3" as redis_persistent #FF6347 collections "Redis Cache x3" as redis_cache #FF6347

redis_cache -[hidden]-> redis_persistent }

cloud "Object Storage" as object_storage #white

elb -[#6a9be7]-> gitlab elb -[hidden]-> sidekiq elb -[hidden]-> support

gitlab -[#32CD32]--> ilb gitlab -[#32CD32]r--> object_storage gitlab -[#32CD32,norank]----> redis gitlab -[#32CD32]----> database

sidekiq -[#ff8dd1]--> ilb sidekiq -[#ff8dd1]r--> object_storage sidekiq -[#ff8dd1,norank]----> redis sidekiq .[#ff8dd1]----> database

ilb -[#9370DB]--> gitaly_cluster ilb -[#9370DB]--> database ilb -[hidden,norank]--> redis

consul .[#e76a9b]--> database consul .[#e76a9b,norank]--> gitaly_cluster consul .[#e76a9b]--> redis

@enduml

쿠버네티스 컴포넌트 타깃#

다음 섹션에서는 쿠버네티스에 배포된 GitLab 컴포넌트에 사용되는 타깃을 자세히 설명합니다.

Webservice#

각 Webservice Pod(Puma 및 Workhorse)는 다음 구성으로 실행하는 것을 권장합니다:

  • Puma Worker 4개

  • vCPU 4개

  • 메모리 5GB(요청)

  • 메모리 7GB(제한)

RPS 500 또는 사용자 25,000명 기준으로 총 Puma worker 수는 약 140개를 권장하므로, 최소 35개의 Webservice Pod를 실행하는 것을 권장합니다.

Webservice 리소스 사용에 대한 자세한 내용은 Webservice 리소스에 대한 Charts 문서를 참조하세요.

Gateway API / Ingress#

Gateway API 또는 Ingress 컨트롤러 Pod를 DaemonSet으로 Webservice 노드에 배포하는 것도 권장합니다. 이를 통해 컨트롤러가 서비스하는 Webservice Pod에 맞게 동적으로 확장되고, 일반적으로 더 큰 머신 유형이 제공하는 높은 네트워크 대역폭을 활용할 수 있습니다.

이것은 엄격한 요구 사항이 아닙니다. Gateway API 또는 Ingress 컨트롤러 Pod는 웹 트래픽을 처리하기에 충분한 리소스가 있는 한 원하는 방식으로 배포할 수 있습니다.

Sidekiq#

각 Sidekiq Pod는 다음 구성으로 실행하는 것을 권장합니다:

  • Sidekiq worker 1개

  • vCPU 900m

  • 메모리 2GB(요청)

  • 메모리 4GB(제한)

앞서 문서화된 표준 배포와 유사하게, 여기서는 초기 타깃으로 Sidekiq worker 14개를 사용했습니다. 특정 워크플로에 따라 추가 worker가 필요할 수 있습니다.

Sidekiq 리소스 사용에 대한 자세한 내용은 Sidekiq 리소스에 대한 Charts 문서를 참조하세요.

지원(Supporting)#

Supporting 노드 풀은 Webservice 및 Sidekiq 풀에 필요하지 않은 모든 지원 배포를 수용하도록 설계되었습니다.

여기에는 클라우드 제공업체의 구현과 관련된 다양한 배포 및 GitLab Shell과 같은 GitLab 지원 배포가 포함됩니다.

컨테이너 레지스트리, Pages, 모니터링 등 추가 배포는 가능한 한 Webservice 또는 Sidekiq 풀이 아닌 Supporting 노드 풀에 배포하세요. Supporting 노드 풀은 여러 추가 배포를 수용할 수 있도록 설계되었습니다. 그러나 배포가 주어진 풀에 맞지 않는 경우 노드 풀을 그에 맞게 늘릴 수 있습니다. 반대로, 사용 사례에서 풀이 과도하게 프로비저닝된 경우 그에 맞게 줄일 수 있습니다.

예시 구성 파일#

RPS 500 또는 사용자 25,000명 레퍼런스 아키텍처 구성을 타깃으로 하는 GitLab Helm Charts의 예시는 Charts 프로젝트에서 확인할 수 있습니다.

컴포넌트 설정으로 돌아가기

다음 단계#

이 가이드를 따른 후에는 핵심 기능이 적절히 구성된 새로운 GitLab 환경이 준비되어 있어야 합니다.

요구 사항에 따라 GitLab의 추가 선택적 기능을 구성할 수 있습니다. 자세한 내용은 GitLab 설치 후 단계를 참조하세요.

환경 및 요구 사항에 따라 원하는 추가 기능을 설정하기 위해 추가적인 하드웨어 요구 사항이나 조정이 필요할 수 있습니다. 자세한 내용은 개별 페이지를 참조하세요.

레퍼런스 아키텍처: 최대 500 RPS 또는 25,000명의 사용자

GitLab v19.2
원문 보기
요약

- Offering: GitLab Self-Managed 이 페이지는 초당 500개 요청(RPS)의 최대 부하를 목표로 설계된 GitLab 레퍼런스 아키텍처를 설명합니다. 전체 레퍼런스 아키텍처 목록은 사용 가능한 레퍼런스 아키텍처를 참조하세요.


레퍼런스 아키텍처: 최대 500 RPS 또는 25,000명의 사용자#

  - 
  Tier: Premium, Ultimate

- Offering: GitLab Self-Managed

이 페이지는 초당 500개 요청(RPS)의 최대 부하를 목표로 설계된 GitLab 레퍼런스 아키텍처를 설명합니다. 이는 실제 데이터를 기반으로 한 수동 및 자동화 방식의 최대 25,000명의 사용자에 해당하는 일반적인 최대 부하입니다.

전체 레퍼런스 아키텍처 목록은 사용 가능한 레퍼런스 아키텍처를 참조하세요.

이 아키텍처를 배포하기 전에 먼저 [주요 문서](/19.2/administration/reference_architectures/)를 읽어보시기 바라며,

특히 시작하기 전에사용할 아키텍처 결정하기 섹션을 확인하세요.

  • 타깃 부하: API: 500 RPS, Web: 50 RPS, Git (Pull): 50 RPS, Git (Push): 10 RPS

  • 고가용성: 예 (HA를 위해 Praefect는 서드파티 PostgreSQL 솔루션 필요)

  • 클라우드 네이티브 하이브리드 대안:

  • 어떤 레퍼런스 아키텍처를 사용해야 할지 모르시겠나요? 이 가이드에서 자세한 내용을 확인하세요

서비스 노드 수 구성 GCP 예시1 AWS 예시1 Azure 예시1
외부 로드 밸런서4 1 8 vCPU, 7.2 GB 메모리 n1-highcpu-8 c5n.2xlarge F8s v2
Consul2 3 2 vCPU, 1.8 GB 메모리 n1-highcpu-2 c5.large F2s v2
PostgreSQL2 3 16 vCPU, 60 GB 메모리 n1-standard-16 m5.4xlarge D16s v3
PgBouncer2 3 2 vCPU, 1.8 GB 메모리 n1-highcpu-2 c5.large F2s v2
내부 로드 밸런서4 1 8 vCPU, 7.2 GB 메모리 n1-highcpu-8 c5n.2xlarge F8s v2
Redis/Sentinel - 캐시3 3 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge D4s v3
Redis/Sentinel - 영구3 3 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge D4s v3
Gitaly67 3 32 vCPU, 120 GB 메모리 n1-standard-32 m5.8xlarge D32s v3
Praefect6 3 4 vCPU, 3.6 GB 메모리 n1-highcpu-4 c5.xlarge F4s v2
Praefect PostgreSQL2 1+ 2 vCPU, 1.8 GB 메모리 n1-highcpu-2 c5.large F2s v2
Sidekiq8 4 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge D4s v3
GitLab Rails8 5 32 vCPU, 28.8 GB 메모리 n1-highcpu-32 c5.9xlarge F32s v2
모니터링 노드 1 4 vCPU, 3.6 GB 메모리 n1-highcpu-4 c5.xlarge F4s v2
오브젝트 스토리지5 - - - - -

각주:

-->

  • 머신 유형 예시는 설명 목적으로 제공됩니다. 이러한 유형은 검증 및 테스트에 사용되지만 규범적인 기본값으로 의도된 것이 아닙니다. 나열된 요구 사항을 충족하는 다른 머신 유형으로의 전환이 지원되며, 가용한 경우 ARM 변형도 포함됩니다. 자세한 내용은 지원되는 머신 유형을 참조하세요.

  • 신뢰할 수 있는 서드파티 외부 PaaS PostgreSQL 솔루션에서 선택적으로 실행할 수 있습니다. 자세한 내용은 자체 PostgreSQL 인스턴스 제공을 참조하세요.

  • 신뢰할 수 있는 서드파티 외부 PaaS Redis 솔루션에서 선택적으로 실행할 수 있습니다. 자세한 내용은 자체 Redis 인스턴스 제공을 참조하세요.

Redis는 기본적으로 단일 스레드이며 CPU 코어 수 증가로부터 크게 이점을 얻지 못합니다. 이 규모의 아키텍처에서는 최적의 성능을 달성하기 위해 지정된 대로 별도의 캐시와 영구 인스턴스를 사용하는 것이 강력히 권장됩니다.

  • 고가용성(HA) 기능을 제공할 수 있는 신뢰할 수 있는 서드파티 로드 밸런서 또는 서비스(LB PaaS)와 함께 실행하는 것이 권장됩니다. 또한 크기는 선택한 로드 밸런서와 네트워크 대역폭 등 추가 요소에 따라 달라집니다. 자세한 내용은 로드 밸런서를 참조하세요.

  • 신뢰할 수 있는 클라우드 제공업체 또는 자체 관리형 솔루션에서 실행해야 합니다. 자세한 내용은 오브젝트 스토리지 구성을 참조하세요.

  • Gitaly 클러스터(Praefect)는 장애 허용성의 이점을 제공하지만 설정 및 관리의 추가적인 복잡성이 따릅니다. Gitaly 클러스터 배포 전 기존 기술적 제한 사항 및 고려 사항을 검토하세요. 샤드된 Gitaly를 원하는 경우 이전 테이블의 Gitaly에 나열된 것과 동일한 사양을 사용하세요.

  • Gitaly 사양은 정상 상태에서의 사용 패턴과 리포지터리 크기의 높은 백분위수를 기반으로 합니다. 그러나 대형 모노리포(수 기가바이트보다 큰 경우)나 추가 워크로드가 있는 경우 Git 및 Gitaly 성능에 상당한 영향을 미칠 수 있으며 추가적인 조정이 필요할 수 있습니다.

  • 해당 컴포넌트가 상태 데이터를 저장하지 않기 때문에 Auto Scaling Groups(ASG)에 배치할 수 있습니다. 그러나 마이그레이션Mailroom과 같은 특정 컴포넌트는 하나의 노드에서만 실행될 수 있어 쿠버네티스에서 더 잘 처리되기 때문에, 일반적으로 클라우드 네이티브 하이브리드 설정이 선호됩니다.

    인스턴스 구성이 포함된 모든 PaaS 솔루션의 경우, 탄력적인 클라우드 아키텍처 관행에 맞추기 위해 세 개의 서로 다른 가용 영역에 최소 세 개의 노드를 구현하는 것이 권장됩니다.

    @startuml 25k skinparam linetype ortho

card "External Load Balancer" as elb #6a9be7 card "Internal Load Balancer" as ilb #9370DB

together { collections "GitLab Rails x5" as gitlab #32CD32 collections "Sidekiq x4" as sidekiq #ff8dd1 }

together { card "Prometheus" as monitor #7FFFD4 collections "Consul x3" as consul #e76a9b }

card "Gitaly Cluster" as gitaly_cluster { collections "Praefect x3" as praefect #FF8C00 collections "Gitaly x3" as gitaly #FF8C00 card "Praefect PostgreSQL*\n//Non fault-tolerant//" as praefect_postgres #FF8C00

praefect -[#FF8C00]-> gitaly praefect -[#FF8C00]> praefect_postgres }

card "Database" as database { collections "PGBouncer x3" as pgbouncer #4EA7FF card "PostgreSQL //Primary//" as postgres_primary #4EA7FF collections "PostgreSQL //Secondary// x2" as postgres_secondary #4EA7FF

pgbouncer -[#4EA7FF]-> postgres_primary postgres_primary .[#4EA7FF]> postgres_secondary }

card "redis" as redis { collections "Redis Persistent x3" as redis_persistent #FF6347 collections "Redis Cache x3" as redis_cache #FF6347

redis_cache -[hidden]-> redis_persistent }

cloud "Object Storage" as object_storage #white

elb -[#6a9be7]-> gitlab elb -[#6a9be7,norank]--> monitor

gitlab -[#32CD32,norank]--> ilb gitlab -[#32CD32]r-> object_storage gitlab -[#32CD32]----> redis gitlab .[#32CD32]----> database gitlab -[hidden]-> monitor gitlab -[hidden]-> consul

sidekiq -[#ff8dd1,norank]--> ilb sidekiq -[#ff8dd1]r-> object_storage sidekiq -[#ff8dd1]----> redis sidekiq .[#ff8dd1]----> database sidekiq -[hidden]-> monitor sidekiq -[hidden]-> consul

ilb -[#9370DB]--> gitaly_cluster ilb -[#9370DB]--> database ilb -[hidden]--> redis ilb -[hidden]u-> consul ilb -[hidden]u-> monitor

consul .[#e76a9b]u-> gitlab consul .[#e76a9b]u-> sidekiq consul .[#e76a9b]r-> monitor consul .[#e76a9b]-> database consul .[#e76a9b]-> gitaly_cluster consul .[#e76a9b,norank]--> redis

monitor .[#7FFFD4]u-> gitlab monitor .[#7FFFD4]u-> sidekiq monitor .[#7FFFD4]> consul monitor .[#7FFFD4]-> database monitor .[#7FFFD4]-> gitaly_cluster monitor .[#7FFFD4,norank]--> redis monitor .[#7FFFD4]> ilb monitor .[#7FFFD4,norank]u--> elb

@enduml

요구사항#

시작하기 전에 레퍼런스 아키텍처의 요구사항을 확인하세요.

테스트 방법론#

500 RPS / 25k 사용자 레퍼런스 아키텍처는 가장 일반적인 워크플로를 수용하도록 설계되었습니다. GitLab은 다음 엔드포인트 처리량 타깃을 기준으로 정기적으로 스모크 및 성능 테스트를 실시합니다:

엔드포인트 유형 타깃 처리량
API 500 RPS
Web 50 RPS
Git (Pull) 50 RPS
Git (Push) 10 RPS

이 타깃은 CI 파이프라인 및 기타 워크로드를 포함하여 지정된 사용자 수에 대한 전체 환경 부하를 반영하는 실제 고객 데이터를 기반으로 합니다. 이는 일반적인 워크로드 구성을 나타냅니다. 비정형 워크로드 패턴에 대한 안내는 RPS 구성 이해하기를 참고하세요.

테스트 방법론에 대한 자세한 내용은 검증 및 테스트 결과 섹션을 참고하세요.

성능 고려사항#

환경에 다음과 같은 상황이 있는 경우 추가적인 조정이 필요할 수 있습니다:

이러한 경우 자세한 내용은 환경 확장하기를 참고하세요. 이러한 고려사항이 해당될 수 있다고 판단되면, 필요한 추가 안내를 위해 저희에게 문의하세요.

로드 밸런서 구성#

테스트 환경에서는 다음을 사용합니다:

  • Linux 패키지 환경을 위한 HAProxy

  • Cloud Native Hybrid를 위한 Gateway API 또는 Ingress 구현이 포함된 클라우드 제공업체 동등 솔루션

컴포넌트 설정#

GitLab 및 해당 컴포넌트를 최대 500 RPS 또는 25,000 사용자를 수용하도록 설정하려면:

서버들은 동일한 10.6.0.0/24 사설 네트워크 대역에서 시작되며, 해당 주소로 서로 자유롭게 연결할 수 있습니다.

다음 목록은 각 서버에 대한 설명과 할당된 IP를 포함합니다:

  • 10.6.0.10: External Load Balancer

  • 10.6.0.11: Consul 1

  • 10.6.0.12: Consul 2

  • 10.6.0.13: Consul 3

  • 10.6.0.21: PostgreSQL primary

  • 10.6.0.22: PostgreSQL secondary 1

  • 10.6.0.23: PostgreSQL secondary 2

  • 10.6.0.31: PgBouncer 1

  • 10.6.0.32: PgBouncer 2

  • 10.6.0.33: PgBouncer 3

  • 10.6.0.40: Internal Load Balancer

  • 10.6.0.51: Redis - Cache Primary

  • 10.6.0.52: Redis - Cache Replica 1

  • 10.6.0.53: Redis - Cache Replica 2

  • 10.6.0.61: Redis - Persistent Primary

  • 10.6.0.62: Redis - Persistent Replica 1

  • 10.6.0.63: Redis - Persistent Replica 2

  • 10.6.0.91: Gitaly 1

  • 10.6.0.92: Gitaly 2

  • 10.6.0.93: Gitaly 3

  • 10.6.0.131: Praefect 1

  • 10.6.0.132: Praefect 2

  • 10.6.0.133: Praefect 3

  • 10.6.0.141: Praefect PostgreSQL 1 (non HA)

  • 10.6.0.101: Sidekiq 1

  • 10.6.0.102: Sidekiq 2

  • 10.6.0.103: Sidekiq 3

  • 10.6.0.104: Sidekiq 4

  • 10.6.0.111: GitLab application 1

  • 10.6.0.112: GitLab application 2

  • 10.6.0.113: GitLab application 3

  • 10.6.0.114: GitLab application 4

  • 10.6.0.115: GitLab application 5

  • 10.6.0.151: Prometheus

외부 로드 밸런서 구성#

다중 노드 GitLab 구성에서는 애플리케이션 서버로 트래픽을 라우팅하기 위한 외부 로드 밸런서가 필요합니다.

어떤 로드 밸런서를 사용할지, 또는 정확한 구성 방법은 GitLab 문서의 범위를 벗어나지만, 일반적인 요구 사항에 대한 자세한 내용은 로드 밸런서를 참고하세요. 이 섹션에서는 선택한 로드 밸런서에 대해 구성해야 하는 세부 사항에 집중합니다.

준비 상태 확인#

외부 로드 밸런서가 내장 모니터링 엔드포인트를 통해 정상 작동하는 서비스로만 트래픽을 라우팅하도록 설정하세요. 준비 상태 확인은 확인 대상 노드에 추가 구성이 필요하며, 그렇지 않으면 외부 로드 밸런서가 연결할 수 없습니다.

포트#

기본으로 사용하는 포트는 아래 테이블에 나와 있습니다.

LB Port Backend Port Protocol
80 80 HTTP (1)
443 443 TCP or HTTPS (1) (2)
22 22 TCP
  • (1): 웹 터미널 지원을 위해 로드 밸런서가 WebSocket 연결을 올바르게 처리해야 합니다. HTTP 또는 HTTPS 프록싱을 사용할 경우, 로드 밸런서는 ConnectionUpgrade hop-by-hop 헤더를 통과시키도록 구성해야 합니다. 자세한 내용은 웹 터미널 통합 가이드를 참고하세요.

  • (2): 포트 443에 HTTPS 프로토콜을 사용할 경우, 로드 밸런서에 SSL 인증서를 추가해야 합니다. SSL을 GitLab 애플리케이션 서버에서 종료하려면 TCP 프로토콜을 사용하세요.

커스텀 도메인 지원과 함께 GitLab Pages를 사용하는 경우 추가적인 포트 구성이 필요합니다. GitLab Pages는 별도의 가상 IP 주소가 필요합니다. /etc/gitlab/gitlab.rbpages_external_url이 새 가상 IP 주소를 가리키도록 DNS를 구성하세요. 다음을 참고하세요.

자세한 내용은 GitLab Pages 문서를 참조하세요.

LB 포트 백엔드 포트 프로토콜
80 상황에 따라 다름 (1) HTTP
443 상황에 따라 다름 (1) TCP (2)
  • (1): GitLab Pages의 백엔드 포트는 gitlab_pages['external_http']gitlab_pages['external_https'] 설정에 따라 달라집니다. 자세한 내용은 GitLab Pages 문서를 참조하세요.

  • (2): GitLab Pages의 443 포트는 항상 TCP 프로토콜을 사용해야 합니다. 사용자가 커스텀 SSL로 커스텀 도메인을 구성할 수 있는데, 로드 밸런서에서 SSL이 종료되면 이것이 불가능해집니다.

대체 SSH 포트#

일부 조직에서는 SSH 포트 22를 개방하는 것을 금지하는 정책을 운영합니다. 이 경우, 사용자가 443 포트로 SSH를 사용할 수 있도록 대체 SSH 호스트명을 구성하는 것이 도움이 될 수 있습니다. 대체 SSH 호스트명을 사용하려면 앞서 설명한 GitLab HTTP 구성과 비교하여 새로운 가상 IP 주소가 필요합니다.

대체 SSH 호스트명(예: altssh.gitlab.example.com)에 대한 DNS를 구성합니다.

LB 포트 백엔드 포트 프로토콜
443 22 TCP

SSL#

다음으로 결정해야 할 사항은 환경에서 SSL을 어떻게 처리할지입니다. 몇 가지 옵션이 있습니다:

애플리케이션 노드에서 SSL 종료#

로드 밸런서가 443 포트의 연결을 HTTP(S) 프로토콜 대신 TCP로 통과시키도록 구성합니다. 이렇게 하면 연결이 애플리케이션 노드의 NGINX 서비스로 변형 없이 전달됩니다. NGINX가 SSL 인증서를 보유하고 443 포트에서 수신 대기합니다.

SSL 인증서 관리 및 NGINX 구성에 대한 자세한 내용은 HTTPS 문서를 참조하세요.

로드 밸런서에서 백엔드 SSL 없이 SSL 종료#

로드 밸런서가 TCP 대신 HTTP(S) 프로토콜을 사용하도록 구성합니다. 그러면 로드 밸런서가 SSL 인증서 관리 및 SSL 종료를 담당합니다.

로드 밸런서와 GitLab 간의 통신이 보안이 적용되지 않으므로 추가 구성이 필요합니다. 자세한 내용은 프록시된 SSL 문서를 참조하세요.

로드 밸런서에서 백엔드 SSL과 함께 SSL 종료#

로드 밸런서가 'TCP' 대신 'HTTP(S)' 프로토콜을 사용하도록 구성합니다. 로드 밸런서가 최종 사용자에게 표시되는 SSL 인증서 관리를 담당합니다.

이 시나리오에서는 로드 밸런서와 NGINX 간의 트래픽도 보안이 적용됩니다. 연결이 전 구간에서 보안이 적용되므로 프록시된 SSL에 대한 구성을 추가할 필요가 없습니다. 단, SSL 인증서를 구성하기 위해 GitLab에 구성을 추가해야 합니다. SSL 인증서 관리 및 NGINX 구성에 대한 자세한 내용은 HTTPS 문서를 참조하세요.

구성 요소 설정으로 돌아가기

내부 로드 밸런서 구성#

내부 로드 밸런서는 GitLab 환경에서 필요한 내부 연결(예: PgBouncerGitaly Cluster(Praefect)에 대한 연결)의 부하를 분산하는 데 사용됩니다.

외부 로드 밸런서와는 별개의 노드이며, 외부에서 접근할 수 없어야 합니다.

다음 IP를 예시로 사용합니다:

  • 10.6.0.40: 내부 로드 밸런서

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 10.6.0.31:6432 check
    server pgbouncer2 10.6.0.32:6432 check
    server pgbouncer3 10.6.0.33:6432 check

# Praefect load balancing (skip both sections below if using DNS service discovery for Praefect)
# For more information, see https://docs.gitlab.com/administration/gitaly/praefect/configure/#service-discovery
frontend internal-praefect-tcp-in
    bind *:2305
    mode tcp
    option tcplog
    option clitcpka

    default_backend praefect

backend praefect
    mode tcp
    option tcp-check
    option srvtcpka

    server praefect1 10.6.0.131:2305 check
    server praefect2 10.6.0.132:2305 check
    server praefect3 10.6.0.133:2305 check

자세한 안내는 사용 중인 로드 밸런서의 문서를 참조하세요.

구성 요소 설정으로 돌아가기

구성 요소 설정으로 돌아가기

Consul 구성#

다음으로, Consul 서버를 설정합니다.

Consul은 반드시 3개 이상의 홀수 노드로 배포해야 합니다. 이는 노드가 쿼럼의 일부로 투표를 수행할 수 있도록 하기 위함입니다.

다음 IP는 예시로 사용됩니다:

  • 10.6.0.11: Consul 1

  • 10.6.0.12: Consul 2

  • 10.6.0.13: Consul 3

Consul을 구성하려면:

Consul을 호스팅할 서버에 SSH로 접속합니다.

원하는 Linux 패키지를 다운로드하여 설치합니다. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제에 맞는 GitLab을 설치해야 합니다. 현재 설치된 것과 동일한 버전과 유형(Community 또는 Enterprise Edition)을 선택하세요.

/etc/gitlab/gitlab.rb를 편집하여 다음 내용을 추가합니다:

roles(['consul_role'])

## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   server: true,
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체합니다. 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

변경 사항을 적용하려면 GitLab을 재구성합니다.

다른 모든 Consul 노드에 대해 위 단계를 반복하며, 올바른 IP를 설정했는지 확인합니다.

세 번째 Consul 서버 프로비저닝이 완료되면 Consul 리더가 선출됩니다. Consul 로그 sudo gitlab-ctl tail consul을 확인하면 ...[INFO] consul: New leader elected: ...가 표시됩니다.

현재 Consul 멤버(서버, 클라이언트)를 나열할 수 있습니다:

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

GitLab 서비스가 실행 중인지 확인할 수 있습니다:

sudo gitlab-ctl status

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

run: consul: (pid 30074) 76834s; run: log: (pid 29740) 76844s
run: logrotate: (pid 30925) 3041s; run: log: (pid 29649) 76861s
run: node-exporter: (pid 30093) 76833s; run: log: (pid 29663) 76855s

구성 요소 설정으로 돌아가기

PostgreSQL 구성#

이 섹션에서는 GitLab과 함께 사용할 고가용성 PostgreSQL 클러스터 구성 방법을 안내합니다.

직접 PostgreSQL 인스턴스 제공#

Linux 패키지에 번들된 PostgreSQL, PgBouncer, Consul 서비스 디스커버리 구성 요소 대신, PostgreSQL용 타사 외부 서비스를 사용할 수 있습니다.

지원되는 PostgreSQL 버전을 실행하는 신뢰할 수 있는 공급자를 사용하세요. 다음 서비스가 잘 작동하는 것으로 알려져 있습니다:

고가용성 및 데이터베이스 로드 밸런싱에 대한 지침을 포함한 자세한 내용은 다음을 참조하세요:

서드 파티 외부 서비스를 사용하는 경우:

Linux 패키지를 사용한 독립형 PostgreSQL#

복제(replication) 및 장애 조치(failover)를 갖춘 PostgreSQL 클러스터에 권장되는 Linux 패키지 구성에는 다음이 필요합니다:

최소 세 개의 PostgreSQL 노드.

최소 세 개의 Consul 서버 노드.

기본 데이터베이스 읽기 및 쓰기를 추적하고 처리하는 최소 세 개의 PgBouncer 노드.

PgBouncer 노드 간 요청을 분산하는 내부 로드 밸런서(TCP).

데이터베이스 로드 밸런싱 활성화.

각 PostgreSQL 노드에 구성할 로컬 PgBouncer 서비스. 이는 기본(primary)을 추적하는 메인 PgBouncer 클러스터와는 별도입니다.

다음 IP는 예시로 사용됩니다:

  • 10.6.0.21: PostgreSQL primary

  • 10.6.0.22: PostgreSQL secondary 1

  • 10.6.0.23: PostgreSQL secondary 2

먼저 각 노드에 Linux 패키지를 설치해야 합니다. GitLab 패키지 리포지터리를 추가하고 선택한 운영 체제에 맞는 GitLab을 설치하되, EXTERNAL_URL 값은 지정하지 않습니다.

PostgreSQL 노드#

PostgreSQL 노드 중 하나에 SSH로 접속합니다.

PostgreSQL 사용자 이름/비밀번호 쌍의 비밀번호 해시를 생성합니다. 기본 사용자 이름인 gitlab을 사용한다고 가정합니다(권장). 명령 실행 시 비밀번호와 확인을 입력하라는 메시지가 표시됩니다. 이 명령의 출력 값을 다음 단계에서 <postgresql_password_hash> 값으로 사용합니다:

sudo gitlab-ctl pg-password-md5 gitlab

PgBouncer 사용자 이름/비밀번호 쌍의 비밀번호 해시를 생성합니다. 기본 사용자 이름인 pgbouncer를 사용한다고 가정합니다(권장). 명령 실행 시 비밀번호와 확인을 입력하라는 메시지가 표시됩니다. 이 명령의 출력 값을 다음 단계에서 <pgbouncer_password_hash> 값으로 사용합니다:

sudo gitlab-ctl pg-password-md5 pgbouncer

PostgreSQL 복제 사용자 이름/비밀번호 쌍의 비밀번호 해시를 생성합니다. 기본 사용자 이름인 gitlab_replicator를 사용한다고 가정합니다(권장). 명령 실행 시 비밀번호와 확인을 입력하라는 메시지가 표시됩니다. 이 명령의 출력 값을 다음 단계에서 <postgresql_replication_password_hash> 값으로 사용합니다:

sudo gitlab-ctl pg-password-md5 gitlab_replicator

Consul 데이터베이스 사용자 이름/비밀번호 쌍의 비밀번호 해시를 생성합니다. 기본 사용자 이름인 gitlab-consul을 사용한다고 가정합니다(권장). 명령 실행 시 비밀번호와 확인을 입력하라는 메시지가 표시됩니다. 이 명령의 출력 값을 다음 단계에서 <consul_password_hash> 값으로 사용합니다:

sudo gitlab-ctl pg-password-md5 gitlab-consul

모든 데이터베이스 노드에서 /etc/gitlab/gitlab.rb를 편집하여 # START user configuration 섹션에 표시된 값을 교체합니다:

# Disable all components except Patroni, PgBouncer and Consul
roles(['patroni_role', 'pgbouncer_role'])

# PostgreSQL configuration
postgresql['listen_address'] = '0.0.0.0'

# Sets `max_replication_slots` to double the number of database nodes.
# Patroni uses one extra slot per node when initiating the replication.
patroni['postgresql']['max_replication_slots'] = 6

# Set `max_wal_senders` to one more than the number of replication slots in the cluster.
# This is used to prevent replication from using up all of the
# available database connections.
patroni['postgresql']['max_wal_senders'] = 7

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

# Configure the Consul agent
consul['services'] = %w(postgresql)
## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

# START user configuration
# Please set the real values as explained in Required Information section
#
# Replace PGBOUNCER_PASSWORD_HASH with a generated md5 value
postgresql['pgbouncer_user_password'] = '<pgbouncer_password_hash>'
# Replace POSTGRESQL_REPLICATION_PASSWORD_HASH with a generated md5 value
postgresql['sql_replication_password'] = '<postgresql_replication_password_hash>'
# Replace POSTGRESQL_PASSWORD_HASH with a generated md5 value
postgresql['sql_user_password'] = '<postgresql_password_hash>'

# Set up basic authentication for the Patroni API (use the same username/password in all nodes).
patroni['username'] = '<patroni_api_username>'
patroni['password'] = '<patroni_api_password>'

# Replace 10.6.0.0/24 with Network Address
postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/24 127.0.0.1/32)

# Local PgBouncer service for Database Load Balancing
pgbouncer['databases'] = {
   gitlabhq_production: {
      host: "127.0.0.1",
      user: "pgbouncer",
      password: '<pgbouncer_password_hash>'
   }
}

# Set the network addresses that the exporters will listen on for monitoring
node_exporter['listen_address'] = '0.0.0.0:9100'
postgres_exporter['listen_address'] = '0.0.0.0:9187'

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}
#
# END user configuration

Patroni가 장애 조치를 관리하는 PostgreSQL은 기본적으로 pg_rewind를 사용하여 충돌을 처리합니다. 대부분의 장애 조치 처리 방법과 마찬가지로, 이 방법은 데이터 손실로 이어질 가능성이 낮지만 존재합니다. 자세한 내용은 다양한 Patroni 복제 방법을 참조하세요.

  • 처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하고, 이 서버에서 동일한 이름의 파일을 추가하거나 교체합니다. 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

  • 변경 사항을 적용하려면 GitLab을 재구성합니다.

고급 구성 옵션을 지원하며 필요한 경우 추가할 수 있습니다.

구성 요소 설정으로 돌아가기

PostgreSQL 사후 구성#

기본 사이트의 Patroni 노드 중 하나에 SSH로 접속합니다:

리더 및 클러스터 상태를 확인합니다:

gitlab-ctl patroni members

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

| Cluster       | Member                            |  Host     | Role   | State   | TL  | Lag in MB | Pending restart |
|---------------|-----------------------------------|-----------|--------|---------|-----|-----------|-----------------|
| postgresql-ha |      | 10.6.0.21 | Leader | running | 175 |           | *               |
| postgresql-ha |  | 10.6.0.22 |        | running | 175 | 0         | *               |
| postgresql-ha |  | 10.6.0.23 |        | running | 175 | 0         | *               |

노드의 ‘State’ 칼럼이 “running”으로 표시되지 않는 경우, 계속 진행하기 전에 PostgreSQL 복제 및 장애 조치 트러블슈팅 섹션을 확인하세요.

구성 요소 설정으로 돌아가기

PgBouncer 구성#

이제 PostgreSQL 서버가 모두 설정되었으므로, 기본 데이터베이스에 대한 읽기/쓰기를 추적하고 처리하기 위해 PgBouncer를 구성해 보겠습니다.

PgBouncer는 단일 스레드이므로 CPU 코어 수를 늘려도 성능이 크게 향상되지 않습니다.

자세한 내용은 스케일링 문서를 참조하세요.

예시로 다음 IP를 사용합니다:

  • 10.6.0.31: PgBouncer 1

  • 10.6.0.32: PgBouncer 2

  • 10.6.0.33: PgBouncer 3

각 PgBouncer 노드에서 /etc/gitlab/gitlab.rb를 편집하고, <consul_password_hash><pgbouncer_password_hash>이전에 설정한 비밀번호 해시로 교체합니다:

# Disable all components except Pgbouncer and Consul agent
roles(['pgbouncer_role'])

# Configure PgBouncer
pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
pgbouncer['users'] = {
   'gitlab-consul': {
      password: '<consul_password_hash>'
   },
   'pgbouncer': {
      password: '<pgbouncer_password_hash>'
   }
}

# Configure Consul agent
consul['watchers'] = %w(postgresql)
consul['configuration'] = {
retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
}

# Enable service discovery for Prometheus
consul['monitoring_service_discovery'] = true

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하고, 이 서버에서 동일한 이름의 파일을 추가하거나 교체합니다. 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

변경 사항을 적용하려면 GitLab을 재구성합니다.

execute[generate databases.ini] 오류가 발생하면, 이는 기존의 알려진 이슈로 인한 것입니다. 다음 단계 이후 두 번째 reconfigure를 실행하면 해결됩니다.

Consul이 PgBouncer를 다시 로드할 수 있도록 .pgpass 파일을 만듭니다. 요청 시 PgBouncer 비밀번호를 두 번 입력합니다:

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

이전 단계에서 발생할 수 있는 오류를 해결하기 위해 GitLab을 다시 재구성합니다.

각 노드가 현재 Primary와 통신하고 있는지 확인합니다:

gitlab-ctl pgb-console # You will be prompted for PGBOUNCER_PASSWORD

콘솔 프롬프트가 나타나면 다음 쿼리를 실행합니다:

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)

구성 요소 설정으로 돌아가기

Redis 구성#

확장 가능한 환경에서 Redis를 사용하는 경우, 장애 조치 절차를 감시하고 자동으로 시작하는 Redis Sentinel 서비스와 함께 Primary x Replica 토폴로지를 사용할 수 있습니다.

  • Redis 클러스터는 각각 3개 이상의 홀수 노드로 배포해야 합니다. 이는 Redis Sentinel이 쿼럼의 일부로 투표를 진행할 수 있도록 하기 위함입니다. 이 규칙은 클라우드 제공업체 서비스와 같이 Redis를 외부에서 구성하는 경우에는 적용되지 않습니다.

  • Redis는 기본적으로 단일 스레드이며 CPU 코어 수를 늘려도 성능이 크게 향상되지 않습니다. 이 규모의 아키텍처에서는 최적의 성능을 달성하기 위해 명시된 대로 별도의 캐시(Cache) 및 영구(Persistent) 인스턴스를 사용하는 것을 강력히 권장합니다. 자세한 내용은 스케일링 문서를 참조하세요.

    Redis는 Sentinel과 함께 사용할 경우 인증이 필요합니다. 자세한 내용은 Redis 보안 문서를 참조하세요. Redis 비밀번호와 엄격한 방화벽 규칙을 조합하여 Redis 서비스를 보호하는 것을 권장합니다. 토폴로지와 아키텍처를 완전히 이해하기 위해 GitLab에서 Redis를 구성하기 전에 Redis Sentinel 문서를 읽어 보실 것을 강력히 권장합니다.

Redis 설정의 요구 사항은 다음과 같습니다:

  • 모든 Redis 노드는 서로 통신할 수 있어야 하며, Redis(6379) 및 Sentinel(26379) 포트에서 수신 연결을 허용해야 합니다(기본값을 변경하지 않는 경우).

  • GitLab 애플리케이션을 호스팅하는 서버는 Redis 노드에 접근할 수 있어야 합니다.

  • 방화벽을 사용하여 외부 네트워크(인터넷)에서 노드에 접근하지 못하도록 보호합니다.

이 섹션에서는 GitLab과 함께 사용할 두 개의 외부 Redis 클러스터를 구성하는 방법을 안내합니다. 다음 IP가 예시로 사용됩니다:

  • 10.6.0.51: Redis - 캐시 Primary

  • 10.6.0.52: Redis - 캐시 Replica 1

  • 10.6.0.53: Redis - 캐시 Replica 2

  • 10.6.0.61: Redis - 영구 Primary

  • 10.6.0.62: Redis - 영구 Replica 1

  • 10.6.0.63: Redis - 영구 Replica 2

자체 Redis 인스턴스 제공#

다음 지침을 참고하여 Redis 캐시 및 영구 인스턴스에 타사 외부 서비스를 선택적으로 사용할 수 있습니다:

  • 신뢰할 수 있는 제공업체 또는 솔루션을 사용해야 합니다. Google MemorystoreAWS ElastiCache는 정상 작동하는 것으로 알려져 있습니다.

  • Redis 클러스터 모드는 특별히 지원되지 않으며, HA가 있는 Redis Standalone은 지원됩니다.

  • 설정에 따라 Redis 제거 정책을 설정해야 합니다.

자세한 내용은 인프라 및 서비스를 참조하세요.

Redis 캐시 클러스터 구성#

이 섹션에서는 새 Redis 캐시 인스턴스를 설치하고 설정합니다.

Primary와 Replica Redis 노드 모두 redis['password']에 동일한 비밀번호가 정의되어 있어야 합니다. 장애 조치 중 언제든지 Sentinel은 노드를 재구성하고 해당 노드의 상태를 Primary에서 Replica로(또는 그 반대로) 변경할 수 있습니다.

Primary Redis 캐시 노드 구성#

Primary Redis 서버에 SSH로 접속합니다.

원하는 Linux 패키지를 다운로드하고 설치합니다. GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 합니다.

선택한 운영 체제용 패키지를 설치합니다. 현재 설치 버전과 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택하세요.

/etc/gitlab/gitlab.rb 파일을 편집하고 다음 내용을 추가합니다:

# Specify server role as 'redis_sentinel_role' 'redis_master_role'
roles ['redis_sentinel_role', 'redis_master_role', 'consul_role']

# Set IP bind address and Quorum number for Redis Sentinel service
sentinel['bind'] = '0.0.0.0'
sentinel['quorum'] = 2

# IP address pointing to a local IP that the other machines can reach.
# You can also set bind to '0.0.0.0' which listen in all interfaces.
# If you really must bind to an external accessible IP, make
# sure you add extra firewall rules to prevent unauthorized access.
redis['bind'] = '10.6.0.51'

# Define a port so Redis can listen for TCP requests which will allow other
# machines to connect to it.
redis['port'] = 6379

# Port of primary Redis server for Sentinel, uncomment to change to non default.
# Defaults to `6379`.
# redis['master_port'] = 6379

# Set up password authentication for Redis (use the same password in all nodes).
redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_FIRST_CLUSTER'

# Must be the same in every Redis node.
redis['master_name'] = 'gitlab-redis-cache'

# The IP of this primary Redis node.
redis['master_ip'] = '10.6.0.51'

# Set the Redis Cache instance as an LRU
# 90% of available RAM in MB
redis['maxmemory'] = '13500mb'
redis['maxmemory_policy'] = "allkeys-lru"
redis['maxmemory_samples'] = 5

## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'
redis_exporter['listen_address'] = '0.0.0.0:9121'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체합니다. 이 노드가 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

변경 사항을 적용하려면 GitLab을 재구성하세요.

복제본 Redis 캐시 노드 구성#

복제본 Redis 서버에 SSH로 접속합니다.

원하는 Linux 패키지를 다운로드하고 설치합니다. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제용 GitLab을 설치해야 합니다. 현재 설치 버전과 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택하세요.

/etc/gitlab/gitlab.rb 파일을 편집하고 이전 섹션의 기본 노드와 동일한 내용을 추가하되, redis_master_noderedis_replica_node로 대체합니다:

# Specify server role as 'redis_replica_role' and enable Consul agent
roles ['redis_sentinel_role', 'redis_replica_role', 'consul_role']

# Set IP bind address and Quorum number for Redis Sentinel service
sentinel['bind'] = `0.0.0.0`
sentinel['quorum'] = 2

# IP address pointing to a local IP that the other machines can reach.
# Set bind to '0.0.0.0' to listen on all interfaces.
# If you really must bind to an external accessible IP, make
# sure you add extra firewall rules to prevent unauthorized access.
redis['bind'] = '10.6.0.52'

# Define a port so Redis can listen for TCP requests which will allow other
# machines to connect to it.
redis['port'] = 6379

## Port of primary Redis server for Sentinel, uncomment to change to non default. Defaults
## to `6379`.
#redis['master_port'] = 6379

# Set up password authentication for Redis and replicas (use the same password in all nodes).
redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_FIRST_CLUSTER'

# Must be the same in every Redis node
redis['master_name'] = 'gitlab-redis-cache'

# The IP of the primary Redis node.
redis['master_ip'] = '10.6.0.51'

# Set the Redis Cache instance as an LRU
# 90% of available RAM in MB
redis['maxmemory'] = '13500mb'
redis['maxmemory_policy'] = "allkeys-lru"
redis['maxmemory_samples'] = 5

## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'
redis_exporter['listen_address'] = '0.0.0.0:9121'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하세요. 이 서버가 처음 구성하는 Linux 패키지 노드인 경우 이 단계를 건너뛸 수 있습니다.

변경 사항이 적용되도록 GitLab을 재구성하세요.

나머지 모든 복제본 노드에 대해 동일한 단계를 반복하고, IP가 올바르게 설정되어 있는지 확인하세요.

고급 구성 옵션이 지원되며 필요에 따라 추가할 수 있습니다.

구성 요소 설정으로 돌아가기

Redis Persistent 클러스터 구성#

이 섹션에서는 새로운 Redis Persistent 인스턴스를 설치하고 설정합니다.

기본 Redis 노드와 복제본 Redis 노드 모두 redis['password']에 동일한 비밀번호를 정의해야 합니다. 페일오버가 발생하면 언제든지 Sentinel이 노드를 재구성하여 기본(primary)에서 복제본(replica)으로 상태를 변경할 수 있습니다(반대의 경우도 마찬가지).

기본 Redis Persistent 노드 구성#

기본(Primary) Redis 서버에 SSH로 접속하세요.

원하는 Linux 패키지를 다운로드하여 설치하세요. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제에 GitLab을 설치하세요. 현재 설치와 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택하세요.

/etc/gitlab/gitlab.rb를 편집하고 다음 내용을 추가하세요:

# Specify server roles as 'redis_sentinel_role' and 'redis_master_role'
roles ['redis_sentinel_role', 'redis_master_role', 'consul_role']

# Set IP bind address and Quorum number for Redis Sentinel service
sentinel['bind'] = '0.0.0.0'
sentinel['quorum'] = 2

# IP address pointing to a local IP that the other machines can reach to.
# You can also set bind to '0.0.0.0' which listen in all interfaces.
# If you really must bind to an external accessible IP, make
# sure you add extra firewall rules to prevent unauthorized access.
redis['bind'] = '10.6.0.61'

# Define a port so Redis can listen for TCP requests which will allow other
# machines to connect to it.
redis['port'] = 6379

## Port of primary Redis server for Sentinel, uncomment to change to non default. Defaults
## to `6379`.
#redis['master_port'] = 6379

# Set up password authentication for Redis and replicas (use the same password in all nodes).
redis['password'] = 'REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER'
redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER'

## Must be the same in every Redis node
redis['master_name'] = 'gitlab-redis-persistent'

## The IP of this primary Redis node.
redis['master_ip'] = '10.6.0.61'

## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'
redis_exporter['listen_address'] = '0.0.0.0:9121'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하세요. 이 서버가 처음 구성하는 Linux 패키지 노드인 경우 이 단계를 건너뛸 수 있습니다.

변경 사항이 적용되도록 GitLab을 재구성하세요.

복제본 Redis Persistent 노드 구성#

복제본(replica) Redis Persistent 서버에 SSH로 접속하세요.

원하는 Linux 패키지를 다운로드하여 설치하세요. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제에 GitLab을 설치하세요. 현재 설치와 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택하세요.

/etc/gitlab/gitlab.rb를 편집하고 다음 내용을 추가하세요:

# Specify server role as 'redis_replica_role' and enable Consul agent
roles ['redis_sentinel_role', 'redis_replica_role', 'consul_role']

# Set IP bind address and Quorum number for Redis Sentinel service
sentinel['bind'] = '0.0.0.0'
sentinel['quorum'] = 2

# IP address pointing to a local IP that the other machines can reach to.
# You can also set bind to '0.0.0.0' which listen in all interfaces.
# If you really must bind to an external accessible IP, make
# sure you add extra firewall rules to prevent unauthorized access.
redis['bind'] = '10.6.0.62'

# Define a port so Redis can listen for TCP requests which will allow other
# machines to connect to it.
redis['port'] = 6379

## Port of primary Redis server for Sentinel, uncomment to change to non default. Defaults
## to `6379`.
#redis['master_port'] = 6379

# The same password for Redis authentication you set up for the primary node.
redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER'

## Must be the same in every Redis node
redis['master_name'] = 'gitlab-redis-persistent'

# The IP of the primary Redis node.
redis['master_ip'] = '10.6.0.61'

## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'
redis_exporter['listen_address'] = '0.0.0.0:9121'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하십시오. 이 서버가 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

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

다른 모든 복제본 노드에 대해 단계를 반복하고, IP가 올바르게 설정되어 있는지 확인하십시오.

고급 구성 옵션이 지원되며 필요에 따라 추가할 수 있습니다.

구성 요소 설정으로 돌아가기

Gitaly Cluster (Praefect) 구성#

Gitaly Cluster (Praefect)는 GitLab이 제공하고 권장하는 Git 리포지터리 저장을 위한 내결함성 솔루션입니다. 이 구성에서 모든 Git 리포지터리는 클러스터의 모든 Gitaly 노드에 저장되며, 그 중 하나가 기본(primary)으로 지정되고, 기본 노드가 다운되면 자동으로 장애 조치(failover)가 수행됩니다.

Gitaly 사양은 정상 상태의 사용 패턴과 리포지터리 크기의 높은 백분위수를 기반으로 합니다.

그러나 대형 모노리포(수 기가바이트 이상) 또는 추가 워크로드가 있는 경우, 이는 환경의 성능에 상당한 영향을 미칠 수 있으며 추가 조정이 필요할 수 있습니다. 해당 사항이 있다고 판단되면 필요에 따라 추가 지침을 위해 문의하십시오.

Gitaly Cluster (Praefect)는 내결함성의 이점을 제공하지만, 설정과 관리의 복잡성이 추가됩니다. Gitaly Cluster (Praefect) 배포 전 기술적 제한 사항 및 고려 사항을 검토하십시오.

다음에 대한 지침은 아래를 참고하십시오:

권장 클러스터 설정에는 다음 구성 요소가 포함됩니다:

  • Gitaly 노드 3개: Git 리포지터리의 복제 스토리지.

  • Praefect 노드 3개: Gitaly Cluster (Praefect)의 라우터 및 트랜잭션 관리자.

  • Praefect PostgreSQL 노드 1개: Praefect용 데이터베이스 서버. Praefect 데이터베이스 연결의 고가용성을 위해 서드파티 솔루션이 필요합니다.

  • 로드 밸런싱: Praefect 노드에 대한 트래픽의 균등 분산. 대부분의 설정에 권장되는 TCP 로드 밸런서 또는 고급 구성을 위한 서비스 디스커버리 DNS를 사용할 수 있습니다. 자세한 내용은 Praefect의 로드 밸런싱을 참조하십시오.

이 섹션에서는 권장 표준 설정을 순서대로 구성하는 방법을 설명합니다. 더 고급 설정은 독립형 Gitaly Cluster (Praefect) 문서를 참조하십시오.

Praefect의 로드 밸런싱#

TCP 로드 밸런서 또는 서비스 디스커버리 DNS를 사용하여 Praefect 노드에 트래픽을 분산할 수 있습니다. TCP 로드 밸런서는 모든 배포 시나리오에서 작동하므로 대부분의 설정에 권장됩니다.

TCP 로드 밸런서#

기존 TCP 로드 밸런서(예: HAProxy 또는 AWS ELB)는 Praefect 노드에 트래픽을 분산합니다. 이 방식은:

  • 모든 배포 시나리오(Omnibus, Cloud Native Hybrid)에서 작동합니다

  • 간단한 설정 및 운영 관리를 제공합니다

  • TLS 및 비TLS 구성을 모두 지원합니다

  • 연결이 특정 노드에 몰릴 수 있어 불균등한 트래픽 분산이 발생할 수 있습니다

  • 노드 재시작 후 트래픽 재분산에 시간이 더 걸릴 수 있습니다

구성 지침은 로드 밸런서를 참조하십시오.

서비스 디스커버리 DNS#

서비스 디스커버리는 DNS를 사용하여 Praefect 노드 주소를 검색하며, 클라이언트가 사용 가능한 모든 노드에 걸쳐 요청을 균등하게 분산할 수 있도록 합니다. 이 방식은:

  • 모든 Praefect 노드에 트래픽을 균등하게 분산합니다

  • 노드가 추가되거나 재시작될 때 트래픽을 자동으로 재분산합니다

  • DNS 인프라(예: Consul, CoreDNS 또는 유사한 도구)가 필요합니다

  • TLS 사용 시 GitLab 18.9 이상이 필요합니다

  • Linux 패키지(Omnibus) 설치에서만 사용 가능합니다

구성 지침은 서비스 디스커버리를 참조하십시오.

Praefect PostgreSQL 구성#

Gitaly Cluster (Praefect)의 라우팅 및 트랜잭션 관리자인 Praefect는 Gitaly Cluster (Praefect) 상태 데이터를 저장하기 위한 자체 데이터베이스 서버가 필요합니다.

고가용성 설정을 원하는 경우, Praefect는 서드파티 PostgreSQL 데이터베이스가 필요합니다. 내장 솔루션은 현재 개발 중입니다.

Linux 패키지를 사용한 Praefect 비-HA PostgreSQL 독립형#

다음 IP는 예시로 사용됩니다:

  • 10.6.0.141: Praefect PostgreSQL

먼저 Praefect PostgreSQL 노드에 Linux 패키지를 설치하십시오. 선택한 운영 체제에 맞는 GitLab 패키지 리포지터리를 추가하고 GitLab을 설치하되, EXTERNAL_URL 값은 제공하지 마십시오.

Praefect PostgreSQL 노드에 SSH로 접속합니다.

Praefect PostgreSQL 사용자에 사용할 강력한 비밀번호를 생성합니다. 이 비밀번호를 <praefect_postgresql_password>로 기록해 두십시오.

Praefect PostgreSQL 사용자 이름/비밀번호 쌍의 비밀번호 해시를 생성합니다. 여기서는 기본 사용자 이름인 praefect를 사용한다고 가정합니다(권장). 이 명령은 비밀번호 <praefect_postgresql_password>와 확인을 요청합니다. 다음 단계에서 <praefect_postgresql_password_hash> 값으로 이 명령의 출력값을 사용하세요:

sudo gitlab-ctl pg-password-md5 praefect

/etc/gitlab/gitlab.rb를 편집하여 # START user configuration 섹션에 명시된 값을 교체합니다:

# Disable all components except PostgreSQL and Consul
roles(['postgres_role', 'consul_role'])

# PostgreSQL configuration
postgresql['listen_address'] = '0.0.0.0'

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

# Configure the Consul agent
## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true

# START user configuration
# Please set the real values as explained in Required Information section
#
# Replace PRAEFECT_POSTGRESQL_PASSWORD_HASH with a generated md5 value
postgresql['sql_user_password'] = "<praefect_postgresql_password_hash>"

# Replace XXX.XXX.XXX.XXX/YY with Network Address
postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/24 127.0.0.1/32)

# Set the network addresses that the exporters will listen on for monitoring
node_exporter['listen_address'] = '0.0.0.0:9100'
postgres_exporter['listen_address'] = '0.0.0.0:9187'

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}
#
# END user configuration

첫 번째로 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체합니다. 이 서버가 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛰어도 됩니다.

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

사후 구성을 따릅니다.

구성 요소 설정으로 돌아가기

Praefect HA PostgreSQL 서드파티 솔루션#

앞서 언급했듯이, 완전한 고가용성을 목표로 한다면 Praefect 데이터베이스에 서드파티 PostgreSQL 솔루션을 사용하는 것이 권장됩니다.

PostgreSQL HA를 위한 서드파티 솔루션은 다양합니다. 선택한 솔루션은 Praefect와 함께 작동하기 위해 다음 조건을 갖춰야 합니다:

  • 페일오버 시에도 변경되지 않는 모든 연결에 대한 정적 IP.

  • LISTEN SQL 기능이 지원되어야 합니다.

    서드파티 설정을 사용하면, 복제를 올바르게 처리하기 위해 별도의 데이터베이스 인스턴스가 필요한 Geo를 사용하는 경우가 아니라면, Praefect의 데이터베이스를 편의상 기본 GitLab 데이터베이스와 동일한 서버에 함께 배치할 수 있습니다. 이 설정에서는 영향이 최소화되므로 기본 데이터베이스 설정의 사양을 변경할 필요가 없습니다.

    이를 위해 신뢰할 수 있는 제공업체나 솔루션을 사용해야 합니다. Google Cloud SQLAmazon RDS는 작동이 확인되어 있습니다. 그러나 Amazon Aurora는 14.4.0부터 기본적으로 활성화된 로드 밸런싱과 호환되지 않습니다.

자세한 내용은 인프라 및 서비스를 참조하세요.

데이터베이스 설정이 완료되면 사후 구성을 따릅니다.

Praefect PostgreSQL 사후 구성#

Praefect PostgreSQL 서버 설정이 완료된 후, Praefect가 사용할 사용자와 데이터베이스를 구성해야 합니다.

사용자 이름은 praefect, 데이터베이스 이름은 praefect_production으로 지정하는 것을 권장하며, 이는 PostgreSQL에서 표준적인 방법으로 구성할 수 있습니다. 사용자의 비밀번호는 이전에 <praefect_postgresql_password>로 구성한 비밀번호와 동일합니다.

Linux 패키지 PostgreSQL 설정에서의 적용 방법은 다음과 같습니다:

Praefect PostgreSQL 노드에 SSH로 접속합니다.

관리자 권한으로 PostgreSQL 서버에 연결합니다. gitlab-psql 사용자는 Linux 패키지에서 기본으로 추가되므로 여기서 사용합니다. template1 데이터베이스는 모든 PostgreSQL 서버에 기본으로 생성되므로 사용합니다.

/opt/gitlab/embedded/bin/psql -U gitlab-psql -d template1 -h POSTGRESQL_SERVER_ADDRESS

<praefect_postgresql_password>를 교체하여 새 사용자 praefect를 생성합니다:

CREATE ROLE praefect WITH LOGIN CREATEDB PASSWORD '<praefect_postgresql_password>';

이번에는 praefect 사용자로 PostgreSQL 서버에 재접속합니다:

/opt/gitlab/embedded/bin/psql -U praefect -d template1 -h POSTGRESQL_SERVER_ADDRESS

새 데이터베이스 praefect_production을 생성합니다:

CREATE DATABASE praefect_production WITH ENCODING=UTF8;

컴포넌트 설정으로 돌아가기

Praefect 구성#

Praefect는 Gitaly Cluster(Praefect)의 라우터이자 트랜잭션 매니저로, Gitaly로의 모든 연결은 이를 통해 이루어집니다. 이 섹션에서는 Praefect 구성 방법을 설명합니다.

Praefect는 3개 이상의 홀수 노드로 배포해야 합니다. 이는 노드들이 쿼럼의 일부로 투표할 수 있도록 하기 위함입니다.

Praefect는 클러스터 전반의 통신을 보호하기 위해 여러 시크릿 토큰이 필요합니다:

  • <praefect_external_token>: Gitaly Cluster(Praefect)에 호스팅된 리포지터리에 사용되며, 이 토큰을 가진 Gitaly 클라이언트만 접근할 수 있습니다.

  • <praefect_internal_token>: Gitaly Cluster(Praefect) 내부의 복제 트래픽에 사용됩니다. praefect_external_token과 구분되는 이유는 Gitaly 클라이언트가 Gitaly Cluster(Praefect)의 내부 노드에 직접 접근할 수 없어야 하기 때문입니다. 직접 접근 시 데이터 손실이 발생할 수 있습니다.

  • <praefect_postgresql_password>: 이전 섹션에서 정의한 Praefect PostgreSQL 비밀번호도 이 설정의 일부로 필요합니다.

Gitaly Cluster(Praefect) 노드는 Praefect에서 virtual storage로 구성됩니다. 각 스토리지에는 클러스터를 구성하는 각 Gitaly 노드의 세부 정보가 포함됩니다. 각 스토리지에는 이름이 부여되며, 이 이름은 구성의 여러 영역에서 사용됩니다. 이 가이드에서 스토리지 이름은 default입니다. 또한 이 가이드는 신규 설치를 기준으로 작성되었으므로, 기존 환경을 Gitaly Cluster(Praefect)를 사용하도록 업그레이드하는 경우 다른 이름을 사용해야 할 수 있습니다. 자세한 내용은 Praefect 문서를 참조하세요.

다음 IP 주소를 예시로 사용합니다:

  • 10.6.0.131: Praefect 1

  • 10.6.0.132: Praefect 2

  • 10.6.0.133: Praefect 3

각 Praefect 노드를 구성하려면 다음 단계를 수행합니다:

Praefect 서버에 SSH로 접속합니다.

원하는 Linux 패키지를 다운로드하여 설치합니다. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제에 GitLab을 설치해야 합니다.

/etc/gitlab/gitlab.rb 파일을 편집하여 Praefect를 구성합니다:

[GitLab에서 기본 리포지터리 스토리지가 필요하므로](/19.2/administration/gitaly/configure_gitaly/#gitlab-requires-a-default-repository-storage) `virtual_storages`에서 `default` 항목을 제거할 수 없습니다.
  • All reference architecture pages -->
# Avoid running unnecessary services on the Praefect server
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 Configuration
praefect['enable'] = true

# Prevent database migrations from running on upgrade automatically
praefect['auto_migrate'] = false
gitlab_rails['auto_migrate'] = false

# Configure the Consul agent
consul['enable'] = true
## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] = true

# START user configuration
# Please set the real values as explained in Required Information section
#

praefect['configuration'] = {
   # ...
   listen_addr: '0.0.0.0:2305',
   auth: {
      # ...
      #
      # Praefect External Token
      # This is needed by clients outside the cluster (like GitLab Shell) to communicate with the Praefect cluster
      token: '<praefect_external_token>',
   },
   # Praefect Database Settings
   database: {
      # ...
      host: '10.6.0.141',
      port: 5432,
      dbname: 'praefect_production',
      user: 'praefect',
      password: '<praefect_postgresql_password>',
   },
   # Praefect Virtual Storage config
   # Name of storage hash must match storage name in gitlab_rails['repositories_storages'] on GitLab
   # server ('praefect') and in gitaly['configuration'][:storage] on Gitaly nodes ('gitaly-1')
   virtual_storage: [
      {
         # ...
         name: 'default',
         node: [
            {
               storage: 'gitaly-1',
               address: 'tcp://10.6.0.91:8075',
               token: '<praefect_internal_token>'
            },
            {
               storage: 'gitaly-2',
               address: 'tcp://10.6.0.92:8075',
               token: '<praefect_internal_token>'
            },
            {
               storage: 'gitaly-3',
               address: 'tcp://10.6.0.93:8075',
               token: '<praefect_internal_token>'
            },
         ],
      },
   ],
   # Set the network address Praefect will listen on for monitoring
   prometheus_listen_addr: '0.0.0.0:9652',
}

# Set the network address the node exporter will listen on for monitoring
node_exporter['listen_address'] = '0.0.0.0:9100'

## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}
#
# END user configuration

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버에 동일한 이름의 파일을 추가하거나 교체하세요. 처음으로 Linux 패키지 노드를 구성하는 경우라면 이 단계를 건너뛸 수 있습니다.

Praefect는 메인 GitLab 애플리케이션과 마찬가지로 일부 데이터베이스 마이그레이션을 실행해야 합니다. 이를 위해 마이그레이션을 실행할 Praefect 노드 하나만 선택해야 하며, 이를 Deploy Node라고 합니다. 이 노드는 다음과 같이 다른 노드들보다 먼저 구성해야 합니다:

/etc/gitlab/gitlab.rb 파일에서 praefect['auto_migrate'] 설정 값을 false에서 true로 변경하세요.

데이터베이스 마이그레이션이 reconfigure 시에만 실행되고 업그레이드 시 자동으로 실행되지 않도록 하려면 다음을 실행하세요:

sudo touch /etc/gitlab/skip-auto-reconfigure
  • 변경 사항을 적용하고 Praefect 데이터베이스 마이그레이션을 실행하려면 GitLab을 reconfigure하세요.

다른 모든 Praefect 노드에서 변경 사항을 적용하려면 GitLab을 reconfigure하세요.

Gitaly 구성#

클러스터를 구성하는 Gitaly 서버 노드는 데이터와 부하에 따라 달라지는 요구 사항이 있습니다.

Gitaly 사양은 사용 패턴과 정상 상태의 리포지터리 크기의 상위 백분위수를 기반으로 합니다.

그러나 대규모 모노레포(수 기가바이트 이상) 또는 추가 워크로드가 있는 경우, 환경 성능에 큰 영향을 미칠 수 있으며 추가 조정이 필요할 수 있습니다. 해당하는 경우 필요한 추가 안내를 위해 저희에게 문의하세요.

Gitaly는 Gitaly 스토리지에 대한 특정 디스크 요구 사항이 있습니다.

Gitaly의 네트워크 트래픽은 기본적으로 암호화되지 않으므로 Gitaly 서버는 공용 인터넷에 노출되어서는 안 됩니다. Gitaly 서버에 대한 접근을 제한하기 위해 방화벽 사용을 강력히 권장합니다. 또 다른 옵션으로 TLS 사용이 있습니다.

Gitaly를 구성할 때 다음 사항에 유의하세요:

  • gitaly['configuration'][:storage]는 특정 Gitaly 노드의 스토리지 경로를 반영하도록 구성해야 합니다.

  • auth_tokenpraefect_internal_token과 동일해야 합니다.

다음 IP는 예시로 사용됩니다:

  • 10.6.0.91: Gitaly 1

  • 10.6.0.92: Gitaly 2

  • 10.6.0.93: Gitaly 3

각 노드에서:

원하는 Linux 패키지를 다운로드하고 설치하세요. 선택한 운영 체제에 맞는 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치하되, EXTERNAL_URL 값은 제공하지 마세요.

Gitaly 서버 노드의 /etc/gitlab/gitlab.rb 파일을 편집하여 스토리지 경로를 구성하고, 네트워크 리스너를 활성화하며, 토큰을 구성하세요:

  • 모든 레퍼런스 아키텍처 페이지 -->
# https://docs.gitlab.com/omnibus/roles/#gitaly-roles
roles(["gitaly_role"])

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

# Configure the gitlab-shell API callback URL. Without this, `git push` will
# fail. This can be your 'front door' GitLab URL or an internal load
# balancer.
gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'

# Configure the Consul agent
consul['enable'] = true
## Enable service discovery for Prometheus
consul['monitoring_service_discovery'] = true

# START user configuration
# Please set the real values as explained in Required Information section
#
## The IPs of the Consul server nodes
## You can also use FQDNs and intermix them with IPs
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
}

# Set the network address that the node exporter will listen on for monitoring
node_exporter['listen_address'] = '0.0.0.0:9100'

gitaly['configuration'] = {
   # Make Gitaly accept connections on all network interfaces. You must use
   # firewalls to restrict access to this address/port.
   # Comment out following line if you only want to support TLS connections
   listen_addr: '0.0.0.0:8075',
   # Set the network address that Gitaly will listen on for monitoring
   prometheus_listen_addr: '0.0.0.0:9236',
   auth: {
      # Gitaly Auth Token
      # Should be the same as praefect_internal_token
      token: '<praefect_internal_token>',
   },
   pack_objects_cache: {
      # Gitaly Pack-objects cache
      # Recommended to be enabled for improved performance but can notably increase disk I/O
      # Refer to https://docs.gitlab.com/administration/gitaly/configure_gitaly/#pack-objects-cache for more info
      enabled: true,
   },
}

#
# END user configuration

각 서버에 다음 내용을 /etc/gitlab/gitlab.rb에 추가합니다:

Gitaly 노드 1:

gitaly['configuration'] = {
   # ...
   storage: [
      {
         name: 'gitaly-1',
         path: '/var/opt/gitlab/git-data/repositories',
      },
   ],
}

Gitaly 노드 2:

gitaly['configuration'] = {
   # ...
   storage: [
      {
         name: 'gitaly-2',
         path: '/var/opt/gitlab/git-data/repositories',
      },
   ],
}

Gitaly 노드 3:

gitaly['configuration'] = {
   # ...
   storage: [
      {
         name: 'gitaly-3',
         path: '/var/opt/gitlab/git-data/repositories',
      },
   ],
}

첫 번째로 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체합니다. 처음으로 구성하는 Linux 패키지 노드라면 이 단계를 건너뛰어도 됩니다.

파일을 저장한 다음 GitLab을 재구성합니다.

Gitaly Cluster (Praefect) TLS 지원#

Praefect는 TLS 암호화를 지원합니다. 보안 연결을 수신하는 Praefect 인스턴스와 통신하려면 다음을 수행해야 합니다:

  • GitLab 구성에서 해당 스토리지 항목의 gitaly_addresstls:// URL 스킴을 사용합니다.

  • 인증서는 자동으로 제공되지 않으므로 직접 준비해야 합니다. 각 Praefect 서버에 해당하는 인증서를 해당 Praefect 서버에 설치해야 합니다.

또한 인증서 또는 인증 기관(CA)을 모든 Gitaly 서버와 Praefect와 통신하는 모든 Praefect 클라이언트에 설치해야 합니다. 아래에서 설명하는 GitLab 사용자 정의 인증서 구성 절차를 따르십시오.

다음 사항에 유의하세요:

  • 인증서에는 Praefect 서버에 접근하는 데 사용하는 주소가 명시되어야 합니다. 인증서에 호스트명 또는 IP 주소를 Subject Alternative Name으로 추가해야 합니다.

  • Praefect 서버를 암호화되지 않은 수신 주소 listen_addr와 암호화된 수신 주소 tls_listen_addr로 동시에 구성할 수 있습니다. 이를 통해 필요한 경우 암호화되지 않은 트래픽에서 암호화된 트래픽으로 점진적으로 전환할 수 있습니다. 암호화되지 않은 리스너를 비활성화하려면 praefect['configuration'][:listen_addr] = nil로 설정합니다.

  • 내부 로드 밸런서는 TLS 연결을 처리하도록 구성해야 합니다. 로드 밸런서가 암호화된 트래픽을 종료하지 않고 백엔드로 전달하는 TLS 패스스루(passthrough)를 지원하도록 구성하세요. 패스스루/직접 서버 반환(DSR) 로드 밸런서는 사용하지 마십시오. 로드 밸런서는 올바른 로드 밸런싱 및 헬스 체크를 유지하기 위해 연결을 적극적으로 프록시해야 합니다.

TLS로 Praefect를 구성하려면:

Praefect 서버용 인증서를 생성합니다.

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

/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',
   },
}

파일을 저장하고 재구성하세요.

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

sudo cp cert.pem /etc/gitlab/trusted-certs/

Praefect 클라이언트(Gitaly 서버 제외)에서 /etc/gitlab/gitlab.rbgitlab_rails['repositories_storages']를 다음과 같이 편집하세요:

gitlab_rails['repositories_storages'] = {
  "default" => {
    "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:3305',
    "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
  }
}

파일을 저장하고 GitLab을 재구성하세요.

컴포넌트 설정으로 돌아가기

Sidekiq 구성#

Sidekiq은 Redis, PostgreSQL, Gitaly 인스턴스에 대한 연결이 필요합니다. 또한 권장 사항에 따라 오브젝트 스토리지에 대한 연결도 필요합니다.

데이터 오브젝트에 NFS 대신 오브젝트 스토리지 사용이 권장되므로, 다음 예시에는 오브젝트 스토리지 구성이 포함되어 있습니다.

환경의 Sidekiq job 처리가 긴 큐로 인해 느리다면 그에 맞게 스케일 조정할 수 있습니다. 자세한 내용은 스케일링 문서를 참조하세요.

Container Registry, SAML, LDAP 등 추가 GitLab 기능을 구성할 때는 Rails 구성 외에 Sidekiq 구성도 함께 업데이트하세요. 자세한 내용은 외부 Sidekiq 문서를 참조하세요.

다음 Sidekiq 노드는 예시로 사용됩니다:

  • 10.6.0.101: Sidekiq 1

  • 10.6.0.102: Sidekiq 2

  • 10.6.0.103: Sidekiq 3

  • 10.6.0.104: Sidekiq 4

각 Sidekiq 노드를 구성하려면 다음 단계를 수행하세요:

Sidekiq 서버에 SSH로 접속합니다.

PostgreSQL, Gitaly, Redis 포트에 접근 가능한지 확인합니다:

telnet  5432 # PostgreSQL
telnet  8075 # Gitaly
telnet  6379 # Redis

원하는 Linux 패키지를 다운로드하고 설치하세요. GitLab 패키지 리포지터리만 추가하고, 선택한 운영 체제에 맞는 GitLab만 설치하세요.

/etc/gitlab/gitlab.rb를 생성하거나 편집하고 다음 구성을 사용하세요:

# https://docs.gitlab.com/omnibus/roles/#sidekiq-roles
roles(["sidekiq_role"])

# External URL
## This should match the URL of the external load balancer
external_url 'https://gitlab.example.com'

# Redis
## Redis connection details
## First cluster that will host the cache data
gitlab_rails['redis_cache_instance'] = 'redis://:@gitlab-redis-cache'

gitlab_rails['redis_cache_sentinels'] = [
  {host: '10.6.0.51', port: 26379},
  {host: '10.6.0.52', port: 26379},
  {host: '10.6.0.53', port: 26379},
]

## Second cluster that hosts all other persistent data
redis['master_name'] = 'gitlab-redis-persistent'
redis['master_password'] = ''

gitlab_rails['redis_sentinels'] = [
  {host: '10.6.0.61', port: 26379},
  {host: '10.6.0.62', port: 26379},
  {host: '10.6.0.63', port: 26379},
]

# Gitaly Cluster
## gitlab_rails['repositories_storages'] gets configured for the Praefect virtual storage
## TCP load balancer (recommended for most setups):
gitlab_rails['repositories_storages'] = {
  "default" => {
    "gitaly_address" => "tcp://10.6.0.40:2305", # internal load balancer IP
    "gitaly_token" => '<praefect_external_token>'
  }
}

## Alternatively, use service discovery DNS (requires DNS infrastructure):
# gitlab_rails['repositories_storages'] = {
#   "default" => {
#     "gitaly_address" => "dns:PRAEFECT_SERVICE_DISCOVERY_ADDRESS:2305",
#     "gitaly_token" => '<praefect_external_token>'
#   }
# }

# PostgreSQL
gitlab_rails['db_host'] = '10.6.0.20' # internal load balancer IP
gitlab_rails['db_port'] = 6432
gitlab_rails['db_password'] = '<postgresql_user_password>'
gitlab_rails['db_load_balancing'] = { 'hosts' => ['10.6.0.21', '10.6.0.22', '10.6.0.23'] } # PostgreSQL IPs

## Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

# Sidekiq
sidekiq['listen_address'] = "0.0.0.0"

## Set number of Sidekiq queue processes to the same number as available CPUs
sidekiq['queue_groups'] = ['*'] * 4

# Monitoring
consul['enable'] = true
consul['monitoring_service_discovery'] =  true

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

## Set the network addresses that the exporters will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'

## Add the monitoring node's IP address to the monitoring whitelist
gitlab_rails['monitoring_whitelist'] = ['10.6.0.151/32', '127.0.0.0/8']

# Object Storage
# This is an example for configuring Object Storage on GCP
# Replace this config with your chosen Object Storage provider as desired
gitlab_rails['object_store']['enabled'] = true
gitlab_rails['object_store']['connection'] = {
  'provider' => 'Google',
  'google_project' => '<gcp-project-name>',
  'google_json_key_location' => '<path-to-gcp-service-account-key>'
}
gitlab_rails['object_store']['objects']['artifacts']['bucket'] = "<gcp-artifacts-bucket-name>"
gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = "<gcp-external-diffs-bucket-name>"
gitlab_rails['object_store']['objects']['lfs']['bucket'] = "<gcp-lfs-bucket-name>"
gitlab_rails['object_store']['objects']['uploads']['bucket'] = "<gcp-uploads-bucket-name>"
gitlab_rails['object_store']['objects']['packages']['bucket'] = "<gcp-packages-bucket-name>"
gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = "<gcp-dependency-proxy-bucket-name>"
gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = "<gcp-terraform-state-bucket-name>"

gitlab_rails['backup_upload_connection'] = {
  'provider' => 'Google',
  'google_project' => '<gcp-project-name>',
  'google_json_key_location' => '<path-to-gcp-service-account-key>'
}
gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"

gitlab_rails['ci_secure_files_object_store_enabled'] = true
gitlab_rails['ci_secure_files_object_store_remote_directory'] = "<gcp-ci_secure_files-bucket-name>"

gitlab_rails['ci_secure_files_object_store_connection'] = {
   'provider' => 'Google',
   'google_project' => '<gcp-project-name>',
   'google_json_key_location' => '<path-to-gcp-service-account-key>'
}

첫 번째로 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하세요. 이 서버가 처음 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

데이터베이스 마이그레이션이 업그레이드 시 자동으로 실행되지 않고 reconfigure 시에만 실행되도록 하려면 다음을 실행하세요:

sudo touch /etc/gitlab/skip-auto-reconfigure

마이그레이션은 GitLab Rails 사후 구성 섹션에 명시된 대로 단일 지정 노드에서만 처리해야 합니다.

변경 사항을 적용하려면 GitLab을 재구성하세요.

컴포넌트 설정으로 돌아가기

GitLab Rails 구성#

이 섹션에서는 GitLab 애플리케이션(Rails) 컴포넌트를 구성하는 방법을 설명합니다.

Rails는 Redis, PostgreSQLGitaly 인스턴스에 대한 연결이 필요합니다. 또한 권장 사항에 따라 오브젝트 스토리지에 대한 연결도 필요합니다.

[데이터 오브젝트에 NFS 대신 오브젝트 스토리지 사용이 권장되므로](/19.2/administration/object_storage/), 다음

예시에는 오브젝트 스토리지 구성이 포함되어 있습니다.

다음 IP가 예시로 사용됩니다:

  • 10.6.0.111: GitLab 애플리케이션 1

  • 10.6.0.112: GitLab 애플리케이션 2

  • 10.6.0.113: GitLab 애플리케이션 3

  • 10.6.0.114: GitLab 애플리케이션 4

  • 10.6.0.115: GitLab 애플리케이션 5

각 노드에서 다음을 수행하세요:

원하는 Linux 패키지를 다운로드하여 설치하세요. 선택한 운영 체제에 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 합니다.

/etc/gitlab/gitlab.rb를 편집하고 다음 구성을 사용하세요. 노드 간 링크 일관성을 유지하기 위해, 애플리케이션 서버의 external_url은 사용자가 GitLab에 접근할 때 사용하는 외부 URL을 가리켜야 합니다. 이는 GitLab 애플리케이션 서버로 트래픽을 라우팅하는 외부 로드 밸런서의 URL입니다:

external_url 'https://gitlab.example.com'

# gitlab_rails['repositories_storages'] gets configured for the Praefect virtual storage
# TCP load balancer (recommended for most setups):
gitlab_rails['repositories_storages'] = {
  "default" => {
    "gitaly_address" => "tcp://10.6.0.40:2305", # internal load balancer IP
    "gitaly_token" => '<praefect_external_token>'
  }
}

# Alternatively, use service discovery DNS (requires DNS infrastructure):
# gitlab_rails['repositories_storages'] = {
#   "default" => {
#     "gitaly_address" => "dns:PRAEFECT_SERVICE_DISCOVERY_ADDRESS:2305",
#     "gitaly_token" => '<praefect_external_token>'
#   }
# }

## Disable components that will not be on the GitLab application server
roles(['application_role'])
gitaly['enable'] = false
sidekiq['enable'] = false

## PostgreSQL connection details
# Disable PostgreSQL on the application node
postgresql['enable'] = false
gitlab_rails['db_host'] = '10.6.0.20' # internal load balancer IP
gitlab_rails['db_port'] = 6432
gitlab_rails['db_password'] = '<postgresql_user_password>'
gitlab_rails['db_load_balancing'] = { 'hosts' => ['10.6.0.21', '10.6.0.22', '10.6.0.23'] } # PostgreSQL IPs

# Prevent database migrations from running on upgrade automatically
gitlab_rails['auto_migrate'] = false

## Redis connection details
## First cluster that will host the cache data
gitlab_rails['redis_cache_instance'] = 'redis://:@gitlab-redis-cache'

gitlab_rails['redis_cache_sentinels'] = [
  {host: '10.6.0.51', port: 26379},
  {host: '10.6.0.52', port: 26379},
  {host: '10.6.0.53', port: 26379},
]

## Second cluster that hosts all other persistent data
redis['master_name'] = 'gitlab-redis-persistent'
redis['master_password'] = ''

gitlab_rails['redis_sentinels'] = [
  {host: '10.6.0.61', port: 26379},
  {host: '10.6.0.62', port: 26379},
  {host: '10.6.0.63', port: 26379},
]

# Set the network addresses that the exporters used for monitoring will listen on
node_exporter['listen_address'] = '0.0.0.0:9100'
gitlab_workhorse['prometheus_listen_addr'] = '0.0.0.0:9229'
puma['listen'] = '0.0.0.0'

# Add the monitoring node's IP address to the monitoring whitelist and allow it to
# scrape the NGINX metrics
gitlab_rails['monitoring_whitelist'] = ['10.6.0.151/32', '127.0.0.0/8']
nginx['status']['options']['allow'] = ['10.6.0.151/32', '127.0.0.0/8']

#############################
###     Object storage    ###
#############################

# This is an example for configuring Object Storage on GCP
# Replace this config with your chosen Object Storage provider as desired
gitlab_rails['object_store']['enabled'] = true
gitlab_rails['object_store']['connection'] = {
  'provider' => 'Google',
  'google_project' => '<gcp-project-name>',
  'google_json_key_location' => '<path-to-gcp-service-account-key>'
}
gitlab_rails['object_store']['objects']['artifacts']['bucket'] = "<gcp-artifacts-bucket-name>"
gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = "<gcp-external-diffs-bucket-name>"
gitlab_rails['object_store']['objects']['lfs']['bucket'] = "<gcp-lfs-bucket-name>"
gitlab_rails['object_store']['objects']['uploads']['bucket'] = "<gcp-uploads-bucket-name>"
gitlab_rails['object_store']['objects']['packages']['bucket'] = "<gcp-packages-bucket-name>"
gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = "<gcp-dependency-proxy-bucket-name>"
gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = "<gcp-terraform-state-bucket-name>"

gitlab_rails['backup_upload_connection'] = {
  'provider' => 'Google',
  'google_project' => '<gcp-project-name>',
  'google_json_key_location' => '<path-to-gcp-service-account-key>'
}
gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"
gitlab_rails['ci_secure_files_object_store_enabled'] = true
gitlab_rails['ci_secure_files_object_store_remote_directory'] = "<gcp-ci_secure_files-bucket-name>"

gitlab_rails['ci_secure_files_object_store_connection'] = {
   'provider' => 'Google',
   'google_project' => '<gcp-project-name>',
   'google_json_key_location' => '<path-to-gcp-service-account-key>'
}

TLS 지원이 포함된 Gitaly를 사용하는 경우, tcp 대신 tlsgitlab_rails['repositories_storages'] 항목이 구성되어 있는지 확인하세요:

# TCP load balancer with TLS (recommended for most setups):
gitlab_rails['repositories_storages'] = {
  "default" => {
    "gitaly_address" => "tls://10.6.0.40:3305", # internal load balancer IP
    "gitaly_token" => '<praefect_external_token>'
  }
}

# Alternatively, use service discovery DNS with TLS (requires DNS infrastructure and GitLab 18.9+):
# gitlab_rails['repositories_storages'] = {
#   "default" => {
#     "gitaly_address" => "dns+tls://DNS_SERVER_ADDRESS:53/PRAEFECT_SERVICE_DISCOVERY_ADDRESS:3305",
#     "gitaly_token" => '<praefect_external_token>'
#   }
# }

인증서를 /etc/gitlab/trusted-certs에 복사하세요:

sudo cp cert.pem /etc/gitlab/trusted-certs/

처음 구성한 Linux 패키지 노드에서 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하세요. 처음 구성하는 Linux 패키지 노드인 경우 이 단계를 건너뛸 수 있습니다.

처음 구성한 Rails 노드에서 SSH 호스트 키(/etc/ssh/ssh_host_*_key* 형식의 모든 파일)를 복사하여 이 서버의 동일한 이름의 파일에 추가하거나 교체하세요. 이를 통해 사용자가 로드 밸런싱된 Rails 노드에 접속할 때 호스트 불일치 오류가 발생하지 않도록 합니다. 처음 구성하는 Linux 패키지 노드인 경우 이 단계를 건너뛸 수 있습니다.

업그레이드 시 자동으로 실행되지 않고 reconfigure 중에만 데이터베이스 마이그레이션이 실행되도록 하려면 다음을 실행하세요:

sudo touch /etc/gitlab/skip-auto-reconfigure

GitLab Rails 사후 구성 섹션에 설명된 대로 지정된 단일 노드만 마이그레이션을 처리해야 합니다.

변경 사항을 적용하려면 GitLab을 Reconfigure하세요.

증분 로깅을 활성화하세요.

노드가 Gitaly에 연결할 수 있는지 확인하세요:

sudo gitlab-rake gitlab:gitaly:check

그런 다음 로그를 tail하여 요청을 확인하세요:

sudo gitlab-ctl tail gitaly

선택 사항으로, Gitaly 서버에서 Gitaly가 내부 API로 콜백을 수행할 수 있는지 확인하세요:

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을 실행하세요.

이전 예시와 같이 external_urlhttps를 지정하면 GitLab은 SSL 인증서가 /etc/gitlab/ssl/에 있을 것으로 예상합니다. 인증서가 없으면 NGINX가 시작되지 않습니다. 자세한 내용은 HTTPS 문서를 참조하세요.

GitLab Rails 사후 구성#

설치 및 업데이트 중 데이터베이스 마이그레이션을 실행할 애플리케이션 노드 하나를 지정하세요. GitLab 데이터베이스를 초기화하고 모든 마이그레이션이 실행되었는지 확인하세요:

sudo gitlab-rake gitlab:db:configure

이 작업을 수행하려면 Rails 노드가 PgBouncer를 우회하여 기본 데이터베이스에 직접 연결하도록 구성해야 합니다. 마이그레이션이 완료된 후에는 PgBouncer를 통해 연결을 전달하도록 노드를 다시 구성해야 합니다.

데이터베이스에서 승인된 SSH 키의 빠른 조회를 구성하세요.

구성 요소 설정으로 돌아가기

Prometheus 구성#

Linux 패키지를 사용하여 Prometheus를 실행하는 독립형 모니터링 노드를 구성할 수 있습니다.

다음 IP를 예시로 사용합니다:

  • 10.6.0.151: Prometheus

모니터링 노드를 구성하려면:

Monitoring 노드에 SSH로 접속합니다.

원하는 Linux 패키지를 다운로드하고 설치합니다. GitLab 패키지 리포지터리만 추가하고 선택한 운영 체제용 GitLab을 설치해야 합니다.

/etc/gitlab/gitlab.rb를 편집하고 다음 내용을 추가합니다:

roles(['monitoring_role', 'consul_role'])

external_url 'http://gitlab.example.com'

# Prometheus
prometheus['listen_address'] = '0.0.0.0:9090'
prometheus['monitor_kubernetes'] = false

# Enable service discovery for Prometheus
consul['monitoring_service_discovery'] =  true
consul['configuration'] = {
   retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
}

# Configure Prometheus to scrape services not covered by discovery
prometheus['scrape_configs'] = [
   {
      'job_name': 'pgbouncer',
      'static_configs' => [
         'targets' => [
         "10.6.0.31:9188",
         "10.6.0.32:9188",
         "10.6.0.33:9188",
         ],
      ],
   },
   {
      'job_name': 'praefect',
      'static_configs' => [
         'targets' => [
         "10.6.0.131:9652",
         "10.6.0.132:9652",
         "10.6.0.133:9652",
         ],
      ],
   },
]

nginx['enable'] = false

파일을 저장하고 GitLab을 재구성합니다.

컴포넌트 설정으로 돌아가기

오브젝트 스토리지 구성#

GitLab은 다양한 유형의 데이터를 저장하기 위해 오브젝트 스토리지 서비스 사용을 지원합니다. 데이터 오브젝트의 경우 NFS보다 오브젝트 스토리지를 권장하며, 오브젝트 스토리지가 일반적으로 성능, 안정성, 확장성 면에서 훨씬 뛰어나기 때문에 대규모 설정에서도 더 적합합니다. 자세한 내용은 인프라 및 서비스를 참조하세요.

GitLab에서 오브젝트 스토리지 구성을 지정하는 방법은 두 가지입니다:

가능한 경우 아래 예시에서는 통합 형식을 사용합니다.

GitLab에서는 데이터 유형별로 별도의 버킷을 사용하는 방식을 권장합니다. 이렇게 하면 GitLab이 저장하는 다양한 유형의 데이터 간에 충돌이 발생하지 않습니다. 향후 단일 버킷 사용을 지원할 계획이 있습니다.

컴포넌트 설정으로 돌아가기

증분 로깅 활성화#

GitLab Runner는 job 로그를 청크 단위로 반환하며, 통합 오브젝트 스토리지를 사용하는 경우에도 Linux 패키지는 기본적으로 /var/opt/gitlab/gitlab-ci/builds 경로의 디스크에 임시로 캐시합니다. 기본 구성에서 이 디렉터리는 모든 GitLab Rails 및 Sidekiq 노드에서 NFS를 통해 공유되어야 합니다.

NFS를 통한 job 로그 공유는 지원되지만, NFS 노드를 배포하지 않은 경우 증분 로깅을 활성화하여 NFS 사용 필요성을 피할 수 있습니다(NFS 노드가 배포되지 않은 경우 필수). 증분 로깅은 job 로그의 임시 캐싱에 디스크 공간 대신 Redis를 사용합니다.

고급 검색 구성#

Elasticsearch를 활용하고 고급 검색을 활성화하면 전체 GitLab 인스턴스에서 더 빠르고 강력한 코드 검색을 수행할 수 있습니다.

Elasticsearch 클러스터 설계 및 요구 사항은 특정 데이터에 따라 달라집니다. 인스턴스와 함께 Elasticsearch 클러스터를 설정하는 방법에 대한 권장 모범 사례는 최적의 클러스터 구성 선택을 참조하세요.

컴포넌트 설정으로 돌아가기

Helm Charts를 사용한 Cloud Native Hybrid 레퍼런스 아키텍처 (대안)#

쿠버네티스에서 특정 GitLab 컴포넌트를 실행하는 대안적 방법도 있습니다. 다음 서비스가 지원됩니다:

  • GitLab Rails

  • Sidekiq

  • NGINX

  • Toolbox

  • Migrations

  • Prometheus

하이브리드 설치는 클라우드 네이티브 배포와 전통적인 컴퓨팅 배포 방식의 장점을 모두 활용합니다. 이를 통해 상태 비저장 컴포넌트는 클라우드 네이티브 워크로드 관리의 이점을 누릴 수 있으며, 상태 저장 컴포넌트는 Linux 패키지 설치를 사용하는 컴퓨팅 VM에 배포되어 더 높은 영속성의 이점을 얻을 수 있습니다.

쿠버네티스와 백엔드 컴포넌트 간에 동기화할 GitLab 시크릿에 대한 안내를 포함한 설정 지침은 Helm 차트 고급 구성 문서를 참조하세요.

이것은 **고급** 설정입니다. 쿠버네티스에서 서비스를 실행하는 것은 복잡한 작업으로 잘 알려져 있습니다.

이 설정은 쿠버네티스에 대한 충분한 실무 지식과 경험이 있는 경우에만 권장됩니다. 이 섹션의 나머지 내용은 이를 전제로 합니다.

Gitaly의 쿠버네티스 가용성, 제한 사항 및 배포 고려 사항에 대한 자세한 내용은 Gitaly on Kubernetes를 참조하세요.

클러스터 토폴로지#

다음 표와 다이어그램은 앞서 설명한 일반적인 환경과 동일한 형식을 사용하여 하이브리드 환경을 자세히 설명합니다.

먼저 쿠버네티스에서 실행되는 컴포넌트입니다. 이들은 여러 노드 그룹에 걸쳐 실행되지만, 최소 CPU 및 메모리 요구 사항이 충족되는 한 전체 구성을 원하는 대로 변경할 수 있습니다.

컴포넌트 노드 그룹 타깃 노드 풀 합계 GCP 예시 AWS 예시
Webservice 140 vCPU175 GB memory (request)245 GB memory (limit) 5 x n1-standard-32 5 x c5.9xlarge
Sidekiq 12.6 vCPU28 GB memory (request)56 GB memory (limit) 4 x n1-standard-4 4 x m5.xlarge
Supporting services 8 vCPU30 GB memory 2 x n1-standard-4 2 x m5.xlarge
  • 이 설정에서는 Google Kubernetes Engine (GKE)Amazon Elastic Kubernetes Service (EKS)를 정기적으로 테스트하고 권장합니다. 다른 쿠버네티스 서비스도 작동할 수 있지만, 결과는 다를 수 있습니다.

  • 머신 유형 예시는 설명 목적으로 제공됩니다. 이 유형들은 검증 및 테스트에서 사용되지만, 규범적인 기본값으로 의도된 것은 아닙니다. 요구 사항을 충족하는 다른 머신 유형으로 전환하는 것이 지원됩니다. 자세한 내용은 지원되는 머신 유형을 참조하세요.

  • WebserviceSidekiq 타깃 노드 풀 합계는 GitLab 컴포넌트 전용으로 제공됩니다. 선택한 쿠버네티스 제공업체의 시스템 프로세스에는 추가 리소스가 필요합니다. 제공된 예시는 이를 고려한 것입니다.

  • Supporting 타깃 노드 풀 합계는 GitLab 배포를 지원하는 여러 리소스 및 요구 사항에 따라 추가로 배포할 수 있는 리소스를 수용하기 위해 일반적으로 제공됩니다. 다른 노드 풀과 마찬가지로 선택한 쿠버네티스 제공업체의 시스템 프로세스에도 리소스가 필요합니다. 제공된 예시는 이를 고려한 것입니다.

  • 프로덕션 배포에서는 Pod를 특정 노드에 할당할 필요가 없습니다. 그러나 복원력 있는 클라우드 아키텍처 관행에 맞게 각 풀에서 여러 가용 영역에 걸쳐 여러 노드를 배치하는 것을 권장합니다.

  • 효율성을 위해 Cluster Autoscaler와 같은 오토스케일링을 활성화하는 것이 권장되지만, 지속적인 성능 보장을 위해 Webservice 및 Sidekiq Pod의 최소 기준을 75%로 타깃팅하는 것이 일반적으로 권장됩니다.

다음은 Linux 패키지(또는 해당하는 경우 외부 PaaS 서비스)를 사용하는 정적 컴퓨팅 VM에서 실행되는 백엔드 컴포넌트입니다:

서비스 노드 수 구성 GCP 예시1 AWS 예시1
Consul2 3 2 vCPU, 1.8 GB memory n1-highcpu-2 c5.large
PostgreSQL2 3 16 vCPU, 60 GB memory n1-standard-16 m5.4xlarge
PgBouncer2 3 2 vCPU, 1.8 GB memory n1-highcpu-2 c5.large
Internal load balancer4 1 8 vCPU, 7.2 GB memory n1-highcpu-8 c5.2xlarge
Redis/Sentinel - Cache3 3 4 vCPU, 15 GB memory n1-standard-4 m5.xlarge
Redis/Sentinel - Persistent3 3 4 vCPU, 15 GB memory n1-standard-4 m5.xlarge
Gitaly67 3 32 vCPU, 120 GB memory n1-standard-32 m5.8xlarge
Praefect6 3 4 vCPU, 3.6 GB memory n1-highcpu-4 c5.xlarge
Praefect PostgreSQL2 1+ 2 vCPU, 1.8 GB memory n1-highcpu-2 c5.large
Object storage5 - - - -

각주:

-->

  • 머신 유형 예시는 설명 목적으로 제공됩니다. 이 유형들은 검증 및 테스트에서 사용되지만, 규범적인 기본값으로 의도된 것은 아닙니다. 나열된 요구 사항을 충족하는 다른 머신 유형으로 전환하는 것이 지원되며, 가능한 경우 ARM 변형도 포함됩니다. 자세한 내용은 지원되는 머신 유형을 참조하세요.

  • 신뢰할 수 있는 타사 외부 PaaS PostgreSQL 솔루션에서 선택적으로 실행할 수 있습니다. 자세한 내용은 직접 PostgreSQL 인스턴스 제공을 참조하세요.

  • 신뢰할 수 있는 타사 외부 PaaS Redis 솔루션에서 선택적으로 실행할 수 있습니다. 자세한 내용은 직접 Redis 인스턴스 제공을 참조하세요.

Redis는 기본적으로 단일 스레드로 동작하며 CPU 코어 수 증가에 따른 이점이 크지 않습니다. 이 규모의 아키텍처에서는 최적의 성능을 위해 지정된 대로 별도의 캐시 및 영속 인스턴스를 사용하는 것이 강력히 권장됩니다.

  • 신뢰할 수 있는 타사 로드 밸런싱 서비스(LB PaaS)에서 선택적으로 실행할 수 있습니다. 자세한 내용은 인프라 및 서비스를 참조하세요.

  • 신뢰할 수 있는 클라우드 제공업체 또는 Self-managed 솔루션에서 실행해야 합니다. 자세한 내용은 오브젝트 스토리지 구성을 참조하세요.

  • Gitaly 클러스터(Praefect)는 장애 허용의 이점을 제공하지만, 설정 및 관리가 더 복잡합니다. Gitaly 클러스터(Praefect) 배포 전 기술적 제한 사항 및 고려 사항을 검토하세요. 샤딩된 Gitaly를 사용하려면 이전 표의 Gitaly 항목과 동일한 사양을 사용하세요.

  • Gitaly 사양은 양호한 상태의 사용 패턴과 리포지터리 크기의 높은 백분위수를 기준으로 합니다. 그러나 대형 모노리포(수 기가바이트 이상) 또는 추가 워크로드가 있는 경우, Git 및 Gitaly 성능에 상당한 영향을 미칠 수 있으며 추가 조정이 필요할 수 있습니다.

    인스턴스 구성이 포함된 모든 PaaS 솔루션의 경우, 복원력 있는 클라우드 아키텍처 관행에 맞게 세 개의 서로 다른 가용 영역에 최소 세 개의 노드를 구현하는 것을 권장합니다.

    @startuml 25k skinparam linetype ortho

card "Kubernetes via Helm Charts" as kubernetes { card "External Load Balancer" as elb #6a9be7

together { collections "Webservice" as gitlab #32CD32 collections "Sidekiq" as sidekiq #ff8dd1 }

card "Supporting Services" as support }

card "Internal Load Balancer" as ilb #9370DB collections "Consul x3" as consul #e76a9b

card "Gitaly Cluster" as gitaly_cluster { collections "Praefect x3" as praefect #FF8C00 collections "Gitaly x3" as gitaly #FF8C00 card "Praefect PostgreSQL*\n//Non fault-tolerant//" as praefect_postgres #FF8C00

praefect -[#FF8C00]-> gitaly praefect -[#FF8C00]> praefect_postgres }

card "Database" as database { collections "PGBouncer x3" as pgbouncer #4EA7FF card "PostgreSQL (Primary)" as postgres_primary #4EA7FF collections "PostgreSQL (Secondary) x2" as postgres_secondary #4EA7FF

pgbouncer -[#4EA7FF]-> postgres_primary postgres_primary .[#4EA7FF]> postgres_secondary }

card "redis" as redis { collections "Redis Persistent x3" as redis_persistent #FF6347 collections "Redis Cache x3" as redis_cache #FF6347

redis_cache -[hidden]-> redis_persistent }

cloud "Object Storage" as object_storage #white

elb -[#6a9be7]-> gitlab elb -[hidden]-> sidekiq elb -[hidden]-> support

gitlab -[#32CD32]--> ilb gitlab -[#32CD32]r--> object_storage gitlab -[#32CD32,norank]----> redis gitlab -[#32CD32]----> database

sidekiq -[#ff8dd1]--> ilb sidekiq -[#ff8dd1]r--> object_storage sidekiq -[#ff8dd1,norank]----> redis sidekiq .[#ff8dd1]----> database

ilb -[#9370DB]--> gitaly_cluster ilb -[#9370DB]--> database ilb -[hidden,norank]--> redis

consul .[#e76a9b]--> database consul .[#e76a9b,norank]--> gitaly_cluster consul .[#e76a9b]--> redis

@enduml

쿠버네티스 컴포넌트 타깃#

다음 섹션에서는 쿠버네티스에 배포된 GitLab 컴포넌트에 사용되는 타깃을 자세히 설명합니다.

Webservice#

각 Webservice Pod(Puma 및 Workhorse)는 다음 구성으로 실행하는 것을 권장합니다:

  • Puma Worker 4개

  • vCPU 4개

  • 메모리 5GB(요청)

  • 메모리 7GB(제한)

RPS 500 또는 사용자 25,000명 기준으로 총 Puma worker 수는 약 140개를 권장하므로, 최소 35개의 Webservice Pod를 실행하는 것을 권장합니다.

Webservice 리소스 사용에 대한 자세한 내용은 Webservice 리소스에 대한 Charts 문서를 참조하세요.

Gateway API / Ingress#

Gateway API 또는 Ingress 컨트롤러 Pod를 DaemonSet으로 Webservice 노드에 배포하는 것도 권장합니다. 이를 통해 컨트롤러가 서비스하는 Webservice Pod에 맞게 동적으로 확장되고, 일반적으로 더 큰 머신 유형이 제공하는 높은 네트워크 대역폭을 활용할 수 있습니다.

이것은 엄격한 요구 사항이 아닙니다. Gateway API 또는 Ingress 컨트롤러 Pod는 웹 트래픽을 처리하기에 충분한 리소스가 있는 한 원하는 방식으로 배포할 수 있습니다.

Sidekiq#

각 Sidekiq Pod는 다음 구성으로 실행하는 것을 권장합니다:

  • Sidekiq worker 1개

  • vCPU 900m

  • 메모리 2GB(요청)

  • 메모리 4GB(제한)

앞서 문서화된 표준 배포와 유사하게, 여기서는 초기 타깃으로 Sidekiq worker 14개를 사용했습니다. 특정 워크플로에 따라 추가 worker가 필요할 수 있습니다.

Sidekiq 리소스 사용에 대한 자세한 내용은 Sidekiq 리소스에 대한 Charts 문서를 참조하세요.

지원(Supporting)#

Supporting 노드 풀은 Webservice 및 Sidekiq 풀에 필요하지 않은 모든 지원 배포를 수용하도록 설계되었습니다.

여기에는 클라우드 제공업체의 구현과 관련된 다양한 배포 및 GitLab Shell과 같은 GitLab 지원 배포가 포함됩니다.

컨테이너 레지스트리, Pages, 모니터링 등 추가 배포는 가능한 한 Webservice 또는 Sidekiq 풀이 아닌 Supporting 노드 풀에 배포하세요. Supporting 노드 풀은 여러 추가 배포를 수용할 수 있도록 설계되었습니다. 그러나 배포가 주어진 풀에 맞지 않는 경우 노드 풀을 그에 맞게 늘릴 수 있습니다. 반대로, 사용 사례에서 풀이 과도하게 프로비저닝된 경우 그에 맞게 줄일 수 있습니다.

예시 구성 파일#

RPS 500 또는 사용자 25,000명 레퍼런스 아키텍처 구성을 타깃으로 하는 GitLab Helm Charts의 예시는 Charts 프로젝트에서 확인할 수 있습니다.

컴포넌트 설정으로 돌아가기

다음 단계#

이 가이드를 따른 후에는 핵심 기능이 적절히 구성된 새로운 GitLab 환경이 준비되어 있어야 합니다.

요구 사항에 따라 GitLab의 추가 선택적 기능을 구성할 수 있습니다. 자세한 내용은 GitLab 설치 후 단계를 참조하세요.

환경 및 요구 사항에 따라 원하는 추가 기능을 설정하기 위해 추가적인 하드웨어 요구 사항이나 조정이 필요할 수 있습니다. 자세한 내용은 개별 페이지를 참조하세요.