외부 Gitaly와 함께 GitLab 차트 구성

이 문서는 이 Helm 차트를 외부 Gitaly 서비스와 함께 구성하는 방법에 대한 문서입니다.

Gitaly 구성이 되어 있지 않은 경우 온프레미스나 VM 배포를 위해서는 리눅스 패키지를 사용해보세요.

:::Note 외부 Gitaly _서비스_는 Gitaly 노드 또는 Praefect 클러스터에서 제공될 수 있습니다. :::

차트 구성

gitaly 차트 및 해당 Gitaly 서비스를 비활성화하고 다른 서비스를 외부 서비스로 지정하세요.

다음 속성을 설정해야 합니다:

  • global.gitaly.enabled: 포함된 Gitaly 차트를 비활성화하려면 false로 설정하세요.
  • global.gitaly.external: 외부 Gitaly 서비스의 배열입니다.
  • global.gitaly.authToken.secret: 인증을 위한 시크릿의 이름입니다.
  • global.gitaly.authToken.key: 토큰 내용을 포함하고 있는 시크릿 내의 키입니다.

외부 Gitaly 서비스는 자체 GitLab Shell 인스턴스를 사용합니다. 구현에 따라 해당 차트와 이 차트의 비밀 내용을 구성하거나 사전에 정의된 소스에서 이 차트의 비밀과 함께 구성할 수 있습니다.

다음 속성을 설정해야 할 수 있습니다:

  • global.shell.authToken.secret: GitLab Shell을 위한 시크릿의 이름입니다.
  • global.shell.authToken.key: 시크릿 내의 비밀 내용을 포함하고 있는 키입니다.

두 개의 외부 서비스(external-gitaly.yml)를 사용한 완전한 예제 구성은 다음과 같습니다:

global:
  gitaly:
    enabled: false
    external:
      - name: default                   # 필수
        hostname: node1.git.example.com # 필수
        port: 8075                      # 선택 사항, 표시된 기본값
      - name: praefect                  # 필수
        hostname: ha.git.example.com    # 필수
        port: 2305                      # Praefect는 포트 2305를 사용합니다
        tlsEnabled: false               # 선택 사항, gitaly.tls.enabled를 재정의함
    authToken:
      secret: external-gitaly-token     # 필수
      key: token                        # 선택 사항, 표시된 기본값
    tls:
      enabled: false                    # 선택 사항, 표시된 기본값

위의 구성 파일을 사용한 예제 설치는 다음과 같습니다. 추가 구성은 gitlab.yml을 통해 이루어집니다.

helm upgrade --install gitlab gitlab/gitlab  \
  -f gitlab.yml \
  -f external-gitaly.yml

다중 외부 Gitaly

이 차트를 벗어난 다중 Gitaly 노드를 사용하는 경우 고려해야 할 복잡성을 허용하기 위해 구문이 약간 다릅니다.

예제 값 파일이 제공되었으며 적절한 구성 집합이 표시됩니다. 이 값 파일의 내용은 --set 인수를 통해 올바르게 해석되지 않으므로 Helm에 -f / --values 플래그로 전달해야 합니다.

TLS를 통한 외부 Gitaly 연결

외부 Gitaly 서버가 TLS 포트에서 청취하는 경우, GitLab 인스턴스가 TLS를 통해 해당 서버와 통신하도록 설정할 수 있습니다. 이를 위해 다음을 수행해야 합니다.

  1. Gitaly 서버의 인증서를 포함하는 쿠버네티스 시크릿을 만듭니다.

    kubectl create secret generic gitlab-gitaly-tls-certificate --from-file=gitaly-tls.crt=<인증서 경로>
    
  2. 외부 Gitaly 서버의 인증서를 사용자 지정 인증 기관 목록에 추가합니다. 값 파일에서 다음을 지정하세요.

    global:
      certificates:
        customCAs:
          - secret: gitlab-gitaly-tls-certificate
    

    또는 --set을 사용하여 helm upgrade 명령에 전달하세요.

    --set global.certificates.customCAs[0].secret=gitlab-gitaly-tls-certificate
    
  3. 모든 Gitaly 인스턴스에 대해 TLS를 사용하려면 global.gitaly.tls.enabled: true로 설정하세요.

    global:
      gitaly:
        tls:
          enabled: true
    

    인스턴스별로 사용하려면 해당 항목의 tlsEnabled: true로 설정하세요.

    global:
      gitaly:
        external:
          - name: default
            hostname: node1.git.example.com
            tlsEnabled: true
    

:::Note 유효한 시크릿 이름 및 키를 선택할 수 있지만 customCAs에 지정된 모든 시크릿에서 충돌을 피하기 위해 해당 키가 모든 시크릿에서 고유한지 확인하세요. 인증서 내의 모든 키가 마운트되므로 해당 인증서에 대한 키가 충돌하지 않도록 하세요. 이러한 인증서는 _클라이언트 측_이므로 해당 인증서에 대한 키를 제공할 필요가 없습니다. :::

GitLab이 Gitaly에 연결되는지 테스트

GitLab이 외부 Gitaly 서버에 연결할 수 있는지 확인하려면:

kubectl exec -it <toolbox-pod> -- gitlab-rake gitlab:gitaly:check

Gitaly에 TLS를 사용하는 경우, GitLab Chart가 Gitaly 인증서를 신뢰하는지도 확인할 수 있습니다:

kubectl exec -it <toolbox-pod> -- echo | /usr/bin/openssl s_client -connect <gitaly-host>:<gitaly-port>

Gitaly 차트에서 외부 Gitaly로 마이그레이션

Gitaly 차트를 사용하여 Gitaly 서비스를 제공하고 모든 리포지토리를 외부 Gitaly 서비스로 마이그레이션해야 하는 경우, Gitaly 차트 PersistentVolumeClaim (PVC)에서 리포지토리를 백업한 다음 외부 Gitaly 서비스로 복원할 수 있습니다.

이 작업은 다음과 같습니다:

  • 모든 사용자에게 다운타임이 발생합니다.
  • Praefect 차트와 테스트되지 않았으며 지원되지 않습니다.

단계 1: GitLab Chart의 현재 릴리스 리비전 가져오기

마이그레이션 중에 예기치 않은 문제가 발생하는 경우에 대비하여 GitLab Chart의 현재 릴리스 리비전을 가져옵니다. 출력을 복사하고 롤백을 수행해야 하는 경우를 대비하여 따로 저장합니다:

helm history <release> --max=1

단계 2: 외부 Gitaly 서비스 또는 Gitaly 클러스터 설정

외부 Gitaly 또는 외부 Gitaly 클러스터를 설정합니다. 이러한 단계에 포함하여야 하는 것은 차트 설치 시 Gitaly 토큰 및 GitLab Shell 비밀 값을 제공하여야 합니다:

# GitLab Shell 비밀 가져오기
kubectl get secret <release>-gitlab-shell-secret -ojsonpath='{.data.secret}' | base64 -d

# Gitaly 토큰 가져오기
kubectl get secret <release>-gitaly-secret -ojsonpath='{.data.token}' | base64 -d
Gitaly
  • 여기서 추출한 Gitaly 토큰은 AUTH_TOKEN 값에 사용되어야 합니다.
  • 여기서 추출한 GitLab Shell 비밀은 shellsecret 값에 사용되어야 합니다.
Gitaly 클러스터
  • 여기서 추출한 Gitaly 토큰은 PRAEFECT_EXTERNAL_TOKEN 값에 사용되어야 합니다.
  • 여기서 추출한 GitLab Shell 비밀은 GITLAB_SHELL_SECRET_TOKEN 값에 사용되어야 합니다.

단계 3: 마이그레이션 중에 Git 변경이 불가능한지 확인

마이그레이션의 데이터 무결성을 보장하기 위해 Git 리포지토리에 변경 사항이 발생하지 않도록 합니다:

1. 유지보수 모드 활성화

GitLab Enterprise Edition을 사용하는 경우, UI, API 또는 Rails 콘솔을 통해 유지보수 모드를 활성화합니다:

kubectl exec <toolbox pod name> -it -- gitlab-rails runner 'Gitlab::CurrentSettings.update!(maintenance_mode: true)'

2. Runner 팟 수 축소

GitLab Community Edition을 사용하는 경우, 클러스터에서 실행 중인 모든 GitLab Runner 팟 수를 축소해야 합니다. 이렇게 하면 러너가 GitLab에 연결되어 CI/CD 작업을 처리하는 것을 방지합니다.

GitLab Enterprise Edition을 사용하는 경우, 이 단계는 유지보수 모드 로 인해 선택 사항입니다.

# 러너의 현재 복제본 수를 메모해두어 나중에 이 수로 확장할 수 있도록 합니다
kubectl get deploy -lapp=gitlab-gitlab-runner,release=<release> -o jsonpath='{.items[].spec.replicas}{"\n"}'

# 러너 팟 수를 0으로 축소합니다
kubectl scale deploy -lapp=gitlab-gitlab-runner,release=<release> --replicas=0

3. CI 작업이 실행 중이 아님을 확인

관리 영역에서 CI/CD > 작업으로 이동합니다. 이 페이지에서 모든 작업이 표시되지만 실행 중 상태의 작업이 없는지 확인합니다. 다음 단계로 진행하기 전에 작업이 완료되기를 기다려야 합니다.

4. Sidekiq cron 작업 비활성화

마이그레이션 중에 Sidekiq 작업이 예약되고 실행되는 것을 방지하려면 모든 Sidekiq cron 작업을 비활성화합니다:

kubectl exec <toolbox pod name> -it -- gitlab-rails runner 'Sidekiq::Cron::Job.all.map(&:disable!)'

5. 백그라운드 작업이 실행 중이 아님을 확인

다음 단계로 진행하기 전에 대기해야 하는 큐에 들어있거나 진행 중인 작업이 완료될 때까지 대기해야 합니다.

  1. 관리 영역에서 Monitoring로 이동하고 백그라운드 작업을 선택합니다.
  2. Sidekiq 대시보드에서 를 선택한 후 실시간 폴링을 선택합니다.
  3. 바쁨대기 중이 모두 0이 될 때까지 기다립니다.

    Sidekiq 백그라운드 작업

6. Sidekiq 및 Webservice 팟 수 축소

일관된 백업을 수행하기 위해 Sidekiq 및 Webservice 팟 수를 축소합니다. 두 서비스는 나중에 다시 확장됩니다:

  • 복원 단계에서 Sidekiq 팟을 다시 확장합니다
  • 외부 Gitaly 서비스로 전환한 후에 Webservice 팟을 다시 확장합니다
# Sidekiq 및 Webservice의 현재 복제본 수를 메모해두어 나중에 이 수로 확장할 수 있도록 합니다
kubectl get deploy -lapp=sidekiq,release=<release> -o jsonpath='{.items[].spec.replicas}{"\n"}'
kubectl get deploy -lapp=webservice,release=<release> -o jsonpath='{.items[].spec.replicas}{"\n"}'

# Sidekiq 및 Webservice 팟 수를 0으로 축소합니다
kubectl scale deploy -lapp=sidekiq,release=<release> --replicas=0
kubectl scale deploy -lapp=webservice,release=<release> --replicas=0

7. 클러스터의 외부 연결 제한

GitLab에 변경 사항을 가할 수 없도록 사용자 및 외부 GitLab Runner가 모두 사양하지 않은 연결을 제한해야 합니다.

이러한 단계가 완료되면 복원이 완료될 때까지 브라우저에서 GitLab에 완전히 액세스할 수 없습니다.

마이그레이션 중에 클러스터를 새로운 외부 Gitaly 서비스에게 액세스할 수 있도록 유지하기 위해 nginx-ingress 구성에 외부 예외로 추가해야 합니다.

  1. 다음 내용으로 ingress-only-allow-ext-gitaly.yml 파일을 작성합니다:

    nginx-ingress:
      controller:
        service:
          loadBalancerSourceRanges:
           - "x.x.x.x/32"
    

    x.x.x.x는 외부 Gitaly 서비스의 IP 주소여야 합니다.

  2. gitlab.ymlingress-only-allow-ext-gitaly.yml 파일을 사용하여 새 구성을 적용합니다:

     helm upgrade <release> gitlab/gitlab \
       -f gitlab.yml \
       -f ingress-only-allow-ext-gitaly.yml
    

8. 리포지토리 체크섬 목록 생성

백업을 실행하기 전에 모든 GitLab 리포지토리를 확인하고 리포지토리 체크섬 목록을 생성합니다. 나중에 해당 목록을 사용하여 마이그레이션 후에 체크섬을 diff 할 수 있도록 출력을 파일에 파이핑합니다:

kubectl exec <toolbox pod name> -it -- gitlab-rake gitlab:git:checksum_projects > ~/checksums-before.txt

단계 4: 모든 저장소 백업

귀하의 저장소만 백업을 만들어 보세요:

kubectl exec <toolbox pod name> -it -- backup-utility --skip artifacts,ci_secure_files,db,external_diffs,lfs,packages,pages,registry,terraform_state,uploads

단계 5: 새로운 Gitaly 서비스를 사용하도록 인스턴스 구성

  1. Gitaly 서브차트를 비활성화하고 GitLab을 외부 Gitaly를 사용하도록 구성합니다. 본인의 주 gitlab.yml 구성 파일에 Gitaly 참조가 있다면 해당 참조를 제거하고, 다음 내용으로 새로운 external-gitaly.yml 파일을 만드세요.

    이전에 추가적인 Gitaly 저장소를 정의한 경우, 새 구성에 동일한 이름을 가진 Gitaly 저장소가 지정되어 있는지 확인해야 합니다. 그렇지 않으면 복원 작업이 실패합니다.

    TLS를 구성 중이라면 TLS를 통한 외부 Gitaly 연결 섹션을 참조하세요:

    Gitaly
    global:
      gitaly:
        enabled: false
        external:
          - name: default                   # 필수
            hostname: node1.git.example.com # 필수
            port: 8075                      # 선택 사항, 표시된 기본값
            tlsEnabled: false               # 선택 사항, gitaly.tls.enabled 대체함
    
    Gitaly 클러스터
    global:
      gitaly:
        enabled: false
        external:
          - name: default                   # 필수
            hostname: ha.git.example.com    # 필수
            port: 2305                      # Praefect는 포트 2305를 사용합니다
            tlsEnabled: false               # 선택 사항, gitaly.tls.enabled 대체함
    
  2. 새로운 구성을 gitlab.yml, ingress-only-allow-ext-gitaly.yml, external-gitaly.yml 파일을 사용하여 적용합니다:

     helm upgrade --install gitlab gitlab/gitlab \
       -f gitlab.yml \
       -f ingress-only-allow-ext-gitaly.yml \
       -f external-gitaly.yml
    
  3. Webservice pods를 원래의 레플리카 수로 확장합니다. 실행 중이 아니라면 이 동작이 필요합니다. 이후 GitLab에서 외부 Gitaly 연결을 테스트할 수 있습니다.

    kubectl scale deploy -lapp=webservice,release=<release> --replicas=<value>
    
  4. Toolbox pod에서 GitLab이 외부 Gitaly에 성공적으로 연결되는지 확인합니다:

    kubectl exec <toolbox pod name> -it -- gitlab-rake gitlab:gitaly:check
    
  5. 외부 Gitaly가 차트 설치에 다시 연결할 수 있는지 확인하세요:

    Gitaly

    Gitaly 서비스가 GitLab API에 대해 콜백을 수행할 수 있는지 확인하세요:

    sudo /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
    
    Gitaly 클러스터

    모든 Praefect 노드에서 Praefect 서비스가 Gitaly 노드에 연결할 수 있는지 확인하세요:

    # Praefect 노드에서 실행
    sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes
    

    모든 Gitaly 노드에서 Gitaly 서비스가 GitLab API에 대해 콜백을 수행할 수 있는지 확인하세요:

    # Gitaly 노드에서 실행
    sudo /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
    

단계 6: 백업된 저장소를 복원하고 검증

  1. 이전에 만든 백업 파일을 복원하세요. 그 결과, 저장소가 구성된 외부 Gitaly나 Gitaly 클러스터로 복사됩니다.

  2. 모든 GitLab 저장소를 확인하고 저장소 체크섬 목록을 만드세요. 출력을 파일로 보내어 다음 단계에서 체크섬들을 diff할 수 있게 합니다:

    kubectl exec <toolbox pod name> -it -- gitlab-rake gitlab:git:checksum_projects  > ~/checksums-after.txt
    
  3. 저장소 이전과 이후의 체크섬을 비교하세요. 체크섬이 동일하다면 이 명령은 출력을 반환하지 않습니다:

    diff ~/checksums-before.txt ~/checksums-after.txt
    

    특정 줄에서 빈 체크섬이 0000000000000000000000000000000000000000으로 변경된 것을 diff에서 관찰한다면, 이것은 예상된 동작이며 안전하게 무시할 수 있습니다.

단계 7: 최종 구성 및 유효성 검사

  1. 외부 사용자 및 GitLab 러너가 다시 GitLab에 연결할 수 있도록하기 위해 gitlab.ymlexternal-gitaly.yml 파일을 적용합니다. ingress-only-allow-ext-gitaly.yml을 지정하지 않았기 때문에 IP 제한이 제거됩니다:

     helm upgrade <릴리스> gitlab/gitlab \
       -f gitlab.yml \
       -f external-gitaly.yml
    

    미래를 위해 외부 Gitaly 구성을 포함하는 통합 gitlab.yml을 생성하는 것을 고려해보세요:

     helm get values <릴리스> gitlab/gitlab -o yaml > gitlab.yml
    
  2. GitLab 엔터프라이즈 에디션을 사용 중이라면 유지 보수 모드를 UI, API 또는 Rails 콘솔을 통해 비활성화합니다:

    kubectl exec <toolbox pod 이름> -it -- gitlab-rails runner 'Gitlab::CurrentSettings.update!(maintenance_mode: false)'
    
  3. 여러 Gitaly 저장소가 있는 경우, 새 저장소가 저장될 위치를 구성합니다.

  4. Sidekiq cron 작업을 활성화합니다:

    kubectl exec <toolbox pod 이름> -it -- gitlab-rails runner 'Sidekiq::Cron::Job.all.map(&:enable!)'
    
  5. 러너 파드를 원래 복제본 수에 맞게 스케일 업합니다.

    kubectl scale deploy -lapp=gitlab-gitlab-runner,release=<릴리스> --replicas=<값>
    
  6. 모든 것이 예상대로 작동하는지 확인한 후, Gitaly PVC를 삭제할 수 있습니다.

    경고: 단계 6에 따라 체크섬이 일치하는지 확인하고 모든 것이 예상대로 작동하는지 다시 한 번 확인하기 전까지 Gitaly PVC를 삭제하지 마십시오.

    kubectl delete pvc repo-data-<릴리스>-gitaly-0
    

롤백

문제가 발생하면 변경된 내용을 롤백하여 Gitaly subchart를 다시 사용할 수 있습니다.

원래 Gitaly PVC는 성공적으로 롤백하기 위해 존재하여야 합니다.

  1. 단계 1: GitLab Chart의 현재 릴리스 리비전 가져오기에서 얻은 리비전 번호를 사용하여 GitLab 차트를 이전 릴리스로 롤백합니다.

    helm rollback <릴리스> <리비전>
    
  2. Webservice 파드를 원래 복제본 수에 맞게 스케일 업합니다.

    kubectl scale deploy -lapp=webservice,release=<릴리스> --replicas=<값>
    
  3. Sidekiq 파드를 원래 복제본 수에 맞게 스케일 업합니다.

    kubectl scale deploy -lapp=sidekiq,release=<릴리스> --replicas=<값>
    
  4. 이전에 비활성화한 경우 Sidekiq cron 작업을 다시 활성화합니다.

    kubectl exec <toolbox pod 이름> -it -- gitlab-rails runner 'Sidekiq::Cron::Job.all.map(&:enable!)'
    
  5. 러너 파드를 원래 복제본 수에 맞게 스케일 업합니다.

    kubectl scale deploy -lapp=gitlab-gitlab-runner,release=<릴리스> --replicas=<값>
    
  6. GitLab 엔터프라이즈 에디션을 사용 중이라면, 유지 보수 모드가 활성화되어 있으면 비활성화합니다.

관련 문서