InfoGrab DocsInfoGrab Docs

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

요약

이 페이지는 실제 데이터를 기반으로, 수동 및 자동 사용을 합쳐 최대 2,000명 사용자의 일반적인 피크 부하인 초당 40개 요청(RPS)을 목표로 설계된 GitLab 참조 아키텍처를 설명합니다. 전체 참조 아키텍처 목록은 사용 가능한 참조 아키텍처를 참고합니다.

이 페이지는 실제 데이터를 기반으로, 수동 및 자동 사용을 합쳐 최대 2,000명 사용자의 일반적인 피크 부하인 초당 40개 요청(RPS)을 목표로 설계된 GitLab 참조 아키텍처를 설명합니다.

전체 참조 아키텍처 목록은 사용 가능한 참조 아키텍처를 참고합니다.

서비스 노드 수 구성 GCP 예시1 AWS 예시1 Azure 예시1
외부 로드 밸런서2 1 4 vCPU, 3.6 GB 메모리 n1-highcpu-4 c5n.xlarge F4s v2
PostgreSQL3 1 2 vCPU, 7.5 GB 메모리 n1-standard-2 m5.large D2s v3
Redis4 1 1 vCPU, 3.75 GB 메모리 n1-standard-1 m5.large D2s v3
Gitaly5 1 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge D4s v3
Sidekiq6 1 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge D4s v3
GitLab Rails6 2 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
오브젝트 스토리지7 - - - - -
Note

인스턴스 구성이 필요한 모든 PaaS 솔루션은 필요하다면 복원력을 위해 여러 가용 영역에 배포하는 것을 권장합니다.

PlantUML 다이어그램 (37줄)
소스 코드 보기
@startuml 2k
skinparam linetype ortho

card "External Load Balancer" as elb #6a9be7

together { collections "GitLab Rails x2" as gitlab #32CD32 card "Sidekiq" as sidekiq #ff8dd1 }

card "Prometheus" as monitor #7FFFD4 card "Gitaly" as gitaly #FF8C00 card "PostgreSQL" as postgres #4EA7FF card "Redis" as redis #FF6347 cloud "Object Storage" as object_storage #white

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

gitlab -[#32CD32]--> gitaly gitlab -[#32CD32]--> postgres gitlab -[#32CD32]> object_storage gitlab -[#32CD32]--> redis

sidekiq -[#ff8dd1]> object_storage sidekiq -[#ff8dd1]--> redis sidekiq .[#ff8dd1]--> postgres sidekiq -[hidden]-> monitor

monitor .[#7FFFD4]u-> gitlab monitor .[#7FFFD4]-> gitaly monitor .[#7FFFD4]-> postgres monitor .[#7FFFD4,norank]--> redis monitor .[#7FFFD4,norank]u--> elb monitor .[#7FFFD4]u-> sidekiq

@enduml

요구 사항#

계속하기 전에 참조 아키텍처의 요구 사항을 검토합니다.

테스트 방법론#

40 RPS / 2k 사용자 참조 아키텍처는 가장 일반적인 워크플로를 수용하도록 설계되었습니다. GitLab은 다음 엔드포인트 처리량 목표를 기준으로 스모크 테스트와 성능 테스트를 정기적으로 수행합니다.

엔드포인트 유형 목표 처리량
API 40 RPS
Web 4 RPS
Git (Pull) 4 RPS
Git (Push) 1 RPS

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

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

성능 고려 사항#

환경에 다음 중 하나가 있으면 추가 조정이 필요할 수 있습니다.

이러한 경우 자세한 내용은 환경 확장을 참고합니다. 이러한 고려 사항이 해당된다고 판단되면 필요에 따라 추가 안내를 받기 위해 문의합니다.

로드 밸런서 구성#

테스트 환경은 다음을 사용합니다.

  • Linux 패키지 환경에는 HAProxy
  • Cloud Native Hybrid에는 Gateway API 또는 Ingress 구현이 있는 클라우드 제공업체의 동등한 서비스

구성 요소 설정#

최대 40 RPS 또는 2,000명 사용자를 수용하도록 GitLab과 그 구성 요소를 설정하려면 다음을 수행합니다.

  1. 외부 로드 밸런싱 노드를 구성하여 GitLab 애플리케이션 서비스 노드의 로드 밸런싱을 처리하도록 합니다.
  2. GitLab의 데이터베이스인 PostgreSQL을 구성합니다.
  3. 세션 데이터, 임시 캐시 정보, 백그라운드 job 큐를 저장하는 Redis를 구성합니다.
  4. Git 리포지터리에 대한 접근을 제공하는 Gitaly를 구성합니다.
  5. 백그라운드 job 처리를 위해 Sidekiq을 구성합니다.
  6. Puma, Workhorse, GitLab Shell을 실행하고 모든 프론트엔드 요청(UI, API, HTTP/SSH를 통한 Git 포함)을 처리하도록 기본 GitLab Rails 애플리케이션을 구성합니다.
  7. GitLab 환경을 모니터링하도록 Prometheus를 구성합니다.
  8. 공유 데이터 객체에 사용하는 오브젝트 스토리지를 구성합니다.
  9. GitLab 인스턴스 전체에서 더 빠르고 고급 코드 검색을 하려면 고급 검색을 구성합니다(선택 사항).

외부 로드 밸런서 구성#

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

사용할 로드 밸런서의 종류나 정확한 구성은 GitLab 문서의 범위를 벗어나지만, 일반적인 요구 사항에 대해서는 로드 밸런서를 참고합니다. 이 섹션에서는 선택한 로드 밸런서에 구성해야 할 구체적인 내용을 중점적으로 다룹니다.

준비 상태 확인#

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

포트#

사용할 기본 포트는 아래 표와 같습니다.

LB 포트 백엔드 포트 프로토콜
80 80 HTTP8
443 443 TCP 또는 HTTPS8, 9
22 22 TCP

사용자 지정 도메인을 지원하는 GitLab Pages를 사용하는 경우 추가 포트 구성이 필요합니다. GitLab Pages에는 별도의 가상 IP 주소가 필요합니다. /etc/gitlab/gitlab.rb의 pages_external_url이 새 가상 IP 주소를 가리키도록 DNS를 구성합니다. 자세한 내용은 GitLab Pages 문서를 참고합니다.

LB 포트 백엔드 포트 프로토콜
80 다양함10 HTTP
443 다양함10 TCP11

대체 SSH 포트#

일부 조직은 SSH 22번 포트를 여는 것을 금지하는 정책이 있습니다. 이 경우 사용자가 443 포트에서 SSH를 사용할 수 있도록 대체 SSH 호스트 이름을 구성하는 것이 도움이 될 수 있습니다. 대체 SSH 호스트 이름에는 앞서 설명한 다른 GitLab HTTP 구성과 달리 새 가상 IP 주소가 필요합니다.

altssh.gitlab.example.com 같은 대체 SSH 호스트 이름에 대해 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 문서를 참고합니다.

Back to set up components

PostgreSQL 구성#

이 섹션에서는 GitLab과 함께 사용할 외부 PostgreSQL 데이터베이스를 구성하는 방법을 안내합니다.

자체 PostgreSQL 인스턴스 제공#

Linux 패키지에 포함된 PostgreSQL, PgBouncer, Consul 서비스 검색 구성 요소 대신 PostgreSQL용 서드파티 외부 서비스를 사용할 수 있습니다.

지원되는 PostgreSQL 버전을 실행하는 신뢰할 수 있는 제공업체를 사용합니다. 다음 서비스는 잘 작동하는 것으로 알려져 있습니다.

고가용성과 데이터베이스 로드 밸런싱에 대한 안내를 포함한 자세한 내용은 다음을 참고합니다.

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

  1. 데이터베이스 요구 사항 문서에 따라 PostgreSQL을 설정합니다.
  2. 필요한 사용자와 데이터베이스를 구성합니다.
  3. GitLab Rails 구성을 따라 적절한 연결 정보로 GitLab 애플리케이션 서버를 구성합니다.

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

  1. PostgreSQL 서버에 SSH로 접속합니다.

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

  3. PostgreSQL용 비밀번호 해시를 생성합니다. 기본 사용자 이름 gitlab(권장)을 사용한다고 가정합니다. 이 명령은 비밀번호와 확인을 요청합니다. 이 명령이 출력하는 값을 다음 단계에서 POSTGRESQL_PASSWORD_HASH의 값으로 사용합니다.

    sudo gitlab-ctl pg-password-md5 gitlab
    
  4. /etc/gitlab/gitlab.rb를 편집하여 아래 내용을 추가하고, 자리 표시자 값을 적절히 업데이트합니다.

    • POSTGRESQL_PASSWORD_HASH - 이전 단계에서 출력된 값
    • APPLICATION_SERVER_IP_BLOCKS - 데이터베이스에 연결할 GitLab Rails 및 Sidekiq 서버의 IP 서브넷 또는 IP 주소를 공백으로 구분한 목록. 예: %w(123.123.123.123/32 123.123.123.234/32)
    # Disable all components except PostgreSQL related ones
    roles(['postgres_role'])
    
    # Set the network addresses that the exporters used for monitoring will listen on
    node_exporter['listen_address'] = '0.0.0.0:9100'
    postgres_exporter['listen_address'] = '0.0.0.0:9187'
    postgres_exporter['dbname'] = 'gitlabhq_production'
    postgres_exporter['password'] = 'POSTGRESQL_PASSWORD_HASH'
    
    # Set the PostgreSQL address and port
    postgresql['listen_address'] = '0.0.0.0'
    postgresql['port'] = 5432
    
    # Replace POSTGRESQL_PASSWORD_HASH with a generated md5 value
    postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
    
    # Replace APPLICATION_SERVER_IP_BLOCK with the CIDR address of the application node
    postgresql['trust_auth_cidr_addresses'] = %w(127.0.0.1/32 APPLICATION_SERVER_IP_BLOCK)
    
    # Prevent database migrations from running on upgrade automatically
    gitlab_rails['auto_migrate'] = false
    
  5. 처음 구성한 Linux 패키지 노드의 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 같은 이름의 파일에 추가하거나 교체합니다. 처음으로 구성하는 Linux 패키지라면 이 단계를 건너뛸 수 있습니다.

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

  7. PostgreSQL 노드의 IP 주소 또는 호스트 이름, 포트, 평문 비밀번호를 기록해 둡니다. 이 정보는 나중에 GitLab 애플리케이션 서버를 구성할 때 필요합니다.

고급 구성 옵션도 지원되며 필요하면 추가할 수 있습니다.

Back to set up components

Redis 구성#

이 섹션에서는 GitLab과 함께 사용할 외부 Redis 인스턴스를 구성하는 방법을 안내합니다.

Note

Redis는 주로 싱글 스레드로 동작하므로 CPU 코어 수를 늘려도 크게 이점이 없습니다. 자세한 내용은 확장 문서를 참고합니다.

자체 Redis 인스턴스 제공#

다음 안내에 따라 선택적으로 Redis 인스턴스용 서드파티 외부 서비스를 사용할 수 있습니다.

  • 신뢰할 수 있는 제공업체 또는 솔루션을 사용해야 합니다. Google Memorystore와 AWS ElastiCache는 잘 작동하는 것으로 알려져 있습니다.
  • Redis Cluster 모드는 명시적으로 지원되지 않으며, HA를 갖춘 Redis Standalone은 지원됩니다.
  • 사용 환경에 맞게 Redis 제거 모드를 설정해야 합니다.

자세한 내용은 인프라와 서비스를 참고합니다.

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

Linux 패키지로 독립형 Redis 서버를 구성할 수 있습니다. 아래 단계는 Linux 패키지로 Redis 서버를 구성하는 데 필요한 최소한의 단계입니다.

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

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

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

    ## Enable Redis
    roles(["redis_master_role"])
    
    redis['bind'] = '0.0.0.0'
    redis['port'] = 6379
    redis['password'] = 'SECRET_PASSWORD_HERE'
    
    # Set the network addresses that the exporters used for monitoring 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
    
  4. 처음 구성한 Linux 패키지 노드의 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 같은 이름의 파일에 추가하거나 교체합니다. 처음으로 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

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

  6. Redis 노드의 IP 주소 또는 호스트 이름, 포트, Redis 비밀번호를 기록해 둡니다. 이 정보는 나중에 GitLab 애플리케이션 서버를 구성할 때 필요합니다.

고급 구성 옵션도 지원되며 필요하면 추가할 수 있습니다.

Back to set up components

Gitaly 구성#

Gitaly 서버 노드 요구 사항은 데이터 크기, 특히 프로젝트 수와 각 프로젝트의 크기에 따라 달라집니다.

Warning

Gitaly 사양은 사용 패턴과 상태가 양호한 리포지터리 크기의 높은 백분위수를 기준으로 합니다. 그러나 대형 모노레포(수 기가바이트보다 큰 경우)나 추가 워크로드가 있으면 환경 성능에 상당한 영향을 줄 수 있으며 추가 조정이 필요할 수 있습니다. 해당된다고 판단되면 필요에 따라 추가 안내를 받기 위해 문의합니다.

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

다음 항목을 유의합니다.

  • GitLab Rails 애플리케이션은 리포지터리를 리포지터리 스토리지 경로로 샤딩합니다.
  • Gitaly 서버 하나가 하나 이상의 스토리지 경로를 호스팅할 수 있습니다.
  • GitLab 서버 하나가 하나 이상의 Gitaly 서버 노드를 사용할 수 있습니다.
  • Gitaly 주소는 모든 Gitaly 클라이언트에서 올바르게 확인되도록 지정해야 합니다.
  • Gitaly 서버는 기본적으로 Gitaly의 네트워크 트래픽이 암호화되지 않으므로 공용 인터넷에 노출되어서는 안 됩니다. Gitaly 서버에 대한 접근을 제한하기 위해 방화벽을 사용하는 것을 강력히 권장합니다. 또 다른 방법은 TLS 사용입니다.
Note

Gitaly 문서 전반에서 언급하는 토큰은 관리자가 임의로 선택한 비밀번호입니다. 이 토큰은 GitLab API용으로 생성한 토큰이나 이와 유사한 다른 웹 API 토큰과 관련이 없습니다.

다음 절차는 시크릿 토큰이 gitalysecret인 gitaly1.internal이라는 Gitaly 서버 한 대를 구성하는 방법을 설명합니다. GitLab 설치에 default와 storage1이라는 두 개의 리포지터리 스토리지가 있다고 가정합니다.

Gitaly 서버를 구성하려면 Gitaly에 사용할 서버 노드에서 다음을 수행합니다.

  1. 원하는 Linux 패키지를 다운로드하여 설치합니다. 선택한 운영 체제에 맞는 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 하며, EXTERNAL_URL 값은 제공하지 않습니다.

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

    [!note] GitLab에서 필요로 하므로 gitaly['configuration'][:storage]에서 default 항목을 제거할 수 없습니다.

    # 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'
    
    # Set the network addresses that the exporters used for monitoring will listen on
    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',
       prometheus_listen_addr: '0.0.0.0:9236',
       # Gitaly Auth Token
       # Should be the same as praefect_internal_token
       auth: {
          # ...
          #
          # Gitaly's authentication token is used to authenticate gRPC requests to Gitaly. This must match
          # the respective value in GitLab Rails application setup.
          token: 'gitalysecret',
       },
       # 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,
       },
       storage: [
          {
             name: 'default',
             path: '/var/opt/gitlab/git-data/repositories',
          },
          {
             name: 'storage1',
             path: '/mnt/gitlab/git-data',
          },
       ],
    }
    
  3. 처음 구성한 Linux 패키지 노드의 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 같은 이름의 파일에 추가하거나 교체합니다. 처음으로 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

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

  5. 다음을 실행하여 Gitaly가 내부 API로 콜백을 수행할 수 있는지 확인합니다. sudo -u git -- /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml.

Gitaly TLS 지원#

Gitaly는 TLS 암호화를 지원합니다. 보안 연결을 수신하는 Gitaly 인스턴스와 통신하려면 GitLab 구성에서 해당 스토리지 항목의 gitaly_address에 tls:// URL 스킴을 사용해야 합니다.

이 인증서는 자동으로 제공되지 않으므로 직접 준비해야 합니다. 인증서 또는 해당 인증 기관은 모든 Gitaly 노드(인증서를 사용하는 Gitaly 노드 포함)와 Gitaly와 통신하는 모든 클라이언트 노드에 GitLab 사용자 지정 인증서 구성에 설명된 절차에 따라 설치해야 합니다.

Note

자체 서명 인증서에는 Gitaly 서버에 접근할 때 사용하는 주소가 지정되어 있어야 합니다. 호스트 이름으로 Gitaly 서버에 접근하는 경우 이를 Subject Alternative Name으로 추가합니다. IP 주소로 Gitaly 서버에 접근하는 경우 인증서에 Subject Alternative Name으로 반드시 추가해야 합니다.

Gitaly 서버에 암호화되지 않은 수신 주소(listen_addr)와 암호화된 수신 주소(tls_listen_addr)를 동시에 구성할 수 있습니다. 이렇게 하면 필요한 경우 암호화되지 않은 트래픽에서 암호화된 트래픽으로 점진적으로 전환할 수 있습니다.

Gitaly에 TLS를 구성하려면 다음을 수행합니다.

  1. /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
    
  2. Gitaly가 자기 자신을 호출할 때 인증서를 신뢰하도록 인증서를 /etc/gitlab/trusted-certs에 복사합니다.

    sudo cp /etc/gitlab/ssl/cert.pem /etc/gitlab/trusted-certs/
    
  3. /etc/gitlab/gitlab.rb를 편집하여 다음을 추가합니다.

    gitaly['configuration'] = {
       # ...
       tls_listen_addr: '0.0.0.0:9999',
       tls: {
          certificate_path: '/etc/gitlab/ssl/cert.pem',
          key_path: '/etc/gitlab/ssl/key.pem',
       },
    }
    
  4. 암호화된 연결만 허용하도록 gitaly['listen_addr']를 삭제합니다.

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

Back to set up components

Sidekiq 구성#

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

환경의 Sidekiq job 처리가 느리고 큐가 길다면 그에 맞게 확장할 수 있습니다. 자세한 내용은 확장 문서를 참고합니다.

Container Registry, SAML, LDAP 같은 추가 GitLab 기능을 구성할 때는 Rails 구성과 함께 Sidekiq 구성도 업데이트합니다. 자세한 내용은 외부 Sidekiq 문서를 참고합니다.

Sidekiq 서버를 구성하려면 Sidekiq에 사용할 서버 노드에서 다음을 수행합니다.

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

  2. PostgreSQL, Gitaly, Redis 포트에 접근할 수 있는지 확인합니다.

    telnet  5432 # PostgreSQL
    telnet  8075 # Gitaly
    telnet  6379 # Redis
    
  3. 원하는 Linux 패키지를 다운로드하여 설치합니다. 선택한 운영 체제에 맞는 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 합니다.

  4. /etc/gitlab/gitlab.rb를 만들거나 편집하여 다음 구성을 사용합니다.

    # https://docs.gitlab.com/omnibus/roles/#sidekiq-roles
    roles(["sidekiq_role"])
    
    # External URL
    external_url 'https://gitlab.example.com'
    
    ## Redis connection details
    gitlab_rails['redis_port'] = '6379'
    gitlab_rails['redis_host'] = '10.1.0.6' # IP/hostname of Redis server
    gitlab_rails['redis_password'] = 'Redis Password'
    
    # Gitaly and GitLab use two shared secrets for authentication, one to authenticate gRPC requests
    # to Gitaly, and a second stored in /etc/gitlab/gitlab-secrets.json for authentication callbacks from GitLab-Shell to the GitLab internal API.
    # The following must be the same as their respective values
    # of the Gitaly setup
    gitlab_rails['gitaly_token'] = 'gitalysecret'
    
    gitlab_rails['repositories_storages'] = {
      'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
    }
    
    ## PostgreSQL connection details
    gitlab_rails['db_adapter'] = 'postgresql'
    gitlab_rails['db_encoding'] = 'unicode'
    gitlab_rails['db_host'] = '10.1.0.5' # IP/hostname of database server
    gitlab_rails['db_password'] = 'DB password'
    
    ## 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
    
    ## Set the network addresses that the exporters will listen on
    node_exporter['listen_address'] = '0.0.0.0:9100'
    
    # 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>'
    }
    
  5. 처음 구성한 Linux 패키지 노드의 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 같은 이름의 파일에 추가하거나 교체합니다. 처음으로 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

  6. 데이터베이스 마이그레이션이 업그레이드 시 자동으로 실행되지 않고 재구성 중에만 실행되도록 다음을 실행합니다.

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

    마이그레이션은 지정된 노드 한 대에서만 처리해야 하며, 자세한 내용은 GitLab Rails 사후 구성 섹션을 참고합니다.

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

  8. GitLab 서비스가 실행 중인지 확인합니다.

    sudo gitlab-ctl status
    

    출력은 다음과 비슷해야 합니다.

    run: logrotate: (pid 192292) 2990s; run: log: (pid 26374) 93048s
    run: node-exporter: (pid 26864) 92997s; run: log: (pid 26446) 93036s
    run: sidekiq: (pid 26870) 92996s; run: log: (pid 26391) 93042s
    
Back to set up components

GitLab Rails 구성#

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

이 아키텍처에서는 각 GitLab Rails 노드를 Puma 웹 서버로 실행하고 워커 수를 사용 가능한 CPU의 90%, 스레드 수를 4개로 설정합니다. Rails를 다른 구성 요소와 함께 실행하는 노드에서는 워커 값을 그에 맞게 줄여야 합니다. 워커 값 50%가 균형이 좋은 것으로 확인했지만, 이는 워크로드에 따라 달라집니다.

각 노드에서 다음을 수행합니다.

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

  2. /etc/gitlab/gitlab.rb를 만들거나 편집하여 다음 구성을 사용합니다. 노드 간 링크의 일관성을 유지하려면 애플리케이션 서버의 external_url이 사용자가 GitLab에 접근할 때 사용하는 외부 URL을 가리켜야 합니다. 이는 GitLab 애플리케이션 서버로 트래픽을 라우팅하는 로드 밸런서의 URL입니다.

    external_url 'https://gitlab.example.com'
    
    # Gitaly and GitLab use two shared secrets for authentication, one to authenticate gRPC requests
    # to Gitaly, and a second stored in /etc/gitlab/gitlab-secrets.json for authentication callbacks from GitLab-Shell to the GitLab internal API.
    # The following must be the same as their respective values
    # of the Gitaly setup
    gitlab_rails['gitaly_token'] = 'gitalysecret'
    
    gitlab_rails['repositories_storages'] = {
      'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
    }
    
    ## Disable components that will not be on the GitLab application server
    roles(['application_role'])
    gitaly['enable'] = false
    sidekiq['enable'] = false
    
    ## PostgreSQL connection details
    gitlab_rails['db_adapter'] = 'postgresql'
    gitlab_rails['db_encoding'] = 'unicode'
    gitlab_rails['db_host'] = '10.1.0.5' # IP/hostname of database server
    gitlab_rails['db_password'] = 'DB password'
    
    ## Redis connection details
    gitlab_rails['redis_port'] = '6379'
    gitlab_rails['redis_host'] = '10.1.0.6' # IP/hostname of Redis server
    gitlab_rails['redis_password'] = 'Redis Password'
    
    # 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. Replace placeholder `monitoring.gitlab.example.com` with
    # the address and/or subnets gathered from the monitoring node
    gitlab_rails['monitoring_whitelist'] = ['/32', '127.0.0.0/8']
    nginx['status']['options']['allow'] = ['/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>'
    }
    
    ## 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
    
  3. TLS 지원이 있는 Gitaly를 사용하는 경우 gitlab_rails['repositories_storages'] 항목이 tcp 대신 tls로 구성되어 있는지 확인합니다.

    gitlab_rails['repositories_storages'] = {
      'default' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
      'storage1' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
      'storage2' => { 'gitaly_address' => 'tls://gitaly2.internal:9999' },
    }
    
    1. 인증서를 /etc/gitlab/trusted-certs에 복사합니다.

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

  5. 처음 구성한 Rails 노드에서 SSH 호스트 키(모두 /etc/ssh/ssh_host_*_key* 이름 형식)를 복사하여 이 서버의 같은 이름의 파일에 추가하거나 교체합니다. 이렇게 하면 사용자가 로드 밸런싱되는 Rails 노드에 접속할 때 호스트 불일치 오류가 발생하지 않습니다. 처음으로 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

  6. 데이터베이스 마이그레이션이 업그레이드 시 자동으로 실행되지 않고 재구성 중에만 실행되도록 다음을 실행합니다.

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

    마이그레이션은 지정된 노드 한 대에서만 처리해야 하며, 자세한 내용은 GitLab Rails 사후 구성 섹션을 참고합니다.

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

  8. 증분 로깅을 활성화합니다.

  9. sudo gitlab-rake gitlab:gitaly:check를 실행하여 노드가 Gitaly에 연결할 수 있는지 확인합니다.

  10. 로그를 tail하여 요청을 확인합니다.

    sudo gitlab-ctl tail gitaly
    

앞의 예시처럼 external_url에 https를 지정하면 GitLab은 SSL 인증서가 /etc/gitlab/ssl/에 있을 것으로 예상합니다. 인증서가 없으면 NGINX가 시작되지 않습니다. 자세한 내용은 HTTPS 문서를 참고합니다.

GitLab Rails 사후 구성#

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

    sudo gitlab-rake gitlab:db:configure
    

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

  2. 데이터베이스에서 승인된 SSH 키를 빠르게 조회하도록 구성합니다.

Back to set up components

Prometheus 구성#

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

  1. 모니터링 노드에 SSH로 접속합니다.

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

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

    roles(['monitoring_role'])
    nginx['enable'] = false
    
    external_url 'http://gitlab.example.com'
    
    # Prometheus
    prometheus['listen_address'] = '0.0.0.0:9090'
    prometheus['monitor_kubernetes'] = false
    
  4. Prometheus는 익스포터를 구성한 여러 노드에서 모든 데이터를 가져오기 위한 스크레이프 구성도 필요합니다. 노드의 IP가 다음과 같다고 가정합니다.

    1.1.1.1: postgres
    1.1.1.2: redis
    1.1.1.3: gitaly1
    1.1.1.4: rails1
    1.1.1.5: rails2
    1.1.1.6: sidekiq
    

    /etc/gitlab/gitlab.rb에 다음을 추가합니다.

    prometheus['scrape_configs'] = [
      {
         'job_name': 'postgres',
         'static_configs' => [
         'targets' => ['1.1.1.1:9187'],
         ],
      },
      {
         'job_name': 'redis',
         'static_configs' => [
         'targets' => ['1.1.1.2:9121'],
         ],
      },
      {
         'job_name': 'gitaly',
         'static_configs' => [
         'targets' => ['1.1.1.3:9236'],
         ],
      },
      {
         'job_name': 'gitlab-nginx',
         'static_configs' => [
         'targets' => ['1.1.1.4:8060', '1.1.1.5:8060'],
         ],
      },
      {
         'job_name': 'gitlab-workhorse',
         'static_configs' => [
         'targets' => ['1.1.1.4:9229', '1.1.1.5:9229'],
         ],
      },
      {
         'job_name': 'gitlab-rails',
         'metrics_path': '/-/metrics',
         'static_configs' => [
         'targets' => ['1.1.1.4:8080', '1.1.1.5:8080'],
         ],
      },
      {
         'job_name': 'gitlab-sidekiq',
         'static_configs' => [
         'targets' => ['1.1.1.6:8082'],
         ],
      },
      {
         'job_name': 'static-node',
         'static_configs' => [
         'targets' => ['1.1.1.1:9100', '1.1.1.2:9100', '1.1.1.3:9100', '1.1.1.4:9100', '1.1.1.5:9100', '1.1.1.6:9100'],
         ],
      },
    ]
    
  5. 파일을 저장하고 GitLab을 재구성합니다.

Back to set up components

오브젝트 스토리지 구성#

GitLab은 오브젝트 스토리지 서비스를 사용하여 여러 유형의 데이터를 보관하는 것을 지원합니다. 데이터 객체에는 NFS보다 오브젝트 스토리지를 권장하며, 오브젝트 스토리지는 일반적으로 성능, 안정성, 확장성이 훨씬 뛰어나므로 대규모 구성에서 대체로 더 좋습니다. 자세한 내용은 인프라와 서비스를 참고합니다.

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

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

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

Back to set up components

증분 로깅 활성화#

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

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

고급 검색 구성#

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

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

Back to set up components

Helm Chart를 사용한 Cloud Native Hybrid 참조 아키텍처(대안)#

대안으로 특정 GitLab 구성 요소를 Kubernetes에서 실행할 수 있습니다. 다음 서비스가 지원됩니다.

  • GitLab Rails
  • Sidekiq
  • NGINX
  • Toolbox
  • Migrations
  • Prometheus

하이브리드 설치는 클라우드 네이티브 배포와 기존 컴퓨트 배포의 장점을 모두 활용합니다. 이를 통해 상태 비저장 구성 요소는 클라우드 네이티브 워크로드 관리의 이점을 누리고, 상태 저장 구성 요소는 영속성이 높다는 이점을 위해 Linux 패키지 설치를 사용하는 컴퓨트 VM에 배포합니다.

설정 방법과 Kubernetes와 백엔드 구성 요소 간에 동기화해야 하는 GitLab 시크릿에 대한 안내는 Helm Chart 고급 구성 문서를 참고합니다.

Note
  • 이는 고급 설정입니다. Kubernetes에서 서비스를 실행하는 것은 복잡하기로 잘 알려져 있습니다. 이 설정은 Kubernetes에 대한 충분한 실무 지식과 경험이 있는 경우에만 권장합니다. 이 섹션의 나머지 부분은 이를 전제로 합니다.
  • 2,000 참조 아키텍처는 고가용성 구성이 아닙니다. HA를 달성하려면 수정된 3K 또는 60 RPS 참조 아키텍처를 따를 수 있습니다.

Kubernetes에서의 Gitaly 가용성, 제한 사항, 배포 시 고려 사항은 Kubernetes의 Gitaly를 참고합니다.

클러스터 토폴로지#

다음 표와 다이어그램은 앞서 설명한 일반 환경과 같은 형식으로 하이브리드 환경을 자세히 설명합니다.

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

구성 요소 노드 그룹 목표 노드 풀 합계 GCP 예시 AWS 예시
Webservice 12 vCPU
15 GB 메모리 (request)
21 GB 메모리 (limit)
3 x n1-standard-8 3 x c5.2xlarge
Sidekiq 3.6 vCPU
8 GB 메모리 (request)
16 GB 메모리 (limit)
2 x n1-standard-4 2 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 예시12 AWS 예시12
PostgreSQL13 1 2 vCPU, 7.5 GB 메모리 n1-standard-2 m5.large
Redis14 1 1 vCPU, 3.75 GB 메모리 n1-standard-1 m5.large
Gitaly15 1 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge
오브젝트 스토리지16 - - - -
Note

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

PlantUML 다이어그램 (32줄)
소스 코드 보기
@startuml 2k
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 }

collections "Supporting Services" as support }

card "Gitaly" as gitaly #FF8C00 card "PostgreSQL" as postgres #4EA7FF card "Redis" as redis #FF6347 cloud "Object Storage" as object_storage #white

elb -[#6a9be7]-> gitlab

gitlab -[#32CD32]--> gitaly gitlab -[#32CD32]--> postgres gitlab -[#32CD32]-> object_storage gitlab -[#32CD32]--> redis

sidekiq -[#ff8dd1]--> gitaly sidekiq -[#ff8dd1]-> object_storage sidekiq -[#ff8dd1]--> postgres sidekiq -[#ff8dd1]--> redis

@enduml

Kubernetes 구성 요소 목표#

다음 섹션에서는 Kubernetes에 배포되는 GitLab 구성 요소에 사용하는 목표를 설명합니다.

Webservice#

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

  • Puma 워커 4개
  • 4 vCPU
  • 5 GB 메모리 (request)
  • 7 GB 메모리 (limit)

40 RPS 또는 2,000명 사용자에는 전체 Puma 워커 수를 약 12개로 하는 것을 권장하며, 따라서 Webservice Pod를 최소 3개 실행하는 것을 권장합니다.

Webservice 리소스 사용량에 대한 자세한 내용은 Chart 문서의 Webservice 리소스를 참고합니다.

Gateway API / Ingress#

Gateway API 또는 Ingress 컨트롤러 Pod도 DaemonSet으로 Webservice 노드에 걸쳐 배포하는 것을 권장합니다. 이렇게 하면 컨트롤러가 담당하는 Webservice Pod에 맞춰 동적으로 확장할 수 있고, 더 큰 머신 유형이 일반적으로 가지는 높은 네트워크 대역폭을 활용할 수 있습니다.

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

Sidekiq#

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

  • Sidekiq 워커 1개
  • 900m vCPU
  • 2 GB 메모리 (request)
  • 4 GB 메모리 (limit)

앞서 설명한 표준 배포와 마찬가지로 여기서는 Sidekiq 워커 4개를 초기 목표로 사용했습니다. 특정 워크플로에 따라 추가 워커가 필요할 수 있습니다.

Sidekiq 리소스 사용량에 대한 자세한 내용은 Chart 문서의 Sidekiq 리소스를 참고합니다.

지원 서비스#

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

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

Container Registry, Pages, 모니터링 같은 추가 배포는 가능하면 Webservice 또는 Sidekiq 풀이 아닌 지원 노드 풀에 배포합니다. 지원 노드 풀은 여러 추가 배포를 수용하도록 설계되었습니다. 그러나 배포가 제시된 풀에 맞지 않으면 그에 맞게 노드 풀을 늘릴 수 있습니다. 반대로 사용 사례에서 풀이 과도하게 프로비저닝되어 있다면 그에 맞게 줄일 수 있습니다.

구성 파일 예시#

40 RPS 또는 2,000명 사용자 참조 아키텍처 구성에 대한 GitLab Helm Chart 예시는 Charts 프로젝트에서 확인할 수 있습니다.

Back to set up components

다음 단계#

이 가이드를 따르면 핵심 기능이 구성된 새로운 GitLab 환경이 준비됩니다.

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

Note

환경과 요구 사항에 따라 원하는 추가 기능을 설정하려면 추가 하드웨어 요구 사항이나 조정이 필요할 수 있습니다. 자세한 내용은 각 페이지를 참고합니다.

Footnotes

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

  2. 신뢰할 수 있는 서드파티 로드 밸런서 또는 서비스(LB PaaS)로 실행하는 것을 권장합니다. 크기는 선택한 로드 밸런서와 네트워크 대역폭 같은 추가 요소에 따라 달라집니다. ↩

  3. 선택적으로 신뢰할 수 있는 서드파티 외부 PaaS PostgreSQL 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 PostgreSQL 인스턴스 제공 및 인프라와 서비스를 참고합니다. ↩

  4. 선택적으로 신뢰할 수 있는 서드파티 외부 PaaS Redis 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 Redis 인스턴스 제공 및 인프라와 서비스를 참고합니다. ↩

  5. Gitaly 사양은 상태가 양호한 일반 크기의 리포지터리를 사용한다는 전제에 기반합니다. 그러나 대형 모노레포(수 기가바이트보다 큰 경우)가 있으면 Git과 Gitaly 성능에 상당한 영향을 줄 수 있으며 사양을 높여야 할 가능성이 큽니다. 자세한 내용은 대형 모노레포를 참고합니다. ↩

  6. 이 구성 요소는 상태 저장 데이터를 저장하지 않으므로 Auto Scaling Group(ASG)에 둘 수 있습니다. 그러나 Cloud Native Hybrid 구성을 일반적으로 더 선호합니다. 마이그레이션과 Mailroom 같은 일부 구성 요소는 노드 한 대에서만 실행할 수 있고, 이는 Kubernetes에서 더 잘 처리되기 때문입니다. ↩ ↩2

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

  8. 웹 터미널 지원에는 로드 밸런서가 WebSocket 연결을 올바르게 처리해야 합니다.

    HTTP 또는 HTTPS 프록시를 사용하는 경우 로드 밸런서가 Connection 및 Upgrade hop-by-hop 헤더를 그대로 전달하도록 구성해야 합니다. 자세한 내용은 웹 터미널 통합 가이드를 참고합니다. ↩ ↩2

  9. 443 포트에 HTTPS 프로토콜을 사용하는 경우 로드 밸런서에 SSL 인증서를 추가해야 합니다. 대신 GitLab 애플리케이션 서버에서 SSL을 종료하려면 TCP 프로토콜을 사용합니다. ↩

  10. GitLab Pages의 백엔드 포트는 gitlab_pages['external_http'] 및 gitlab_pages['external_https'] 설정에 따라 달라집니다. 자세한 내용은 GitLab Pages 문서를 참고합니다. ↩ ↩2

  11. GitLab Pages의 443 포트는 항상 TCP 프로토콜을 사용해야 합니다. 사용자는 사용자 지정 SSL이 적용된 사용자 지정 도메인을 구성할 수 있는데, 로드 밸런서에서 SSL을 종료하면 이것이 불가능해집니다. ↩

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

  13. 선택적으로 신뢰할 수 있는 서드파티 외부 PaaS PostgreSQL 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 PostgreSQL 인스턴스 제공 및 인프라와 서비스를 참고합니다. ↩

  14. 선택적으로 신뢰할 수 있는 서드파티 외부 PaaS Redis 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 Redis 인스턴스 제공 및 인프라와 서비스를 참고합니다. ↩

  15. Gitaly 사양은 상태가 양호한 일반 크기의 리포지터리를 사용한다는 전제에 기반합니다. 그러나 대형 모노레포(수 기가바이트보다 큰 경우)가 있으면 Git과 Gitaly 성능에 상당한 영향을 줄 수 있으며 사양을 높여야 할 가능성이 큽니다. 자세한 내용은 대형 모노레포를 참고합니다. ↩

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

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

GitLab v19.5
Tier: Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기

요약

이 페이지는 실제 데이터를 기반으로, 수동 및 자동 사용을 합쳐 최대 2,000명 사용자의 일반적인 피크 부하인 초당 40개 요청(RPS)을 목표로 설계된 GitLab 참조 아키텍처를 설명합니다. 전체 참조 아키텍처 목록은 사용 가능한 참조 아키텍처를 참고합니다.

이 페이지는 실제 데이터를 기반으로, 수동 및 자동 사용을 합쳐 최대 2,000명 사용자의 일반적인 피크 부하인 초당 40개 요청(RPS)을 목표로 설계된 GitLab 참조 아키텍처를 설명합니다.

전체 참조 아키텍처 목록은 사용 가능한 참조 아키텍처를 참고합니다.

서비스 노드 수 구성 GCP 예시1 AWS 예시1 Azure 예시1
외부 로드 밸런서2 1 4 vCPU, 3.6 GB 메모리 n1-highcpu-4 c5n.xlarge F4s v2
PostgreSQL3 1 2 vCPU, 7.5 GB 메모리 n1-standard-2 m5.large D2s v3
Redis4 1 1 vCPU, 3.75 GB 메모리 n1-standard-1 m5.large D2s v3
Gitaly5 1 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge D4s v3
Sidekiq6 1 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge D4s v3
GitLab Rails6 2 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
오브젝트 스토리지7 - - - - -
Note

인스턴스 구성이 필요한 모든 PaaS 솔루션은 필요하다면 복원력을 위해 여러 가용 영역에 배포하는 것을 권장합니다.

PlantUML 다이어그램 (37줄)
소스 코드 보기
@startuml 2k
skinparam linetype ortho

card "External Load Balancer" as elb #6a9be7

together { collections "GitLab Rails x2" as gitlab #32CD32 card "Sidekiq" as sidekiq #ff8dd1 }

card "Prometheus" as monitor #7FFFD4 card "Gitaly" as gitaly #FF8C00 card "PostgreSQL" as postgres #4EA7FF card "Redis" as redis #FF6347 cloud "Object Storage" as object_storage #white

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

gitlab -[#32CD32]--> gitaly gitlab -[#32CD32]--> postgres gitlab -[#32CD32]> object_storage gitlab -[#32CD32]--> redis

sidekiq -[#ff8dd1]> object_storage sidekiq -[#ff8dd1]--> redis sidekiq .[#ff8dd1]--> postgres sidekiq -[hidden]-> monitor

monitor .[#7FFFD4]u-> gitlab monitor .[#7FFFD4]-> gitaly monitor .[#7FFFD4]-> postgres monitor .[#7FFFD4,norank]--> redis monitor .[#7FFFD4,norank]u--> elb monitor .[#7FFFD4]u-> sidekiq

@enduml

요구 사항#

계속하기 전에 참조 아키텍처의 요구 사항을 검토합니다.

테스트 방법론#

40 RPS / 2k 사용자 참조 아키텍처는 가장 일반적인 워크플로를 수용하도록 설계되었습니다. GitLab은 다음 엔드포인트 처리량 목표를 기준으로 스모크 테스트와 성능 테스트를 정기적으로 수행합니다.

엔드포인트 유형 목표 처리량
API 40 RPS
Web 4 RPS
Git (Pull) 4 RPS
Git (Push) 1 RPS

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

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

성능 고려 사항#

환경에 다음 중 하나가 있으면 추가 조정이 필요할 수 있습니다.

이러한 경우 자세한 내용은 환경 확장을 참고합니다. 이러한 고려 사항이 해당된다고 판단되면 필요에 따라 추가 안내를 받기 위해 문의합니다.

로드 밸런서 구성#

테스트 환경은 다음을 사용합니다.

  • Linux 패키지 환경에는 HAProxy
  • Cloud Native Hybrid에는 Gateway API 또는 Ingress 구현이 있는 클라우드 제공업체의 동등한 서비스

구성 요소 설정#

최대 40 RPS 또는 2,000명 사용자를 수용하도록 GitLab과 그 구성 요소를 설정하려면 다음을 수행합니다.

  1. 외부 로드 밸런싱 노드를 구성하여 GitLab 애플리케이션 서비스 노드의 로드 밸런싱을 처리하도록 합니다.
  2. GitLab의 데이터베이스인 PostgreSQL을 구성합니다.
  3. 세션 데이터, 임시 캐시 정보, 백그라운드 job 큐를 저장하는 Redis를 구성합니다.
  4. Git 리포지터리에 대한 접근을 제공하는 Gitaly를 구성합니다.
  5. 백그라운드 job 처리를 위해 Sidekiq을 구성합니다.
  6. Puma, Workhorse, GitLab Shell을 실행하고 모든 프론트엔드 요청(UI, API, HTTP/SSH를 통한 Git 포함)을 처리하도록 기본 GitLab Rails 애플리케이션을 구성합니다.
  7. GitLab 환경을 모니터링하도록 Prometheus를 구성합니다.
  8. 공유 데이터 객체에 사용하는 오브젝트 스토리지를 구성합니다.
  9. GitLab 인스턴스 전체에서 더 빠르고 고급 코드 검색을 하려면 고급 검색을 구성합니다(선택 사항).

외부 로드 밸런서 구성#

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

사용할 로드 밸런서의 종류나 정확한 구성은 GitLab 문서의 범위를 벗어나지만, 일반적인 요구 사항에 대해서는 로드 밸런서를 참고합니다. 이 섹션에서는 선택한 로드 밸런서에 구성해야 할 구체적인 내용을 중점적으로 다룹니다.

준비 상태 확인#

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

포트#

사용할 기본 포트는 아래 표와 같습니다.

LB 포트 백엔드 포트 프로토콜
80 80 HTTP8
443 443 TCP 또는 HTTPS8, 9
22 22 TCP

사용자 지정 도메인을 지원하는 GitLab Pages를 사용하는 경우 추가 포트 구성이 필요합니다. GitLab Pages에는 별도의 가상 IP 주소가 필요합니다. /etc/gitlab/gitlab.rb의 pages_external_url이 새 가상 IP 주소를 가리키도록 DNS를 구성합니다. 자세한 내용은 GitLab Pages 문서를 참고합니다.

LB 포트 백엔드 포트 프로토콜
80 다양함10 HTTP
443 다양함10 TCP11

대체 SSH 포트#

일부 조직은 SSH 22번 포트를 여는 것을 금지하는 정책이 있습니다. 이 경우 사용자가 443 포트에서 SSH를 사용할 수 있도록 대체 SSH 호스트 이름을 구성하는 것이 도움이 될 수 있습니다. 대체 SSH 호스트 이름에는 앞서 설명한 다른 GitLab HTTP 구성과 달리 새 가상 IP 주소가 필요합니다.

altssh.gitlab.example.com 같은 대체 SSH 호스트 이름에 대해 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 문서를 참고합니다.

Back to set up components

PostgreSQL 구성#

이 섹션에서는 GitLab과 함께 사용할 외부 PostgreSQL 데이터베이스를 구성하는 방법을 안내합니다.

자체 PostgreSQL 인스턴스 제공#

Linux 패키지에 포함된 PostgreSQL, PgBouncer, Consul 서비스 검색 구성 요소 대신 PostgreSQL용 서드파티 외부 서비스를 사용할 수 있습니다.

지원되는 PostgreSQL 버전을 실행하는 신뢰할 수 있는 제공업체를 사용합니다. 다음 서비스는 잘 작동하는 것으로 알려져 있습니다.

고가용성과 데이터베이스 로드 밸런싱에 대한 안내를 포함한 자세한 내용은 다음을 참고합니다.

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

  1. 데이터베이스 요구 사항 문서에 따라 PostgreSQL을 설정합니다.
  2. 필요한 사용자와 데이터베이스를 구성합니다.
  3. GitLab Rails 구성을 따라 적절한 연결 정보로 GitLab 애플리케이션 서버를 구성합니다.

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

  1. PostgreSQL 서버에 SSH로 접속합니다.

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

  3. PostgreSQL용 비밀번호 해시를 생성합니다. 기본 사용자 이름 gitlab(권장)을 사용한다고 가정합니다. 이 명령은 비밀번호와 확인을 요청합니다. 이 명령이 출력하는 값을 다음 단계에서 POSTGRESQL_PASSWORD_HASH의 값으로 사용합니다.

    sudo gitlab-ctl pg-password-md5 gitlab
    
  4. /etc/gitlab/gitlab.rb를 편집하여 아래 내용을 추가하고, 자리 표시자 값을 적절히 업데이트합니다.

    • POSTGRESQL_PASSWORD_HASH - 이전 단계에서 출력된 값
    • APPLICATION_SERVER_IP_BLOCKS - 데이터베이스에 연결할 GitLab Rails 및 Sidekiq 서버의 IP 서브넷 또는 IP 주소를 공백으로 구분한 목록. 예: %w(123.123.123.123/32 123.123.123.234/32)
    # Disable all components except PostgreSQL related ones
    roles(['postgres_role'])
    
    # Set the network addresses that the exporters used for monitoring will listen on
    node_exporter['listen_address'] = '0.0.0.0:9100'
    postgres_exporter['listen_address'] = '0.0.0.0:9187'
    postgres_exporter['dbname'] = 'gitlabhq_production'
    postgres_exporter['password'] = 'POSTGRESQL_PASSWORD_HASH'
    
    # Set the PostgreSQL address and port
    postgresql['listen_address'] = '0.0.0.0'
    postgresql['port'] = 5432
    
    # Replace POSTGRESQL_PASSWORD_HASH with a generated md5 value
    postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
    
    # Replace APPLICATION_SERVER_IP_BLOCK with the CIDR address of the application node
    postgresql['trust_auth_cidr_addresses'] = %w(127.0.0.1/32 APPLICATION_SERVER_IP_BLOCK)
    
    # Prevent database migrations from running on upgrade automatically
    gitlab_rails['auto_migrate'] = false
    
  5. 처음 구성한 Linux 패키지 노드의 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 같은 이름의 파일에 추가하거나 교체합니다. 처음으로 구성하는 Linux 패키지라면 이 단계를 건너뛸 수 있습니다.

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

  7. PostgreSQL 노드의 IP 주소 또는 호스트 이름, 포트, 평문 비밀번호를 기록해 둡니다. 이 정보는 나중에 GitLab 애플리케이션 서버를 구성할 때 필요합니다.

고급 구성 옵션도 지원되며 필요하면 추가할 수 있습니다.

Back to set up components

Redis 구성#

이 섹션에서는 GitLab과 함께 사용할 외부 Redis 인스턴스를 구성하는 방법을 안내합니다.

Note

Redis는 주로 싱글 스레드로 동작하므로 CPU 코어 수를 늘려도 크게 이점이 없습니다. 자세한 내용은 확장 문서를 참고합니다.

자체 Redis 인스턴스 제공#

다음 안내에 따라 선택적으로 Redis 인스턴스용 서드파티 외부 서비스를 사용할 수 있습니다.

  • 신뢰할 수 있는 제공업체 또는 솔루션을 사용해야 합니다. Google Memorystore와 AWS ElastiCache는 잘 작동하는 것으로 알려져 있습니다.
  • Redis Cluster 모드는 명시적으로 지원되지 않으며, HA를 갖춘 Redis Standalone은 지원됩니다.
  • 사용 환경에 맞게 Redis 제거 모드를 설정해야 합니다.

자세한 내용은 인프라와 서비스를 참고합니다.

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

Linux 패키지로 독립형 Redis 서버를 구성할 수 있습니다. 아래 단계는 Linux 패키지로 Redis 서버를 구성하는 데 필요한 최소한의 단계입니다.

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

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

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

    ## Enable Redis
    roles(["redis_master_role"])
    
    redis['bind'] = '0.0.0.0'
    redis['port'] = 6379
    redis['password'] = 'SECRET_PASSWORD_HERE'
    
    # Set the network addresses that the exporters used for monitoring 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
    
  4. 처음 구성한 Linux 패키지 노드의 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 같은 이름의 파일에 추가하거나 교체합니다. 처음으로 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

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

  6. Redis 노드의 IP 주소 또는 호스트 이름, 포트, Redis 비밀번호를 기록해 둡니다. 이 정보는 나중에 GitLab 애플리케이션 서버를 구성할 때 필요합니다.

고급 구성 옵션도 지원되며 필요하면 추가할 수 있습니다.

Back to set up components

Gitaly 구성#

Gitaly 서버 노드 요구 사항은 데이터 크기, 특히 프로젝트 수와 각 프로젝트의 크기에 따라 달라집니다.

Warning

Gitaly 사양은 사용 패턴과 상태가 양호한 리포지터리 크기의 높은 백분위수를 기준으로 합니다. 그러나 대형 모노레포(수 기가바이트보다 큰 경우)나 추가 워크로드가 있으면 환경 성능에 상당한 영향을 줄 수 있으며 추가 조정이 필요할 수 있습니다. 해당된다고 판단되면 필요에 따라 추가 안내를 받기 위해 문의합니다.

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

다음 항목을 유의합니다.

  • GitLab Rails 애플리케이션은 리포지터리를 리포지터리 스토리지 경로로 샤딩합니다.
  • Gitaly 서버 하나가 하나 이상의 스토리지 경로를 호스팅할 수 있습니다.
  • GitLab 서버 하나가 하나 이상의 Gitaly 서버 노드를 사용할 수 있습니다.
  • Gitaly 주소는 모든 Gitaly 클라이언트에서 올바르게 확인되도록 지정해야 합니다.
  • Gitaly 서버는 기본적으로 Gitaly의 네트워크 트래픽이 암호화되지 않으므로 공용 인터넷에 노출되어서는 안 됩니다. Gitaly 서버에 대한 접근을 제한하기 위해 방화벽을 사용하는 것을 강력히 권장합니다. 또 다른 방법은 TLS 사용입니다.
Note

Gitaly 문서 전반에서 언급하는 토큰은 관리자가 임의로 선택한 비밀번호입니다. 이 토큰은 GitLab API용으로 생성한 토큰이나 이와 유사한 다른 웹 API 토큰과 관련이 없습니다.

다음 절차는 시크릿 토큰이 gitalysecret인 gitaly1.internal이라는 Gitaly 서버 한 대를 구성하는 방법을 설명합니다. GitLab 설치에 default와 storage1이라는 두 개의 리포지터리 스토리지가 있다고 가정합니다.

Gitaly 서버를 구성하려면 Gitaly에 사용할 서버 노드에서 다음을 수행합니다.

  1. 원하는 Linux 패키지를 다운로드하여 설치합니다. 선택한 운영 체제에 맞는 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 하며, EXTERNAL_URL 값은 제공하지 않습니다.

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

    [!note] GitLab에서 필요로 하므로 gitaly['configuration'][:storage]에서 default 항목을 제거할 수 없습니다.

    # 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'
    
    # Set the network addresses that the exporters used for monitoring will listen on
    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',
       prometheus_listen_addr: '0.0.0.0:9236',
       # Gitaly Auth Token
       # Should be the same as praefect_internal_token
       auth: {
          # ...
          #
          # Gitaly's authentication token is used to authenticate gRPC requests to Gitaly. This must match
          # the respective value in GitLab Rails application setup.
          token: 'gitalysecret',
       },
       # 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,
       },
       storage: [
          {
             name: 'default',
             path: '/var/opt/gitlab/git-data/repositories',
          },
          {
             name: 'storage1',
             path: '/mnt/gitlab/git-data',
          },
       ],
    }
    
  3. 처음 구성한 Linux 패키지 노드의 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 같은 이름의 파일에 추가하거나 교체합니다. 처음으로 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

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

  5. 다음을 실행하여 Gitaly가 내부 API로 콜백을 수행할 수 있는지 확인합니다. sudo -u git -- /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml.

Gitaly TLS 지원#

Gitaly는 TLS 암호화를 지원합니다. 보안 연결을 수신하는 Gitaly 인스턴스와 통신하려면 GitLab 구성에서 해당 스토리지 항목의 gitaly_address에 tls:// URL 스킴을 사용해야 합니다.

이 인증서는 자동으로 제공되지 않으므로 직접 준비해야 합니다. 인증서 또는 해당 인증 기관은 모든 Gitaly 노드(인증서를 사용하는 Gitaly 노드 포함)와 Gitaly와 통신하는 모든 클라이언트 노드에 GitLab 사용자 지정 인증서 구성에 설명된 절차에 따라 설치해야 합니다.

Note

자체 서명 인증서에는 Gitaly 서버에 접근할 때 사용하는 주소가 지정되어 있어야 합니다. 호스트 이름으로 Gitaly 서버에 접근하는 경우 이를 Subject Alternative Name으로 추가합니다. IP 주소로 Gitaly 서버에 접근하는 경우 인증서에 Subject Alternative Name으로 반드시 추가해야 합니다.

Gitaly 서버에 암호화되지 않은 수신 주소(listen_addr)와 암호화된 수신 주소(tls_listen_addr)를 동시에 구성할 수 있습니다. 이렇게 하면 필요한 경우 암호화되지 않은 트래픽에서 암호화된 트래픽으로 점진적으로 전환할 수 있습니다.

Gitaly에 TLS를 구성하려면 다음을 수행합니다.

  1. /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
    
  2. Gitaly가 자기 자신을 호출할 때 인증서를 신뢰하도록 인증서를 /etc/gitlab/trusted-certs에 복사합니다.

    sudo cp /etc/gitlab/ssl/cert.pem /etc/gitlab/trusted-certs/
    
  3. /etc/gitlab/gitlab.rb를 편집하여 다음을 추가합니다.

    gitaly['configuration'] = {
       # ...
       tls_listen_addr: '0.0.0.0:9999',
       tls: {
          certificate_path: '/etc/gitlab/ssl/cert.pem',
          key_path: '/etc/gitlab/ssl/key.pem',
       },
    }
    
  4. 암호화된 연결만 허용하도록 gitaly['listen_addr']를 삭제합니다.

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

Back to set up components

Sidekiq 구성#

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

환경의 Sidekiq job 처리가 느리고 큐가 길다면 그에 맞게 확장할 수 있습니다. 자세한 내용은 확장 문서를 참고합니다.

Container Registry, SAML, LDAP 같은 추가 GitLab 기능을 구성할 때는 Rails 구성과 함께 Sidekiq 구성도 업데이트합니다. 자세한 내용은 외부 Sidekiq 문서를 참고합니다.

Sidekiq 서버를 구성하려면 Sidekiq에 사용할 서버 노드에서 다음을 수행합니다.

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

  2. PostgreSQL, Gitaly, Redis 포트에 접근할 수 있는지 확인합니다.

    telnet  5432 # PostgreSQL
    telnet  8075 # Gitaly
    telnet  6379 # Redis
    
  3. 원하는 Linux 패키지를 다운로드하여 설치합니다. 선택한 운영 체제에 맞는 GitLab 패키지 리포지터리만 추가하고 GitLab을 설치해야 합니다.

  4. /etc/gitlab/gitlab.rb를 만들거나 편집하여 다음 구성을 사용합니다.

    # https://docs.gitlab.com/omnibus/roles/#sidekiq-roles
    roles(["sidekiq_role"])
    
    # External URL
    external_url 'https://gitlab.example.com'
    
    ## Redis connection details
    gitlab_rails['redis_port'] = '6379'
    gitlab_rails['redis_host'] = '10.1.0.6' # IP/hostname of Redis server
    gitlab_rails['redis_password'] = 'Redis Password'
    
    # Gitaly and GitLab use two shared secrets for authentication, one to authenticate gRPC requests
    # to Gitaly, and a second stored in /etc/gitlab/gitlab-secrets.json for authentication callbacks from GitLab-Shell to the GitLab internal API.
    # The following must be the same as their respective values
    # of the Gitaly setup
    gitlab_rails['gitaly_token'] = 'gitalysecret'
    
    gitlab_rails['repositories_storages'] = {
      'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
    }
    
    ## PostgreSQL connection details
    gitlab_rails['db_adapter'] = 'postgresql'
    gitlab_rails['db_encoding'] = 'unicode'
    gitlab_rails['db_host'] = '10.1.0.5' # IP/hostname of database server
    gitlab_rails['db_password'] = 'DB password'
    
    ## 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
    
    ## Set the network addresses that the exporters will listen on
    node_exporter['listen_address'] = '0.0.0.0:9100'
    
    # 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>'
    }
    
  5. 처음 구성한 Linux 패키지 노드의 /etc/gitlab/gitlab-secrets.json 파일을 복사하여 이 서버의 같은 이름의 파일에 추가하거나 교체합니다. 처음으로 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

  6. 데이터베이스 마이그레이션이 업그레이드 시 자동으로 실행되지 않고 재구성 중에만 실행되도록 다음을 실행합니다.

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

    마이그레이션은 지정된 노드 한 대에서만 처리해야 하며, 자세한 내용은 GitLab Rails 사후 구성 섹션을 참고합니다.

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

  8. GitLab 서비스가 실행 중인지 확인합니다.

    sudo gitlab-ctl status
    

    출력은 다음과 비슷해야 합니다.

    run: logrotate: (pid 192292) 2990s; run: log: (pid 26374) 93048s
    run: node-exporter: (pid 26864) 92997s; run: log: (pid 26446) 93036s
    run: sidekiq: (pid 26870) 92996s; run: log: (pid 26391) 93042s
    
Back to set up components

GitLab Rails 구성#

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

이 아키텍처에서는 각 GitLab Rails 노드를 Puma 웹 서버로 실행하고 워커 수를 사용 가능한 CPU의 90%, 스레드 수를 4개로 설정합니다. Rails를 다른 구성 요소와 함께 실행하는 노드에서는 워커 값을 그에 맞게 줄여야 합니다. 워커 값 50%가 균형이 좋은 것으로 확인했지만, 이는 워크로드에 따라 달라집니다.

각 노드에서 다음을 수행합니다.

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

  2. /etc/gitlab/gitlab.rb를 만들거나 편집하여 다음 구성을 사용합니다. 노드 간 링크의 일관성을 유지하려면 애플리케이션 서버의 external_url이 사용자가 GitLab에 접근할 때 사용하는 외부 URL을 가리켜야 합니다. 이는 GitLab 애플리케이션 서버로 트래픽을 라우팅하는 로드 밸런서의 URL입니다.

    external_url 'https://gitlab.example.com'
    
    # Gitaly and GitLab use two shared secrets for authentication, one to authenticate gRPC requests
    # to Gitaly, and a second stored in /etc/gitlab/gitlab-secrets.json for authentication callbacks from GitLab-Shell to the GitLab internal API.
    # The following must be the same as their respective values
    # of the Gitaly setup
    gitlab_rails['gitaly_token'] = 'gitalysecret'
    
    gitlab_rails['repositories_storages'] = {
      'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
    }
    
    ## Disable components that will not be on the GitLab application server
    roles(['application_role'])
    gitaly['enable'] = false
    sidekiq['enable'] = false
    
    ## PostgreSQL connection details
    gitlab_rails['db_adapter'] = 'postgresql'
    gitlab_rails['db_encoding'] = 'unicode'
    gitlab_rails['db_host'] = '10.1.0.5' # IP/hostname of database server
    gitlab_rails['db_password'] = 'DB password'
    
    ## Redis connection details
    gitlab_rails['redis_port'] = '6379'
    gitlab_rails['redis_host'] = '10.1.0.6' # IP/hostname of Redis server
    gitlab_rails['redis_password'] = 'Redis Password'
    
    # 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. Replace placeholder `monitoring.gitlab.example.com` with
    # the address and/or subnets gathered from the monitoring node
    gitlab_rails['monitoring_whitelist'] = ['/32', '127.0.0.0/8']
    nginx['status']['options']['allow'] = ['/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>'
    }
    
    ## 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
    
  3. TLS 지원이 있는 Gitaly를 사용하는 경우 gitlab_rails['repositories_storages'] 항목이 tcp 대신 tls로 구성되어 있는지 확인합니다.

    gitlab_rails['repositories_storages'] = {
      'default' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
      'storage1' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
      'storage2' => { 'gitaly_address' => 'tls://gitaly2.internal:9999' },
    }
    
    1. 인증서를 /etc/gitlab/trusted-certs에 복사합니다.

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

  5. 처음 구성한 Rails 노드에서 SSH 호스트 키(모두 /etc/ssh/ssh_host_*_key* 이름 형식)를 복사하여 이 서버의 같은 이름의 파일에 추가하거나 교체합니다. 이렇게 하면 사용자가 로드 밸런싱되는 Rails 노드에 접속할 때 호스트 불일치 오류가 발생하지 않습니다. 처음으로 구성하는 Linux 패키지 노드라면 이 단계를 건너뛸 수 있습니다.

  6. 데이터베이스 마이그레이션이 업그레이드 시 자동으로 실행되지 않고 재구성 중에만 실행되도록 다음을 실행합니다.

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

    마이그레이션은 지정된 노드 한 대에서만 처리해야 하며, 자세한 내용은 GitLab Rails 사후 구성 섹션을 참고합니다.

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

  8. 증분 로깅을 활성화합니다.

  9. sudo gitlab-rake gitlab:gitaly:check를 실행하여 노드가 Gitaly에 연결할 수 있는지 확인합니다.

  10. 로그를 tail하여 요청을 확인합니다.

    sudo gitlab-ctl tail gitaly
    

앞의 예시처럼 external_url에 https를 지정하면 GitLab은 SSL 인증서가 /etc/gitlab/ssl/에 있을 것으로 예상합니다. 인증서가 없으면 NGINX가 시작되지 않습니다. 자세한 내용은 HTTPS 문서를 참고합니다.

GitLab Rails 사후 구성#

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

    sudo gitlab-rake gitlab:db:configure
    

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

  2. 데이터베이스에서 승인된 SSH 키를 빠르게 조회하도록 구성합니다.

Back to set up components

Prometheus 구성#

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

  1. 모니터링 노드에 SSH로 접속합니다.

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

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

    roles(['monitoring_role'])
    nginx['enable'] = false
    
    external_url 'http://gitlab.example.com'
    
    # Prometheus
    prometheus['listen_address'] = '0.0.0.0:9090'
    prometheus['monitor_kubernetes'] = false
    
  4. Prometheus는 익스포터를 구성한 여러 노드에서 모든 데이터를 가져오기 위한 스크레이프 구성도 필요합니다. 노드의 IP가 다음과 같다고 가정합니다.

    1.1.1.1: postgres
    1.1.1.2: redis
    1.1.1.3: gitaly1
    1.1.1.4: rails1
    1.1.1.5: rails2
    1.1.1.6: sidekiq
    

    /etc/gitlab/gitlab.rb에 다음을 추가합니다.

    prometheus['scrape_configs'] = [
      {
         'job_name': 'postgres',
         'static_configs' => [
         'targets' => ['1.1.1.1:9187'],
         ],
      },
      {
         'job_name': 'redis',
         'static_configs' => [
         'targets' => ['1.1.1.2:9121'],
         ],
      },
      {
         'job_name': 'gitaly',
         'static_configs' => [
         'targets' => ['1.1.1.3:9236'],
         ],
      },
      {
         'job_name': 'gitlab-nginx',
         'static_configs' => [
         'targets' => ['1.1.1.4:8060', '1.1.1.5:8060'],
         ],
      },
      {
         'job_name': 'gitlab-workhorse',
         'static_configs' => [
         'targets' => ['1.1.1.4:9229', '1.1.1.5:9229'],
         ],
      },
      {
         'job_name': 'gitlab-rails',
         'metrics_path': '/-/metrics',
         'static_configs' => [
         'targets' => ['1.1.1.4:8080', '1.1.1.5:8080'],
         ],
      },
      {
         'job_name': 'gitlab-sidekiq',
         'static_configs' => [
         'targets' => ['1.1.1.6:8082'],
         ],
      },
      {
         'job_name': 'static-node',
         'static_configs' => [
         'targets' => ['1.1.1.1:9100', '1.1.1.2:9100', '1.1.1.3:9100', '1.1.1.4:9100', '1.1.1.5:9100', '1.1.1.6:9100'],
         ],
      },
    ]
    
  5. 파일을 저장하고 GitLab을 재구성합니다.

Back to set up components

오브젝트 스토리지 구성#

GitLab은 오브젝트 스토리지 서비스를 사용하여 여러 유형의 데이터를 보관하는 것을 지원합니다. 데이터 객체에는 NFS보다 오브젝트 스토리지를 권장하며, 오브젝트 스토리지는 일반적으로 성능, 안정성, 확장성이 훨씬 뛰어나므로 대규모 구성에서 대체로 더 좋습니다. 자세한 내용은 인프라와 서비스를 참고합니다.

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

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

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

Back to set up components

증분 로깅 활성화#

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

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

고급 검색 구성#

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

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

Back to set up components

Helm Chart를 사용한 Cloud Native Hybrid 참조 아키텍처(대안)#

대안으로 특정 GitLab 구성 요소를 Kubernetes에서 실행할 수 있습니다. 다음 서비스가 지원됩니다.

  • GitLab Rails
  • Sidekiq
  • NGINX
  • Toolbox
  • Migrations
  • Prometheus

하이브리드 설치는 클라우드 네이티브 배포와 기존 컴퓨트 배포의 장점을 모두 활용합니다. 이를 통해 상태 비저장 구성 요소는 클라우드 네이티브 워크로드 관리의 이점을 누리고, 상태 저장 구성 요소는 영속성이 높다는 이점을 위해 Linux 패키지 설치를 사용하는 컴퓨트 VM에 배포합니다.

설정 방법과 Kubernetes와 백엔드 구성 요소 간에 동기화해야 하는 GitLab 시크릿에 대한 안내는 Helm Chart 고급 구성 문서를 참고합니다.

Note
  • 이는 고급 설정입니다. Kubernetes에서 서비스를 실행하는 것은 복잡하기로 잘 알려져 있습니다. 이 설정은 Kubernetes에 대한 충분한 실무 지식과 경험이 있는 경우에만 권장합니다. 이 섹션의 나머지 부분은 이를 전제로 합니다.
  • 2,000 참조 아키텍처는 고가용성 구성이 아닙니다. HA를 달성하려면 수정된 3K 또는 60 RPS 참조 아키텍처를 따를 수 있습니다.

Kubernetes에서의 Gitaly 가용성, 제한 사항, 배포 시 고려 사항은 Kubernetes의 Gitaly를 참고합니다.

클러스터 토폴로지#

다음 표와 다이어그램은 앞서 설명한 일반 환경과 같은 형식으로 하이브리드 환경을 자세히 설명합니다.

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

구성 요소 노드 그룹 목표 노드 풀 합계 GCP 예시 AWS 예시
Webservice 12 vCPU
15 GB 메모리 (request)
21 GB 메모리 (limit)
3 x n1-standard-8 3 x c5.2xlarge
Sidekiq 3.6 vCPU
8 GB 메모리 (request)
16 GB 메모리 (limit)
2 x n1-standard-4 2 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 예시12 AWS 예시12
PostgreSQL13 1 2 vCPU, 7.5 GB 메모리 n1-standard-2 m5.large
Redis14 1 1 vCPU, 3.75 GB 메모리 n1-standard-1 m5.large
Gitaly15 1 4 vCPU, 15 GB 메모리 n1-standard-4 m5.xlarge
오브젝트 스토리지16 - - - -
Note

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

PlantUML 다이어그램 (32줄)
소스 코드 보기
@startuml 2k
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 }

collections "Supporting Services" as support }

card "Gitaly" as gitaly #FF8C00 card "PostgreSQL" as postgres #4EA7FF card "Redis" as redis #FF6347 cloud "Object Storage" as object_storage #white

elb -[#6a9be7]-> gitlab

gitlab -[#32CD32]--> gitaly gitlab -[#32CD32]--> postgres gitlab -[#32CD32]-> object_storage gitlab -[#32CD32]--> redis

sidekiq -[#ff8dd1]--> gitaly sidekiq -[#ff8dd1]-> object_storage sidekiq -[#ff8dd1]--> postgres sidekiq -[#ff8dd1]--> redis

@enduml

Kubernetes 구성 요소 목표#

다음 섹션에서는 Kubernetes에 배포되는 GitLab 구성 요소에 사용하는 목표를 설명합니다.

Webservice#

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

  • Puma 워커 4개
  • 4 vCPU
  • 5 GB 메모리 (request)
  • 7 GB 메모리 (limit)

40 RPS 또는 2,000명 사용자에는 전체 Puma 워커 수를 약 12개로 하는 것을 권장하며, 따라서 Webservice Pod를 최소 3개 실행하는 것을 권장합니다.

Webservice 리소스 사용량에 대한 자세한 내용은 Chart 문서의 Webservice 리소스를 참고합니다.

Gateway API / Ingress#

Gateway API 또는 Ingress 컨트롤러 Pod도 DaemonSet으로 Webservice 노드에 걸쳐 배포하는 것을 권장합니다. 이렇게 하면 컨트롤러가 담당하는 Webservice Pod에 맞춰 동적으로 확장할 수 있고, 더 큰 머신 유형이 일반적으로 가지는 높은 네트워크 대역폭을 활용할 수 있습니다.

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

Sidekiq#

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

  • Sidekiq 워커 1개
  • 900m vCPU
  • 2 GB 메모리 (request)
  • 4 GB 메모리 (limit)

앞서 설명한 표준 배포와 마찬가지로 여기서는 Sidekiq 워커 4개를 초기 목표로 사용했습니다. 특정 워크플로에 따라 추가 워커가 필요할 수 있습니다.

Sidekiq 리소스 사용량에 대한 자세한 내용은 Chart 문서의 Sidekiq 리소스를 참고합니다.

지원 서비스#

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

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

Container Registry, Pages, 모니터링 같은 추가 배포는 가능하면 Webservice 또는 Sidekiq 풀이 아닌 지원 노드 풀에 배포합니다. 지원 노드 풀은 여러 추가 배포를 수용하도록 설계되었습니다. 그러나 배포가 제시된 풀에 맞지 않으면 그에 맞게 노드 풀을 늘릴 수 있습니다. 반대로 사용 사례에서 풀이 과도하게 프로비저닝되어 있다면 그에 맞게 줄일 수 있습니다.

구성 파일 예시#

40 RPS 또는 2,000명 사용자 참조 아키텍처 구성에 대한 GitLab Helm Chart 예시는 Charts 프로젝트에서 확인할 수 있습니다.

Back to set up components

다음 단계#

이 가이드를 따르면 핵심 기능이 구성된 새로운 GitLab 환경이 준비됩니다.

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

Note

환경과 요구 사항에 따라 원하는 추가 기능을 설정하려면 추가 하드웨어 요구 사항이나 조정이 필요할 수 있습니다. 자세한 내용은 각 페이지를 참고합니다.

Footnotes

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

  2. 신뢰할 수 있는 서드파티 로드 밸런서 또는 서비스(LB PaaS)로 실행하는 것을 권장합니다. 크기는 선택한 로드 밸런서와 네트워크 대역폭 같은 추가 요소에 따라 달라집니다. ↩

  3. 선택적으로 신뢰할 수 있는 서드파티 외부 PaaS PostgreSQL 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 PostgreSQL 인스턴스 제공 및 인프라와 서비스를 참고합니다. ↩

  4. 선택적으로 신뢰할 수 있는 서드파티 외부 PaaS Redis 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 Redis 인스턴스 제공 및 인프라와 서비스를 참고합니다. ↩

  5. Gitaly 사양은 상태가 양호한 일반 크기의 리포지터리를 사용한다는 전제에 기반합니다. 그러나 대형 모노레포(수 기가바이트보다 큰 경우)가 있으면 Git과 Gitaly 성능에 상당한 영향을 줄 수 있으며 사양을 높여야 할 가능성이 큽니다. 자세한 내용은 대형 모노레포를 참고합니다. ↩

  6. 이 구성 요소는 상태 저장 데이터를 저장하지 않으므로 Auto Scaling Group(ASG)에 둘 수 있습니다. 그러나 Cloud Native Hybrid 구성을 일반적으로 더 선호합니다. 마이그레이션과 Mailroom 같은 일부 구성 요소는 노드 한 대에서만 실행할 수 있고, 이는 Kubernetes에서 더 잘 처리되기 때문입니다. ↩ ↩2

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

  8. 웹 터미널 지원에는 로드 밸런서가 WebSocket 연결을 올바르게 처리해야 합니다.

    HTTP 또는 HTTPS 프록시를 사용하는 경우 로드 밸런서가 Connection 및 Upgrade hop-by-hop 헤더를 그대로 전달하도록 구성해야 합니다. 자세한 내용은 웹 터미널 통합 가이드를 참고합니다. ↩ ↩2

  9. 443 포트에 HTTPS 프로토콜을 사용하는 경우 로드 밸런서에 SSL 인증서를 추가해야 합니다. 대신 GitLab 애플리케이션 서버에서 SSL을 종료하려면 TCP 프로토콜을 사용합니다. ↩

  10. GitLab Pages의 백엔드 포트는 gitlab_pages['external_http'] 및 gitlab_pages['external_https'] 설정에 따라 달라집니다. 자세한 내용은 GitLab Pages 문서를 참고합니다. ↩ ↩2

  11. GitLab Pages의 443 포트는 항상 TCP 프로토콜을 사용해야 합니다. 사용자는 사용자 지정 SSL이 적용된 사용자 지정 도메인을 구성할 수 있는데, 로드 밸런서에서 SSL을 종료하면 이것이 불가능해집니다. ↩

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

  13. 선택적으로 신뢰할 수 있는 서드파티 외부 PaaS PostgreSQL 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 PostgreSQL 인스턴스 제공 및 인프라와 서비스를 참고합니다. ↩

  14. 선택적으로 신뢰할 수 있는 서드파티 외부 PaaS Redis 솔루션에서 실행할 수 있습니다. 자세한 내용은 자체 Redis 인스턴스 제공 및 인프라와 서비스를 참고합니다. ↩

  15. Gitaly 사양은 상태가 양호한 일반 크기의 리포지터리를 사용한다는 전제에 기반합니다. 그러나 대형 모노레포(수 기가바이트보다 큰 경우)가 있으면 Git과 Gitaly 성능에 상당한 영향을 줄 수 있으며 사양을 높여야 할 가능성이 큽니다. 자세한 내용은 대형 모노레포를 참고합니다. ↩

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