레퍼런스 아키텍처: 최대 60 RPS 또는 3,000명 사용자
GitLab v19.5Offering: GitLab Self-Managed
요약
이 페이지는 초당 60 요청(RPS)의 최대 부하를 목표로 설계된 GitLab 레퍼런스 아키텍처를 설명합니다. 이 아키텍처는 HA가 기본으로 내장된 가장 작은 아키텍처입니다. 전체 레퍼런스 아키텍처 목록은 사용 가능한 레퍼런스 아키텍처를 참고합니다.
이 페이지는 초당 60 요청(RPS)의 최대 부하를 목표로 설계된 GitLab 레퍼런스 아키텍처를 설명합니다. 60 RPS는 실제 데이터를 기준으로, 수동 및 자동화된 부하를 모두 포함한 최대 3,000명 사용자의 일반적인 최대 부하입니다.
이 아키텍처는 HA가 기본으로 내장된 가장 작은 아키텍처입니다. HA가 필요하지만 사용자 수나 전체 부하가 더 적은 경우, 사용자 수가 적은 환경에서 지원되는 수정 사항 섹션에서 HA를 유지하면서 이 아키텍처의 규모를 줄이는 방법을 설명합니다.
전체 레퍼런스 아키텍처 목록은 사용 가능한 레퍼런스 아키텍처를 참고합니다.
- 목표 부하: API: 60 RPS, Web: 6 RPS, Git (Pull): 6 RPS, Git (Push): 1 RPS
- 고가용성: 예. 다만 Praefect에는 서드파티 PostgreSQL 솔루션이 필요합니다
- 클라우드 네이티브 하이브리드 대안: 예
- 어떤 레퍼런스 아키텍처를 사용해야 할지 확실하지 않은 경우: 이 가이드에서 자세한 정보를 확인합니다.
| 서비스 | 노드 수 | 구성 | GCP 예시1 | AWS 예시1 | Azure 예시1 |
|---|---|---|---|---|---|
| 외부 로드 밸런서2 | 1 | 4 vCPU, 3.6 GB 메모리 | n1-highcpu-4 |
c5n.xlarge |
F4s v2 |
| Consul3 | 3 | 2 vCPU, 1.8 GB 메모리 | n1-highcpu-2 |
c5.large |
F2s v2 |
| PostgreSQL3 | 3 | 2 vCPU, 7.5 GB 메모리 | n1-standard-2 |
m5.large |
D2s v3 |
| PgBouncer3 | 3 | 2 vCPU, 1.8 GB 메모리 | n1-highcpu-2 |
c5.large |
F2s v2 |
| 내부 로드 밸런서2 | 1 | 4 vCPU, 3.6 GB 메모리 | n1-highcpu-4 |
c5n.xlarge |
F4s v2 |
| Redis/Sentinel4 | 3 | 2 vCPU, 7.5 GB 메모리 | n1-standard-2 |
m5.large |
D2s v3 |
| Gitaly5, 6 | 3 | 4 vCPU, 15 GB 메모리 | n1-standard-4 |
m5.xlarge |
D4s v3 |
| Praefect5 | 3 | 2 vCPU, 1.8 GB 메모리 | n1-highcpu-2 |
c5.large |
F2s v2 |
| Praefect PostgreSQL3 | 1+ | 2 vCPU, 1.8 GB 메모리 | n1-highcpu-2 |
c5.large |
F2s v2 |
| Sidekiq7 | 2 | 4 vCPU, 15 GB 메모리 | n1-standard-4 |
m5.xlarge |
D2s v3 |
| GitLab Rails7 | 3 | 8 vCPU, 7.2 GB 메모리 | n1-highcpu-8 |
c5.2xlarge |
F8s v2 |
| 모니터링 노드 | 1 | 2 vCPU, 1.8 GB 메모리 | n1-highcpu-2 |
c5.large |
F2s v2 |
| 오브젝트 스토리지8 | - | - | - | - | - |
인스턴스 구성이 필요한 모든 PaaS 솔루션에서는 복원력 있는 클라우드 아키텍처 관행에 맞추어 서로 다른 가용 영역 세 곳에 최소 노드 세 개를 구성하기를 권장합니다.
소스 코드 보기
@startuml 3k
skinparam linetype ortho
card "External Load Balancer" as elb #6a9be7
card "Internal Load Balancer" as ilb #9370DB
together {
collections "GitLab Rails x3" as gitlab #32CD32
collections "Sidekiq x2" 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 x3" as redis_nodes #FF6347
}
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
요구 사항#
진행하기 전에 레퍼런스 아키텍처의 요구 사항을 검토합니다.
테스트 방법론#
60 RPS / 3k 사용자 레퍼런스 아키텍처는 가장 일반적인 워크플로를 수용하도록 설계되었습니다. GitLab은 다음 엔드포인트 처리량 목표를 기준으로 스모크 테스트와 성능 테스트를 정기적으로 수행합니다.
| 엔드포인트 유형 | 목표 처리량 |
|---|---|
| API | 60 RPS |
| Web | 6 RPS |
| Git (Pull) | 6 RPS |
| Git (Push) | 1 RPS |
이 목표는 CI 파이프라인과 기타 워크로드를 포함해, 지정된 사용자 수에 대한 전체 환경 부하를 반영하는 실제 고객 데이터를 기준으로 합니다. 이는 일반적인 워크로드 구성을 나타냅니다. 일반적이지 않은 워크로드 패턴에 대한 안내는 RPS 구성 이해를 참고합니다.
테스트 방법론에 대한 자세한 내용은 검증 및 테스트 결과 섹션을 참고합니다.
성능 고려 사항#
환경에 다음 중 하나가 해당하면 추가 조정이 필요할 수 있습니다.
이러한 경우 자세한 내용은 환경 확장을 참고합니다. 이러한 고려 사항이 해당한다고 생각되면 필요에 따라 추가 안내를 받을 수 있도록 문의합니다.
로드 밸런서 구성#
테스트 환경에서는 다음을 사용합니다.
- Linux 패키지 환경에는 HAProxy
- 클라우드 네이티브 하이브리드에는 Gateway API 또는 Ingress 구현을 갖춘 클라우드 제공업체의 동등한 서비스
구성 요소 설정#
최대 60 RPS 또는 3,000명 사용자를 수용하도록 GitLab과 그 구성 요소를 설정하는 방법은 다음과 같습니다.
- 외부 로드 밸런서를 구성하여 GitLab 애플리케이션 서비스 노드의 로드 밸런싱을 처리합니다.
- 내부 로드 밸런서를 구성하여 GitLab 애플리케이션 내부 연결의 로드 밸런싱을 처리합니다.
- 서비스 검색과 상태 확인을 위해 Consul을 구성합니다.
- GitLab의 데이터베이스인 PostgreSQL을 구성합니다.
- 데이터베이스 연결 풀링과 관리를 위해 PgBouncer를 구성합니다.
- 세션 데이터, 임시 캐시 정보, 백그라운드 job 큐를 저장하는 Redis를 구성합니다.
- Git 리포지터리에 대한 접근을 제공하는 Gitaly Cluster(Praefect)를 구성합니다.
- 백그라운드 job 처리를 위해 Sidekiq을 구성합니다.
- Puma, Workhorse, GitLab Shell을 실행하고 UI, API, HTTP/SSH를 통한 Git을 포함한 모든 프론트엔드 요청을 처리하도록 메인 GitLab Rails 애플리케이션을 구성합니다.
- GitLab 환경을 모니터링하도록 Prometheus를 구성합니다.
- 공유 데이터 객체에 사용하는 오브젝트 스토리지를 구성합니다.
- GitLab 인스턴스 전체에서 더 빠르고 고급 코드 검색을 하려면 고급 검색을 구성합니다(선택 사항).
서버는 동일한 10.6.0.0/24 사설 네트워크 범위에서 시작하며, 이 주소를 통해 서로 자유롭게 연결할 수 있습니다.
다음 목록은 각 서버와 할당된 IP를 설명합니다.
10.6.0.10: 외부 로드 밸런서10.6.0.11: Consul/Sentinel 110.6.0.12: Consul/Sentinel 210.6.0.13: Consul/Sentinel 310.6.0.21: PostgreSQL 기본10.6.0.22: PostgreSQL 보조 110.6.0.23: PostgreSQL 보조 210.6.0.31: PgBouncer 110.6.0.32: PgBouncer 210.6.0.33: PgBouncer 310.6.0.20: 내부 로드 밸런서10.6.0.61: Redis 기본10.6.0.62: Redis 복제본 110.6.0.63: Redis 복제본 210.6.0.51: Gitaly 110.6.0.52: Gitaly 210.6.0.93: Gitaly 310.6.0.131: Praefect 110.6.0.132: Praefect 210.6.0.133: Praefect 310.6.0.141: Praefect PostgreSQL 1 (비 HA)10.6.0.71: Sidekiq 110.6.0.72: Sidekiq 210.6.0.41: GitLab 애플리케이션 110.6.0.42: GitLab 애플리케이션 210.6.0.43: GitLab 애플리케이션 310.6.0.81: Prometheus
외부 로드 밸런서 구성#
멀티 노드 GitLab 구성에서는 트래픽을 애플리케이션 서버로 라우팅하기 위해 외부 로드 밸런서가 필요합니다.
사용할 로드 밸런서나 정확한 구성 방법은 GitLab 문서의 범위를 벗어나지만, 일반적인 요구 사항은 로드 밸런서를 참고합니다. 이 섹션에서는 선택한 로드 밸런서에 무엇을 구성해야 하는지를 중심으로 설명합니다.
준비 상태 확인#
외부 로드 밸런서가 기본 제공 모니터링 엔드포인트가 있는 정상 서비스로만 트래픽을 라우팅하도록 합니다. 준비 상태 확인은 모두 확인 대상 노드에 추가 구성이 필요하며, 그렇지 않으면 외부 로드 밸런서가 연결할 수 없습니다.
포트#
사용하는 기본 포트는 아래 표와 같습니다.
사용자 지정 도메인을 지원하는 GitLab Pages를 사용하는 경우
추가 포트 구성이 필요합니다.
GitLab Pages에는 별도의 가상 IP 주소가 필요합니다. /etc/gitlab/gitlab.rb의
pages_external_url이 새 가상 IP 주소를 가리키도록 DNS를 구성합니다. 자세한 내용은
GitLab Pages 문서를 참고합니다.
대체 SSH 포트#
일부 조직은 SSH 22번 포트를 여는 것을 금지하는 정책을 가지고 있습니다. 이 경우 사용자가 443번 포트에서 SSH를 사용할 수 있도록 대체 SSH 호스트 이름을 구성하는 것이 도움이 될 수 있습니다. 대체 SSH 호스트 이름에는 앞서 설명한 다른 GitLab HTTP 구성과 달리 새 가상 IP 주소가 필요합니다.
altssh.gitlab.example.com 같은 대체 SSH 호스트 이름에 대해 DNS를 구성합니다.
| LB 포트 | 백엔드 포트 | 프로토콜 |
|---|---|---|
| 443 | 22 | TCP |
SSL#
다음으로 고려할 사항은 환경에서 SSL을 어떻게 처리할 것인지입니다. 여러 가지 옵션이 있습니다.
- 애플리케이션 노드에서 SSL을 종료합니다.
- 로드 밸런서에서 SSL을 종료하며 백엔드 SSL은 사용하지 않습니다. 이 경우 로드 밸런서와 애플리케이션 노드 사이의 통신은 안전하지 않습니다.
- 로드 밸런서에서 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 구성에서는 PgBouncer 및 Gitaly Cluster(Praefect)에 대한 연결처럼, 구성된 경우 일부 내부 컴포넌트의 트래픽을 라우팅하기 위해 내부 로드 밸런서가 필요합니다.
사용할 로드 밸런서나 정확한 구성 방법은 GitLab 문서의 범위를 벗어나지만, 일반적인 요구 사항은 로드 밸런서를 참고합니다. 이 섹션에서는 선택한 로드 밸런서에 무엇을 구성해야 하는지를 중심으로 설명합니다.
다음 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 110.6.0.12: Consul 210.6.0.13: Consul 3
Consul을 구성하는 방법은 다음과 같습니다.
-
Consul을 호스팅할 서버에 SSH로 접속합니다.
-
원하는 Linux 패키지를 다운로드하여 설치합니다. 선택한 운영 체제용 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 합니다. 현재 설치와 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택합니다.
-
/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 버전을 실행하는, 신뢰할 수 있는 제공업체를 사용합니다. 다음 서비스는 잘 작동하는 것으로 알려져 있습니다.
고가용성과 데이터베이스 로드 밸런싱에 대한 안내를 포함한 자세한 내용은 다음을 참고합니다.
서드파티 외부 서비스를 사용하는 경우 다음을 수행합니다.
- 데이터베이스 요구 사항 문서에 따라 PostgreSQL을 설정합니다.
- 필요한 사용자 및 데이터베이스를 구성합니다.
- GitLab Rails 구성을 따라 GitLab 애플리케이션 서버에 적절한 연결 정보를 구성합니다.
Linux 패키지를 사용한 독립 실행형 PostgreSQL#
복제와 장애 조치를 갖춘 PostgreSQL 클러스터에 권장되는 Linux 패키지 구성에는 다음이 필요합니다.
-
최소 PostgreSQL 노드 3개
-
최소 Consul 서버 노드 3개
-
기본 데이터베이스의 읽기와 쓰기를 추적하고 처리하는 최소 PgBouncer 노드 3개
- PgBouncer 노드 간 요청을 분산하는 내부 로드 밸런서(TCP)
-
데이터베이스 로드 밸런싱 활성화
각 PostgreSQL 노드에 로컬 PgBouncer 서비스를 구성해야 합니다. 이는 기본을 추적하는 메인 PgBouncer 클러스터와는 별개입니다.
다음 IP를 예시로 사용합니다.
10.6.0.21: PostgreSQL 기본10.6.0.22: PostgreSQL 보조 110.6.0.23: PostgreSQL 보조 2
먼저 각 노드에 Linux GitLab 패키지를 설치해야 합니다.
선택한 운영 체제용 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 110.6.0.32: PgBouncer 210.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' pgbouncer_exporter['listen_address'] = '0.0.0.0:9188' -
처음 구성한 Linux 패키지 노드의
/etc/gitlab/gitlab-secrets.json파일을 복사하여 이 서버의 같은 이름 파일에 추가하거나 교체합니다. 구성하는 노드가 첫 번째 Linux 패키지 노드라면 이 단계를 건너뜁니다. -
변경 사항이 적용되도록 GitLab을 재구성합니다.
-
Consul이 PgBouncer를 다시 로드할 수 있도록
.pgpass파일을 생성합니다. 메시지가 표시되면 PgBouncer 비밀번호를 두 번 입력합니다.gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul -
각 노드가 현재 마스터와 통신하고 있는지 확인합니다.
gitlab-ctl pgb-console # You will be prompted for PGBOUNCER_PASSWORD비밀번호를 입력한 후
psql: ERROR: Auth failed오류가 발생하면 앞서 MD5 비밀번호 해시를 올바른 형식으로 생성했는지 확인합니다. 올바른 형식은 비밀번호와 사용자 이름을 이어 붙인PASSWORDUSERNAME입니다. 예를 들어pgbouncer사용자의 MD5 비밀번호 해시를 생성하는 데 필요한 텍스트는Sup3rS3cr3tpgbouncer입니다. -
콘솔 프롬프트가 표시되면 다음 쿼리를 실행합니다.
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) -
GitLab 서비스가 실행 중인지 확인합니다.
sudo gitlab-ctl status출력은 다음과 비슷해야 합니다.
run: consul: (pid 31530) 77150s; run: log: (pid 31106) 77182s run: logrotate: (pid 32613) 3357s; run: log: (pid 30107) 77500s run: node-exporter: (pid 31550) 77149s; run: log: (pid 30138) 77493s run: pgbouncer: (pid 32033) 75593s; run: log: (pid 31117) 77175s run: pgbouncer-exporter: (pid 31558) 77148s; run: log: (pid 31498) 77156s
Redis 구성#
확장 가능한 환경에서 Redis는 Primary x Replica 토폴로지와 장애 조치 절차를 감시하고 자동으로 시작하는 Redis Sentinel 서비스를 사용해 운영할 수 있습니다. 장애 조치 절차를 시작하도록 구성할 수 있습니다.
- Redis 클러스터는 각각 홀수 개인 3개 이상의 노드로 배포해야 합니다. Redis Sentinel이 쿼럼의 일부로 투표할 수 있도록 하기 위해서입니다. 클라우드 제공업체 서비스처럼 Redis를 외부에서 구성하는 경우에는 해당하지 않습니다.
- Redis는 주로 싱글 스레드로 동작하므로 CPU 코어를 늘려도 큰 이점이 없습니다. 이 아키텍처는 하나로 통합된 Redis 클러스터(노드 3개)를 사용하지만, 최적의 성능을 위해 Redis를 별도의 Cache 인스턴스와 Persistent 인스턴스(총 노드 6개)로 분리할 수 있습니다. Redis CPU가 포화 상태에 이르고 있다면 분리를 강력히 권장합니다. 자세한 내용은 확장 문서를 참고합니다.
Sentinel과 함께 사용하는 Redis에는 인증이 필요합니다. 자세한 내용은 Redis 보안 문서를 참고합니다. Redis 비밀번호와 엄격한 방화벽 규칙을 함께 사용해 Redis 서비스를 보호하기를 권장합니다. GitLab과 함께 Redis를 구성하기 전에 Redis Sentinel 문서를 반드시 읽고 토폴로지와 아키텍처를 충분히 이해하기를 강력히 권장합니다.
Redis 설정의 요구 사항은 다음과 같습니다.
- 모든 Redis 노드는 서로 통신할 수 있어야 하며, Redis(
6379) 및 Sentinel(26379) 포트를 통한 수신 연결을 허용해야 합니다(기본 포트를 변경하지 않은 경우). - GitLab 애플리케이션을 호스팅하는 서버가 Redis 노드에 접근할 수 있어야 합니다.
- 방화벽 같은 옵션을 사용해 외부 네트워크(인터넷)에서 노드에 접근하지 못하도록 보호합니다.
이 섹션에서는 GitLab과 함께 사용할 외부 Redis 클러스터를 구성하는 방법을 안내합니다. 다음 IP를 예시로 사용합니다.
10.6.0.61: Redis 기본10.6.0.62: Redis 복제본 110.6.0.63: Redis 복제본 2
자체 Redis 인스턴스 제공#
다음 안내에 따라 선택적으로 Redis 인스턴스용 서드파티 외부 서비스를 사용할 수 있습니다.
- 신뢰할 수 있는 제공업체나 솔루션을 사용해야 합니다. Google Memorystore와 AWS ElastiCache가 작동하는 것으로 알려져 있습니다.
- Redis Cluster 모드는 지원되지 않으며, HA를 갖춘 Redis Standalone은 지원됩니다.
- 사용자 환경에 맞게 Redis 제거 모드를 설정해야 합니다.
자세한 내용은 인프라 및 서비스를 참고합니다.
Redis 클러스터 구성#
이 섹션에서는 새 Redis 인스턴스를 설치하고 설정합니다.
기본 Redis 노드와 복제본 Redis 노드는 모두 redis['password']에 정의된
동일한 비밀번호가 필요합니다. 장애 조치 중에는 언제든지 Sentinel이 노드를 재구성하여
상태를 기본에서 복제본으로(또는 그 반대로) 변경할 수 있습니다.
기본 Redis 노드 구성#
-
Primary Redis 서버에 SSH로 접속합니다.
-
원하는 Linux 패키지를 다운로드하여 설치합니다. 선택한 운영 체제용 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 합니다. 현재 설치와 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택합니다.
-
/etc/gitlab/gitlab.rb를 편집하여 다음 내용을 추가합니다.# Specify server roles as 'redis_master_role' with Sentinel and the Consul agent 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 listens 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.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' redis['master_password'] = 'REDIS_PRIMARY_PASSWORD' ## Must be the same in every Redis node redis['master_name'] = 'gitlab-redis' ## 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 노드 구성#
-
복제본 Redis 서버에 SSH로 접속합니다.
-
원하는 Linux 패키지를 다운로드하여 설치합니다. 선택한 운영 체제용 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 합니다. 현재 설치와 동일한 버전 및 유형(Community 또는 Enterprise 에디션)을 선택합니다.
-
/etc/gitlab/gitlab.rb를 편집하여 다음 내용을 추가합니다.# Specify server roles as 'redis_sentinel_role' and 'redis_replica_role' 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. # You can also set bind to '0.0.0.0' which listens 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.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['password'] = 'REDIS_PRIMARY_PASSWORD' redis['master_password'] = 'REDIS_PRIMARY_PASSWORD' ## Must be the same in every Redis node redis['master_name'] = 'gitlab-redis' # 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)는 Git 리포지터리를 저장하기 위해 GitLab이 제공하고 권장하는 내결함성 솔루션입니다. 이 구성에서는 모든 Git 리포지터리가 클러스터의 모든 Gitaly 노드에 저장되며, 노드 하나가 기본으로 지정됩니다. 기본 노드가 다운되면 장애 조치가 자동으로 수행됩니다.
Gitaly 사양은 정상 상태인 사용 패턴과 리포지터리 크기의 높은 백분위수를 기준으로 합니다. 그러나 대규모 모노레포(수 기가바이트 이상)나 추가 워크로드가 있으면 환경 성능에 상당한 영향을 줄 수 있으며 추가 조정이 필요할 수 있습니다. 해당된다고 생각되면 필요에 따라 추가 안내를 받을 수 있도록 문의합니다.
Gitaly Cluster(Praefect)는 내결함성이라는 이점을 제공하지만, 설정과 관리가 더 복잡해집니다. Gitaly Cluster(Praefect)를 배포하기 전의 기술적 제한 사항과 고려 사항을 검토합니다.
다음 안내가 필요한 경우입니다.
- 대신 샤딩된 Gitaly를 구현하려면 이 섹션이 아니라 별도의 Gitaly 문서를 따릅니다. 동일한 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, 클라우드 네이티브 하이브리드)에서 작동합니다
- 설정과 운영 관리가 간단합니다
- 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
LISTENSQL 기능을 지원해야 합니다.
서드파티 구성에서는 Praefect의 데이터베이스를 메인 GitLab 데이터베이스와 같은 서버에 함께 둘 수 있습니다. 다만 Geo를 사용하는 경우 복제를 올바르게 처리하려면 별도의 데이터베이스 인스턴스가 필요합니다. 이 구성에서는 영향이 미미할 것이므로 메인 데이터베이스 설정의 사양을 변경할 필요가 없습니다.
신뢰할 수 있는 제공업체나 솔루션을 사용해야 합니다. Google Cloud SQL 과 Amazon RDS가 작동하는 것으로 알려져 있습니다. 다만 Amazon Aurora는 14.4.0부터 기본으로 활성화된 로드 밸런싱과 호환되지 않습니다.
자세한 내용은 인프라 및 서비스를 참고합니다.
데이터베이스를 설정한 후 구성 후 작업을 따릅니다.
Praefect PostgreSQL 구성 후 작업#
Praefect PostgreSQL 서버를 설정한 후에는 Praefect가 사용할 사용자와 데이터베이스를 구성해야 합니다.
사용자 이름은 praefect, 데이터베이스 이름은 praefect_production으로 지정하기를 권장하며, PostgreSQL에서 표준 방식으로 구성할 수 있습니다.
사용자의 비밀번호는 앞서 <praefect_postgresql_password>로 구성한 비밀번호와 같습니다.
Linux 패키지 PostgreSQL 구성에서는 다음과 같이 진행합니다.
-
Praefect PostgreSQL 노드에 SSH로 접속합니다.
-
관리자 권한으로 PostgreSQL 서버에 연결합니다. Linux 패키지에 기본으로 추가되므로 여기서는
gitlab-psql사용자를 사용해야 합니다.template1데이터베이스는 모든 PostgreSQL 서버에 기본으로 생성되므로 사용합니다./opt/gitlab/embedded/bin/psql -U gitlab-psql -d template1 -h POSTGRESQL_SERVER_ADDRESS -
새 사용자
praefect를 생성합니다.<praefect_postgresql_password>를 교체합니다.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를 구성하는 방법을 설명합니다.
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)를 사용하는 경우 다른 이름을 사용해야 할 수 있습니다.
자세한 내용은 Gitaly Cluster(Praefect) 문서를 참고합니다.
다음 IP를 예시로 사용합니다.
10.6.0.131: Praefect 110.6.0.132: Praefect 210.6.0.133: Praefect 3
Praefect 노드를 구성하려면 각 노드에서 다음을 수행합니다.
-
Praefect 서버에 SSH로 접속합니다.
-
원하는 Linux 패키지를 다운로드하여 설치합니다. 선택한 운영 체제용 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 합니다.
-
/etc/gitlab/gitlab.rb파일을 편집하여 Praefect를 구성합니다.[!note]
virtual_storages에서default항목은 GitLab에 필요하므로 제거할 수 없습니다.# 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 the 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로 변경합니다. -
데이터베이스 마이그레이션이 업그레이드 시 자동으로 실행되지 않고 재구성 중에만 실행되도록 다음을 실행합니다.
sudo touch /etc/gitlab/skip-auto-reconfigure- 변경 사항이 적용되고 Praefect 데이터베이스 마이그레이션이 실행되도록 GitLab을 재구성합니다.
-
-
다른 모든 Praefect 노드에서는 변경 사항이 적용되도록 GitLab을 재구성합니다.
Gitaly 구성#
클러스터를 구성하는 Gitaly 서버 노드에는 데이터와 부하에 따라 달라지는 요구 사항이 있습니다.
Gitaly 사양은 정상 상태인 사용 패턴과 리포지터리 크기의 높은 백분위수를 기준으로 합니다. 그러나 대규모 모노레포(수 기가바이트 이상)나 추가 워크로드가 있으면 환경 성능에 상당한 영향을 줄 수 있으며 추가 조정이 필요할 수 있습니다. 해당된다고 생각되면 필요에 따라 추가 안내를 받을 수 있도록 문의합니다.
Gitaly에는 Gitaly 스토리지에 대한 특정 디스크 요구 사항이 있습니다.
Gitaly는 기본적으로 네트워크 트래픽이 암호화되지 않으므로 Gitaly 서버를 공용 인터넷에 노출해서는 안 됩니다. 방화벽을 사용해 Gitaly 서버에 대한 접근을 제한하기를 강력히 권장합니다. 다른 방법으로 TLS를 사용할 수 있습니다.
Gitaly를 구성할 때는 다음 사항에 유의합니다.
gitaly['configuration'][:storage]는 해당 Gitaly 노드의 스토리지 경로를 반영하도록 구성해야 합니다auth_token은praefect_internal_token과 같아야 합니다
다음 IP를 예시로 사용합니다.
10.6.0.91: Gitaly 110.6.0.92: Gitaly 210.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', # Gitaly Auth Token # Should be the same as praefect_internal_token auth: { # ... token: '<praefect_internal_token>', }, # 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 pack_objects_cache: { # ... 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_address에tls://URL 스킴을 사용합니다. - 자동으로 제공되지 않으므로 직접 인증서를 준비합니다. 각 Praefect 서버에 해당하는 인증서를 그 Praefect 서버에 설치해야 합니다.
또한 인증서 또는 해당 인증 기관을 Gitaly 서버 전체와 이와 통신하는 모든 Praefect 클라이언트에 설치해야 합니다. 절차는 GitLab 사용자 지정 인증서 구성에 설명되어 있으며(아래에서 다시 설명합니다) 이를 따릅니다.
다음 사항에 유의합니다.
- 인증서에는 Praefect 서버에 접근할 때 사용하는 주소가 지정되어 있어야 합니다. 호스트 이름이나 IP 주소를 Subject Alternative Name으로 인증서에 추가해야 합니다.
- Praefect 서버는 암호화되지 않은 수신 주소
listen_addr와 암호화된 수신 주소tls_listen_addr를 동시에 구성할 수 있습니다. 이렇게 하면 필요한 경우 암호화되지 않은 트래픽에서 암호화된 트래픽으로 단계적으로 전환할 수 있습니다. 암호화되지 않은 리스너를 비활성화하려면praefect['configuration'][:listen_addr] = nil을 설정합니다. - 내부 로드 밸런서는 TLS 연결을 처리하도록 구성해야 합니다. 로드 밸런서가 암호화된 트래픽을 종료하지 않고 백엔드로 전달하는 TLS 패스스루를 지원하도록 구성합니다. 패스스루/직접 서버 반환(DSR) 로드 밸런서는 사용하지 않습니다. 로드 밸런서는 적절한 로드 밸런싱과 상태 확인을 유지하기 위해 연결을 능동적으로 프록시해야 합니다.
Praefect에 TLS를 구성하는 방법은 다음과 같습니다.
-
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.rb의gitlab_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.71: Sidekiq 110.6.0.72: Sidekiq 2
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['master_name'] = 'gitlab-redis' ## The same password for Redis authentication you set up for the master node. redis['master_password'] = '<redis_primary_password>' ## A list of sentinels with `host` and `port` gitlab_rails['redis_sentinels'] = [ {'host' => '10.6.0.11', 'port' => 26379}, {'host' => '10.6.0.12', 'port' => 26379}, {'host' => '10.6.0.13', 'port' => 26379}, ] # Gitaly Cluster ## 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.40' # 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.81/32', '127.0.0.0/8'] gitlab_rails['prometheus_address'] = '10.6.0.81:9090' # 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 패키지 노드라면 이 단계를 건너뜁니다. -
데이터베이스 마이그레이션이 업그레이드 시 자동으로 실행되지 않고 재구성 중에만 실행되도록 다음을 실행합니다.
sudo touch /etc/gitlab/skip-auto-reconfigureGitLab Rails 구성 후 작업 섹션에 설명된 대로 지정된 노드 하나만 마이그레이션을 처리해야 합니다.
-
파일을 저장한 다음 GitLab을 재구성합니다.
-
GitLab 서비스가 실행 중인지 확인합니다.
sudo gitlab-ctl status출력은 다음과 비슷해야 합니다.
run: consul: (pid 30114) 77353s; run: log: (pid 29756) 77367s run: logrotate: (pid 9898) 3561s; run: log: (pid 29653) 77380s run: node-exporter: (pid 30134) 77353s; run: log: (pid 29706) 77372s run: sidekiq: (pid 30142) 77351s; run: log: (pid 29638) 77386s
GitLab Rails 구성#
이 섹션에서는 GitLab 애플리케이션(Rails) 컴포넌트를 구성하는 방법을 설명합니다.
Rails에는 Redis, PostgreSQL, Gitaly 인스턴스에 대한 연결이 필요합니다. 또한 권장 사항에 따라 오브젝트 스토리지에 대한 연결도 필요합니다.
데이터 객체에는 NFS 대신 오브젝트 스토리지를 사용하기를 권장하므로 다음 예시에는 오브젝트 스토리지 구성이 포함되어 있습니다.
각 노드에서 다음을 수행합니다.
-
원하는 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 ## Must be the same in every sentinel node redis['master_name'] = 'gitlab-redis' ## The same password for Redis authentication you set up for the Redis primary node. redis['master_password'] = '<redis_primary_password>' ## A list of sentinels with `host` and `port` gitlab_rails['redis_sentinels'] = [ {'host' => '10.6.0.11', 'port' => 26379}, {'host' => '10.6.0.12', 'port' => 26379}, {'host' => '10.6.0.13', 'port' => 26379} ] ## Enable service discovery for Prometheus consul['enable'] = true consul['monitoring_service_discovery'] = true # 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' sidekiq['listen_address'] = "0.0.0.0" puma['listen'] = '0.0.0.0' ## 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), } # 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.81/32', '127.0.0.0/8'] nginx['status']['options']['allow'] = ['10.6.0.81/32', '127.0.0.0/8'] gitlab_rails['prometheus_address'] = '10.6.0.81:9090' ## Uncomment and edit the following options if you have set up NFS ## ## Prevent GitLab from starting if NFS data mounts are not available ## #high_availability['mountpoint'] = '/var/opt/gitlab/git-data' ## ## Ensure UIDs and GIDs match between servers for permissions via NFS ## #user['uid'] = 9000 #user['gid'] = 9000 #web_server['uid'] = 9001 #web_server['gid'] = 9001 #registry['uid'] = 9002 #registry['gid'] = 9002 # 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를 사용하는 경우
gitlab_rails['repositories_storages']항목을tcp가 아니라tls로 구성했는지 확인합니다.# 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 패키지 노드라면 이 단계를 건너뜁니다. -
SSH 호스트 키(이름 형식이 모두
/etc/ssh/ssh_host_*_key*인 파일)를 처음 구성한 Rails 노드에서 복사하여 이 서버의 같은 이름 파일에 추가하거나 교체합니다. 이렇게 하면 사용자가 로드 밸런싱되는 Rails 노드에 접속할 때 호스트 불일치 오류가 발생하지 않습니다. 첫 번째 Linux 패키지 노드를 구성하는 경우 이 단계를 건너뜁니다. -
데이터베이스 마이그레이션이 업그레이드 시 자동으로 실행되지 않고 재구성 중에만 실행되도록 다음을 실행합니다.
sudo touch /etc/gitlab/skip-auto-reconfigureGitLab Rails 구성 후 작업 섹션에 설명된 대로 지정된 노드 하나만 마이그레이션을 처리해야 합니다.
-
변경 사항이 적용되도록 GitLab을 재구성합니다.
-
증분 로깅을 활성화합니다.
-
sudo gitlab-rake gitlab:gitaly:check를 실행하여 노드가 Gitaly에 연결할 수 있는지 확인합니다. -
로그를 실시간으로 확인하여 요청을 살펴봅니다.
sudo gitlab-ctl tail gitaly -
GitLab 서비스가 실행 중인지 확인합니다.
sudo gitlab-ctl status출력은 다음과 비슷해야 합니다.
run: consul: (pid 4890) 8647s; run: log: (pid 29962) 79128s run: gitlab-exporter: (pid 4902) 8647s; run: log: (pid 29913) 79134s run: gitlab-workhorse: (pid 4904) 8646s; run: log: (pid 29713) 79155s run: logrotate: (pid 12425) 1446s; run: log: (pid 29798) 79146s run: nginx: (pid 4925) 8646s; run: log: (pid 29726) 79152s run: node-exporter: (pid 4931) 8645s; run: log: (pid 29855) 79140s run: puma: (pid 4936) 8645s; run: log: (pid 29656) 79161s
external_url에 앞선 예시처럼 https를 지정하면
GitLab은 SSL 인증서가 /etc/gitlab/ssl/에 있을 것으로 기대합니다. 인증서가
없으면 NGINX가 시작되지 않습니다. 자세한 내용은
HTTPS 문서를 참고합니다.
GitLab Rails 구성 후 작업#
-
모든 마이그레이션이 실행되었는지 확인합니다.
gitlab-rake gitlab:db:configure이 작업을 하려면 Rails 노드가 기본 데이터베이스에 직접 연결하도록 구성해야 합니다. PgBouncer를 우회하는 방식입니다. 마이그레이션이 완료된 후에는 노드가 다시 PgBouncer를 거치도록 구성해야 합니다.
Prometheus 구성#
Linux 패키지를 사용해 Prometheus를 실행하는 독립 실행형 모니터링 노드를 구성할 수 있습니다.
-
모니터링 노드에 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 서비스가 실행 중인지 확인합니다.
sudo gitlab-ctl status출력은 다음과 비슷해야 합니다.
run: consul: (pid 31637) 17337s; run: log: (pid 29748) 78432s run: logrotate: (pid 31809) 2936s; run: log: (pid 29581) 78462s run: nginx: (pid 31665) 17335s; run: log: (pid 29556) 78468s run: prometheus: (pid 31672) 17335s; run: log: (pid 29633) 78456s
오브젝트 스토리지 구성#
GitLab은 다양한 유형의 데이터를 보관하기 위해 오브젝트 스토리지 서비스를 사용하는 것을 지원합니다. 데이터 객체에는 NFS보다 오브젝트 스토리지를 사용하기를 권장하며, 일반적으로 대규모 환경에서 더 좋습니다. 오브젝트 스토리지는 일반적으로 성능, 안정성, 확장성이 훨씬 뛰어나기 때문입니다. 자세한 내용은 인프라 및 서비스를 참고합니다.
GitLab에서 오브젝트 스토리지 구성을 지정하는 방법은 두 가지입니다.
- 통합 형식(Consolidated form): 지원되는 모든 객체 유형이 하나의 자격 증명을 공유합니다.
- 스토리지별 형식(Storage-specific form): 각 객체가 자체 오브젝트 스토리지 연결 및 구성을 정의합니다.
다음 예시에서는 사용할 수 있는 경우 통합 형식을 사용합니다.
GitLab에는 데이터 유형별로 별도의 버킷을 사용하는 방식을 권장합니다. 이렇게 하면 GitLab이 저장하는 여러 유형의 데이터 간에 충돌이 발생하지 않습니다. 향후 단일 버킷 사용을 지원할 계획이 있습니다.
증분 로깅 활성화#
GitLab Runner는 job 로그를 청크 단위로 반환하며, Linux 패키지는 통합 오브젝트 스토리지를 사용하는 경우에도 이 로그를 기본적으로 디스크의 /var/opt/gitlab/gitlab-ci/builds에 임시로 캐시합니다. 기본 구성에서는 이 디렉터리를 모든 GitLab Rails 및 Sidekiq 노드에서 NFS로 공유해야 합니다.
NFS로 job 로그를 공유하는 방식도 지원되지만, 증분 로깅을 활성화하여 NFS를 사용할 필요가 없도록 합니다(NFS 노드를 배포하지 않은 경우에는 필수입니다). 증분 로깅은 job 로그의 임시 캐싱에 디스크 공간 대신 Redis를 사용합니다.
고급 검색 구성#
Elasticsearch를 활용하고 고급 검색을 활성화하면 GitLab 인스턴스 전체에서 더 빠르고 고급 코드 검색을 사용할 수 있습니다.
Elasticsearch 클러스터 설계와 요구 사항은 사용자의 데이터에 따라 달라집니다. 인스턴스와 함께 Elasticsearch 클러스터를 설정하는 권장 모범 사례는 다음에서 확인합니다. 최적의 클러스터 구성 선택
사용자 수가 적은 환경에서 지원되는 수정 사항(HA)#
60 RPS 또는 3,000명 사용자용 GitLab 레퍼런스 아키텍처는 고가용성(HA)을 달성할 수 있도록 권장하는 가장 작은 규모입니다. 그러나 더 적은 사용자나 더 낮은 RPS를 처리하면서 HA를 유지해야 하는 환경에서는, 복잡성과 비용을 줄이기 위해 이 아키텍처에 적용할 수 있는 지원되는 수정 사항이 몇 가지 있습니다.
GitLab에서 HA를 달성하려면 결국 60 RPS 또는 3,000명 사용자 아키텍처의 구성이 필요하다는 점에 유의합니다. 각 컴포넌트에는 다양한 고려 사항과 따라야 할 규칙이 있으며, 이 아키텍처는 이 모두를 충족합니다. 이 아키텍처의 더 작은 버전도 근본적으로 같지만 성능 요구 사항이 더 작습니다. 다음 수정 사항이 지원됩니다.
아래에 명시되지 않은 경우, 사용자 수가 적은 환경에서 다른 수정 사항은 지원되지 않습니다.
- 노드 사양 낮추기: 사용자 수에 따라 권장되는 모든 노드 사양을 원하는 만큼 낮출 수 있습니다. 다만 일반 요구 사항보다 낮추지 않기를 권장합니다.
- 특정 노드 통합: 다음 컴포넌트는 같은 노드에 통합하여 성능을 일부 희생하는 대신 복잡성을 줄일 수 있습니다.
- GitLab Rails 및 Sidekiq: Sidekiq 노드를 제거하고 대신 GitLab Rails 노드에서 해당 컴포넌트를 활성화할 수 있습니다.
- PostgreSQL 및 PgBouncer: PgBouncer 노드를 제거하고 대신 PostgreSQL 노드에서 PgBouncer를 활성화한 후 내부 로드 밸런서가 해당 노드를 가리키게 할 수 있습니다. 다만 데이터베이스 로드 밸런싱을 활성화하려면 별도의 PgBouncer 배열이 여전히 필요합니다.
- 노드 수 줄이기: 일부 노드 유형은 합의가 필요하지 않으므로 더 적은 노드로 실행할 수 있습니다(다만 이중화를 위해 둘 이상이어야 합니다).
- GitLab Rails 및 Sidekiq: 상태를 저장하지 않는 서비스에는 최소 노드 수가 없습니다. 이중화에는 두 개면 충분합니다.
- PostgreSQL 및 PgBouncer: 쿼럼이 반드시 필요하지는 않습니다. 이중화에는 PostgreSQL 노드 2개와 PgBouncer 노드 2개면 충분합니다.
- Consul, Redis Sentinel, Praefect: 투표 쿼럼을 위해 홀수 개, 최소 3개의 노드가 필요합니다.
- 특정 컴포넌트를 신뢰할 수 있는 클라우드 PaaS 솔루션에서 실행: 다음 컴포넌트는 신뢰할 수 있는 클라우드 제공업체의 PaaS 솔루션에서 실행할 수 있습니다. 이렇게 하면 의존하는 다른 컴포넌트도 제거할 수 있습니다.
- PostgreSQL: Google Cloud SQL이나 Amazon RDS 같은 신뢰할 수 있는 클라우드 PaaS 솔루션에서 실행할 수 있습니다. 이 구성에서는 PgBouncer 노드와 Consul 노드가 더 이상 필요하지 않습니다.
- Prometheus 자동 검색이 필요한 경우 Consul이 여전히 필요할 수 있으며, 그렇지 않으면 모든 노드에 대해 스크레이프 구성을 수동으로 추가해야 합니다.
- Redis: Google Memorystore와 AWS ElastiCache 같은 신뢰할 수 있는 클라우드 PaaS 솔루션에서 실행할 수 있습니다. 이 구성에서는 Redis Sentinel이 더 이상 필요하지 않습니다.
- PostgreSQL: Google Cloud SQL이나 Amazon RDS 같은 신뢰할 수 있는 클라우드 PaaS 솔루션에서 실행할 수 있습니다. 이 구성에서는 PgBouncer 노드와 Consul 노드가 더 이상 필요하지 않습니다.
Helm Charts를 사용하는 클라우드 네이티브 하이브리드 레퍼런스 아키텍처(대안)#
대안으로 특정 GitLab 컴포넌트를 Kubernetes에서 실행할 수 있습니다. 다음 서비스가 지원됩니다.
- GitLab Rails
- Sidekiq
- NGINX
- Toolbox
- Migrations
- Prometheus
하이브리드 설치는 클라우드 네이티브 방식과 기존 컴퓨트 배포 방식의 이점을 모두 활용합니다. 이를 통해 상태를 저장하지 않는 컴포넌트는 클라우드 네이티브 워크로드 관리의 이점을 얻고, 상태를 저장하는 컴포넌트는 Linux 패키지 설치와 함께 컴퓨트 VM에 배포되어 지속성이 높아지는 이점을 얻습니다.
설정 방법은 Helm Charts 고급 구성 문서를 참고하며, Kubernetes와 백엔드 컴포넌트 사이에서 어떤 GitLab 시크릿을 동기화해야 하는지에 대한 안내도 포함되어 있습니다.
이는 고급 구성입니다. Kubernetes에서 서비스를 실행하는 일은 복잡하기로 잘 알려져 있습니다. 이 구성은 Kubernetes에 대한 충분한 실무 지식과 경험이 있는 경우에만 권장합니다. 이 섹션의 나머지 부분은 이를 전제로 합니다.
Kubernetes에서의 Gitaly 제공 여부, 제한 사항, 배포 시 고려 사항은 Kubernetes에서의 Gitaly를 참고합니다.
클러스터 토폴로지#
다음 표와 다이어그램은 앞서 설명한 일반 환경과 같은 형식으로 하이브리드 환경을 설명합니다.
먼저 Kubernetes에서 실행되는 컴포넌트입니다. 이들은 여러 노드 그룹에 걸쳐 실행되며, 최소 CPU 및 메모리 요구 사항을 지키는 한 전체 구성은 원하는 대로 변경할 수 있습니다.
| 컴포넌트 노드 그룹 | 목표 노드 풀 합계 | GCP 예시 | AWS 예시 |
|---|---|---|---|
| Webservice | 16 vCPU 20 GB 메모리(요청) 28 GB 메모리(제한) |
2 x n1-standard-16 |
2 x c5.4xlarge |
| Sidekiq | 7.2 vCPU 16 GB 메모리(요청) 32 GB 메모리(제한) |
3 x n1-standard-4 |
3 x m5.xlarge |
| 지원 서비스 | 4 vCPU 15 GB 메모리 |
2 x n1-standard-2 |
2 x m5.large |
- 이 구성에서는 Google Kubernetes Engine(GKE)과 Amazon Elastic Kubernetes Service(EKS)를 정기적으로 테스트하며 권장합니다. 다른 Kubernetes 서비스도 작동할 수 있지만 결과는 다를 수 있습니다.
- 머신 유형 예시는 설명을 위해 제공됩니다. 이 유형들은 검증 및 테스트에 사용되지만 권장 기본값으로 의도된 것은 아닙니다. 나열된 요구 사항을 충족하는 다른 머신 유형으로 전환할 수 있습니다. 자세한 내용은 지원되는 머신 유형을 참고합니다.
- Webservice와 Sidekiq의 목표 노드 풀 합계는 GitLab 컴포넌트만을 기준으로 합니다. 선택한 Kubernetes 제공업체의 시스템 프로세스에는 추가 리소스가 필요합니다. 제시된 예시는 이를 고려한 것입니다.
- 지원 서비스의 목표 노드 풀 합계는 GitLab 배포를 지원하는 여러 리소스와, 요구 사항에 따라 추가로 배포할 수 있는 모든 배포를 수용할 수 있도록 일반적인 기준으로 제시됩니다. 다른 노드 풀과 마찬가지로 선택한 Kubernetes 제공업체의 시스템 프로세스에도 리소스가 필요합니다. 제시된 예시는 이를 고려한 것입니다.
- 프로덕션 배포에서는 Pod를 특정 노드에 할당할 필요가 없습니다. 다만 복원력 있는 클라우드 아키텍처 관행에 맞추어 각 풀에 서로 다른 가용 영역에 분산된 노드를 여러 개 두기를 권장합니다.
- 효율성을 위해 Cluster Autoscaler 같은 자동 확장을 활성화하는 것이 좋지만, 지속적인 성능을 보장하기 위해 일반적으로 Webservice 및 Sidekiq Pod의 하한을 75%로 목표하기를 권장합니다.
다음은 Linux 패키지를 사용하는 고정 컴퓨트 VM(또는 해당하는 경우 외부 PaaS 서비스)에서 실행되는 백엔드 컴포넌트입니다.
| 서비스 | 노드 수 | 구성 | GCP 예시13 | AWS 예시13 |
|---|---|---|---|---|
| Consul14 | 3 | 2 vCPU, 1.8 GB 메모리 | n1-highcpu-2 |
c5.large |
| PostgreSQL14 | 3 | 2 vCPU, 7.5 GB 메모리 | n1-standard-2 |
m5.large |
| PgBouncer14 | 3 | 2 vCPU, 1.8 GB 메모리 | n1-highcpu-2 |
c5.large |
| 내부 로드 밸런서15 | 1 | 4 vCPU, 3.6 GB 메모리 | n1-highcpu-4 |
c5n.xlarge |
| Redis/Sentinel16 | 3 | 2 vCPU, 7.5 GB 메모리 | n1-standard-2 |
m5.large |
| Gitaly17, 18 | 3 | 4 vCPU, 15 GB 메모리 | n1-standard-4 |
m5.xlarge |
| Praefect17 | 3 | 2 vCPU, 1.8 GB 메모리 | n1-highcpu-2 |
c5.large |
| Praefect PostgreSQL14 | 1+ | 2 vCPU, 1.8 GB 메모리 | n1-highcpu-2 |
c5.large |
| 오브젝트 스토리지19 | - | - | - | - |
인스턴스 구성이 필요한 모든 PaaS 솔루션에서는 복원력 있는 클라우드 아키텍처 관행에 맞추어 서로 다른 가용 영역 세 곳에 최소 노드 세 개를 구성하기를 권장합니다.
소스 코드 보기
@startuml 3k
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 x3" as redis_nodes #FF6347
}
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
Kubernetes 컴포넌트 목표#
다음 섹션에서는 Kubernetes에 배포되는 GitLab 컴포넌트에 사용하는 목표를 설명합니다.
Webservice#
각 Webservice Pod(Puma 및 Workhorse)는 다음 구성으로 실행하기를 권장합니다.
- Puma 워커 4개
- 4 vCPU
- 5 GB 메모리(요청)
- 7 GB 메모리(제한)
60 RPS 또는 3,000명 사용자에는 전체 Puma 워커 수를 약 16개로 하기를 권장하며, 따라서 Webservice Pod를 4개 이상 실행하기를 권장합니다.
Webservice 리소스 사용량에 대한 자세한 내용은 Charts 문서의 Webservice 리소스를 참고합니다.
Gateway API / Ingress#
Gateway API 또는 Ingress 컨트롤러 Pod를 Webservice 노드 전체에 DaemonSet으로 배포하는 것도 권장합니다. 이렇게 하면 컨트롤러가 담당하는 Webservice Pod에 맞춰 동적으로 확장되며, 더 큰 머신 유형이 일반적으로 갖는 높은 네트워크 대역폭을 활용할 수 있습니다.
엄격한 요구 사항은 아닙니다. Gateway API 또는 Ingress 컨트롤러 Pod는 웹 트래픽을 처리할 충분한 리소스가 있다면 원하는 대로 배포할 수 있습니다.
Sidekiq#
각 Sidekiq Pod는 다음 구성으로 실행하기를 권장합니다.
- Sidekiq 워커 1개
- 900m vCPU
- 2 GB 메모리(요청)
- 4 GB 메모리(제한)
앞서 설명한 표준 배포와 마찬가지로, 여기서는 초기 목표로 Sidekiq 워커 8개를 사용했습니다. 특정 워크플로에 따라 추가 워커가 필요할 수 있습니다.
Sidekiq 리소스 사용량에 대한 자세한 내용은 Charts 문서의 Sidekiq 리소스를 참고합니다.
지원 서비스#
지원 서비스 노드 풀은 Webservice 및 Sidekiq 풀에 필요하지 않은 모든 지원 배포를 수용하도록 설계되었습니다.
여기에는 클라우드 제공업체 구현과 관련된 여러 배포와 GitLab Shell 같은 GitLab 지원 배포가 포함됩니다.
Container Registry, Pages, Monitoring 같은 추가 배포는 가능하면 Webservice나 Sidekiq 풀이 아니라 지원 서비스 노드 풀에 배포합니다. 지원 서비스 노드 풀은 여러 추가 배포를 수용하도록 설계되었습니다. 다만 배포가 제시된 풀에 맞지 않는다면 그에 맞게 노드 풀을 늘릴 수 있습니다. 반대로 사용 사례에서 풀이 과다 프로비저닝되어 있다면 그에 맞게 줄일 수 있습니다.
예시 구성 파일#
60 RPS 또는 3,000명 사용자 레퍼런스 아키텍처 구성에 대한 GitLab Helm Charts 예시는 Charts 프로젝트에서 확인할 수 있습니다.
다음 단계#
이 가이드를 따르면 핵심 기능이 구성된 새 GitLab 환경이 준비됩니다.
요구 사항에 따라 GitLab의 추가 선택 기능을 구성할 수 있습니다. 자세한 내용은 GitLab 설치 후 단계를 참고합니다.
환경과 요구 사항에 따라 원하는 추가 기능을 설정하기 위해 추가 하드웨어 요구 사항이나 조정이 필요할 수 있습니다. 자세한 내용은 개별 페이지를 참고합니다.
Footnotes
-
머신 유형 예시는 설명을 위해 제공됩니다. 이 유형들은 검증 및 테스트에 사용되지만 권장 기본값으로 의도된 것은 아닙니다. 나열된 요구 사항을 충족하는 다른 머신 유형으로 전환할 수 있으며, 사용 가능한 경우 ARM 변형도 지원됩니다. 자세한 내용은 지원되는 머신 유형을 참고합니다. ↩ ↩2 ↩3
-
HA 기능을 제공할 수 있는, 신뢰할 수 있는 서드파티 로드 밸런서 또는 서비스(LB PaaS)와 함께 실행하기를 권장합니다. 규모는 선택한 로드 밸런서와 네트워크 대역폭 같은 추가 요인에 따라 달라집니다. ↩ ↩2
-
선택적으로 신뢰할 수 있는 서드파티 외부 PaaS PostgreSQL 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 PostgreSQL 인스턴스 제공을 참고합니다. ↩ ↩2 ↩3 ↩4
-
선택적으로 신뢰할 수 있는 서드파티 외부 PaaS Redis 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 Redis 인스턴스 제공을 참고합니다. ↩
-
Gitaly Cluster(Praefect)는 내결함성이라는 이점을 제공하지만, 설정과 관리가 더 복잡해집니다. Gitaly Cluster(Praefect)를 배포하기 전의 기술적 제한 사항과 고려 사항을 검토합니다. 샤딩된 Gitaly를 원하는 경우 이전 표에서
Gitaly에 나열된 것과 같은 사양을 사용합니다. ↩ ↩2 -
Gitaly 사양은 정상 상태인 사용 패턴과 리포지터리 크기의 높은 백분위수를 기준으로 합니다. 그러나 대규모 모노레포(수 기가바이트 이상)나 추가 워크로드가 있으면 Git과 Gitaly 성능에 크게 영향을 줄 수 있으며, 추가 조정이 필요할 가능성이 높습니다. ↩
-
이 컴포넌트는 상태 저장 데이터를 저장하지 않으므로 Auto Scaling Group(ASG)에 배치할 수 있습니다. 그러나 클라우드 네이티브 하이브리드 구성을 일반적으로 더 권장합니다. 마이그레이션과 Mailroom 같은 일부 컴포넌트는 노드 한 대에서만 실행할 수 있으며, 이는 Kubernetes에서 더 잘 처리되기 때문입니다. ↩ ↩2
-
신뢰할 수 있는 클라우드 제공업체 또는 자체 관리 솔루션에서 실행해야 합니다. 자세한 내용은 오브젝트 스토리지 구성을 참고합니다. ↩
-
웹 터미널 지원을 위해서는 로드 밸런서가 WebSocket 연결을 올바르게 처리해야 합니다.
HTTP 또는 HTTPS 프록시를 사용하는 경우, 로드 밸런서가
Connection및Upgradehop-by-hop 헤더를 통과시키도록 구성되어야 한다는 뜻입니다. 자세한 내용은 웹 터미널 통합 가이드를 참고합니다. ↩ ↩2 -
443 포트에 HTTPS 프로토콜을 사용하는 경우 로드 밸런서에 SSL 인증서를 추가해야 합니다. GitLab 애플리케이션 서버에서 SSL을 종료하려면 TCP 프로토콜을 사용합니다. ↩
-
GitLab Pages의 백엔드 포트는
gitlab_pages['external_http']및gitlab_pages['external_https']설정에 따라 달라집니다. 자세한 내용은 GitLab Pages 문서를 참고합니다. ↩ ↩2 -
GitLab Pages의 443 포트에는 항상 TCP 프로토콜을 사용해야 합니다. 사용자는 사용자 지정 SSL로 사용자 지정 도메인을 구성할 수 있는데, 로드 밸런서에서 SSL을 종료하면 이를 사용할 수 없습니다. ↩
-
머신 유형 예시는 설명을 위해 제공됩니다. 이 유형들은 검증 및 테스트에 사용되지만 권장 기본값으로 의도된 것은 아닙니다. 나열된 요구 사항을 충족하는 다른 머신 유형으로 전환할 수 있으며, 사용 가능한 경우 ARM 변형도 지원됩니다. 자세한 내용은 지원되는 머신 유형을 참고합니다. ↩ ↩2
-
선택적으로 신뢰할 수 있는 서드파티 외부 PaaS PostgreSQL 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 PostgreSQL 인스턴스 제공을 참고합니다. ↩ ↩2 ↩3 ↩4
-
HA 기능을 제공할 수 있는, 신뢰할 수 있는 서드파티 로드 밸런서 또는 서비스(LB PaaS)와 함께 실행하기를 권장합니다. 규모는 선택한 로드 밸런서와 네트워크 대역폭 같은 추가 요인에 따라 달라집니다. ↩
-
선택적으로 신뢰할 수 있는 서드파티 외부 PaaS Redis 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 Redis 인스턴스 제공을 참고합니다. ↩
-
Gitaly Cluster(Praefect)는 내결함성이라는 이점을 제공하지만, 설정과 관리가 더 복잡해집니다. Gitaly Cluster(Praefect)를 배포하기 전의 기술적 제한 사항과 고려 사항을 검토합니다. 샤딩된 Gitaly를 원하는 경우 이전 표에서
Gitaly에 나열된 것과 같은 사양을 사용합니다. ↩ ↩2 -
Gitaly 사양은 정상 상태인 사용 패턴과 리포지터리 크기의 높은 백분위수를 기준으로 합니다. 그러나 대규모 모노레포(수 기가바이트 이상)나 추가 워크로드가 있으면 Git과 Gitaly 성능에 크게 영향을 줄 수 있으며, 추가 조정이 필요할 가능성이 높습니다. ↩
-
신뢰할 수 있는 클라우드 제공업체 또는 자체 관리 솔루션에서 실행해야 합니다. 자세한 내용은 오브젝트 스토리지 구성을 참고합니다. ↩