Gitaly 구성

Tier: Free, Premium, Ultimate Offering: Self-managed

다음 두 가지 방법 중 하나로 Gitaly를 구성하세요:

Linux 패키지 (Omnibus)
  1. /etc/gitlab/gitlab.rb를 편집하고
    Gitaly 설정을 추가하거나 변경합니다.
  2. 파일을 저장하고 GitLab을 재구성합니다.
Helm 차트 (Kubernetes)
  1. Gitaly 차트를 구성합니다.
  2. Helm 릴리스를 업그레이드합니다.
수동 컴파일 (소스)
  1. /home/git/gitaly/config.toml을 편집하고 Gitaly 설정을 추가하거나 변경합니다.
  2. 파일을 저장하고 GitLab을 재시작합니다.

다음 구성 옵션도 사용할 수 있습니다:

Gitaly 토큰에 대하여

Gitaly 문서 전반에 걸쳐 언급된 토큰은 단순히 관리자가 선택한 임의의 비밀번호입니다.
이것은 GitLab API 또는 기타 유사한 웹 API 토큰을 위해 생성된 토큰과는 관련이 없습니다.

Gitaly를 자체 서버에서 실행

기본적으로 Gitaly는 Gitaly 클라이언트와 같은 서버에서 실행되며
위와 같이 구성됩니다. 단일 서버 설치는 다음과 같은 기본 구성이 가장 적합합니다:

그러나 Gitaly는 자체 서버에 배포할 수 있으며, 이는 여러 머신에 걸쳐 있는 GitLab 설치에 이점을 제공할 수 있습니다.

note
자체 서버에서 실행되도록 구성된 경우,
Gitaly 서버는 클러스터의 Gitaly 클라이언트보다 업그레이드되어야 합니다.
note

Gitaly를 자체 서버에 설정하는 과정은 다음과 같습니다:

  1. Gitaly 설치.
  2. 인증 구성.
  3. Gitaly 서버 구성.
  4. Gitaly 클라이언트 구성.
  5. 필요하지 않은 Gitaly 비활성화 (선택 사항).

네트워크 아키텍처

다음 목록은 Gitaly의 네트워크 아키텍처를 나타냅니다:

  • GitLab Rails는 리포지토리를 리포지토리 저장소로 분할합니다.
  • /config/gitlab.yml에는 저장소 이름에서 (Gitaly 주소, Gitaly 토큰) 쌍으로의 매핑이 포함됩니다.
  • /config/gitlab.ymlstorage name -> (Gitaly 주소, Gitaly 토큰) 매핑은 Gitaly 네트워크 토폴로지에 대한 유일한
    진실의 원천입니다.
  • (Gitaly 주소, Gitaly 토큰)는 Gitaly 서버에 해당합니다.
  • Gitaly 서버는 하나 이상의 저장소를 호스팅합니다.
  • Gitaly 클라이언트는 하나 이상의 Gitaly 서버를 사용할 수 있습니다.
  • Gitaly 주소는 모든 Gitaly 클라이언트가 올바르게 해결될 수 있도록 지정되어야 합니다.
  • Gitaly 클라이언트는:
    • Puma.
    • Sidekiq.
    • GitLab Workhorse.
    • GitLab Shell.
    • Elasticsearch 인덱서.
    • Gitaly 자체.
  • Gitaly 서버는 /config/gitlab.yml에 지정된 자신의
    (Gitaly 주소, Gitaly 토큰) 쌍을 사용하여 자체에 대한 RPC 호출을 할 수 있어야 합니다.
  • 인증은 Gitaly 및 GitLab Rails 노드 간에 공유되는 정적 토큰을 통해 수행됩니다.

다음 다이어그램은 Gitaly 서버와 GitLab Rails 간의 통신을 나타내며
HTTP 및 HTTPS 통신을 위한 기본 포트를 보여줍니다.

두 개의 Gitaly 서버와 정보를 교환하는 GitLab Rails

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

다음 섹션에서는 비밀 토큰 abc123secret를 사용하여 두 개의 Gitaly 서버를 구성하는 방법을 설명합니다:

  • gitaly1.internal.
  • gitaly2.internal.

세 개의 리포지토리 저장소가 있는 GitLab 설치가 있다고 가정합니다:

  • default.
  • storage1.
  • storage2.

원하는 경우 하나의 리포지토리 저장소가 있는 서버만 사용할 수 있습니다.

Gitaly 설치

Gitaly를 각 Gitaly 서버에 다음 방법 중 하나로 설치합니다:

  • 리눅스 패키지 설치. 다운로드 및 설치 원하는 리눅스 패키지를 다운로드하지만 EXTERNAL_URL= 값을 제공하지 마십시오.
  • 자체 컴파일 설치. Gitaly 설치에서 단계를 따릅니다.

Gitaly 서버 구성

Gitaly 서버를 구성하려면 다음과 같이 해야 합니다:

  • 인증 구성.
  • 저장소 경로 구성.
  • 네트워크 리스너 활성화.

git 사용자는 구성된 저장소 경로를 읽고, 쓰고, 권한을 설정할 수 있어야 합니다.

Gitaly 토큰을 회전하는 동안 다운타임을 피하려면 gitaly['auth_transitioning'] 설정을 사용하여 인증을 일시적으로 비활성화할 수 있습니다. 자세한 내용은 “auth transitioning mode” 활성화 문서를 참조하십시오.

인증 구성

Gitaly와 GitLab은 인증을 위해 두 개의 공유 비밀을 사용합니다:

  • Gitaly token: Gitaly에 대한 gRPC 요청을 인증하는 데 사용됩니다.
  • GitLab Shell token: GitLab Shell에서 GitLab 내부 API로의 인증 콜백에 사용됩니다.
리눅스 패키지 (Omnibus)
  1. _Gitaly token_을 구성하려면 /etc/gitlab/gitlab.rb를 편집합니다:

    gitaly['configuration'] = {
       # ...
       auth: {
         # ...
         token: 'abc123secret',
       },
    }
    
  2. _GitLab Shell token_을 두 가지 방법 중 하나로 구성합니다:

    • 방법 1 (권장):

      Gitaly 클라이언트에서 /etc/gitlab/gitlab-secrets.json을 Gitaly 서버의 동일한 경로로 복사합니다 (및 다른 Gitaly 클라이언트).

    • 방법 2:

      /etc/gitlab/gitlab.rb를 편집합니다:

      gitlab_shell['secret_token'] = 'shellsecret'
      
자체 컴파일 (소스)
  1. Gitaly 클라이언트에서 /home/git/gitlab/.gitlab_shell_secret를 동일한 경로의 Gitaly 서버로 복사합니다 (및 다른 Gitaly 클라이언트).

  2. Gitaly 클라이언트에서 /home/git/gitlab/config/gitlab.yml을 편집합니다:

    gitlab:
      gitaly:
        token: 'abc123secret'
    
  3. 파일을 저장하고 GitLab 재시작을 수행합니다.

  4. Gitaly 서버에서 /home/git/gitaly/config.toml을 편집합니다:

    [auth]
    token = 'abc123secret'
    
  5. 파일을 저장하고 GitLab 재시작을 수행합니다.

Gitaly 서버 구성

Gitaly 서버를 구성합니다.

리눅스 패키지 (Omnibus)
  1. /etc/gitlab/gitlab.rb를 편집합니다:

    # Gitaly 서버에서 불필요한 서비스 실행 방지
    postgresql['enable'] = false
    redis['enable'] = false
    nginx['enable'] = false
    puma['enable'] = false
    sidekiq['enable'] = false
    gitlab_workhorse['enable'] = false
    gitlab_exporter['enable'] = false
    gitlab_kas['enable'] = false
    
    # 별도의 모니터링 노드를 실행하는 경우 이러한 서비스를 비활성화할 수 있습니다
    prometheus['enable'] = false
    alertmanager['enable'] = false
    
    # 별도의 모니터링 노드를 실행하지 않는 경우
    # Prometheus 액세스를 활성화하고 이러한 추가 서비스를 비활성화할 수 있습니다.
    # 이렇게 하면 Prometheus가 모든 인터페이스에서 수신 대기합니다. 방화벽을 사용하여 이 주소/포트에 대한 액세스를 제한해야 합니다.
    # prometheus['listen_address'] = '0.0.0.0:9090'
    # prometheus['monitor_kubernetes'] = false
    
    # 모니터링 서비스를 실행하고 싶지 않은 경우 다음을 주석 해제하십시오(권장되지 않음)
    # node_exporter['enable'] = false
    
    # 'gitlab-ctl reconfigure' 중 데이터베이스 연결 방지
    gitlab_rails['auto_migrate'] = false
    
    # gitlab-shell API 콜백 URL을 구성합니다. 이것 없이 `git push`가
    # 실패합니다. 이것은 귀하의 '프론트 도어' GitLab URL 또는 내부 로드
    # 밸런서가 될 수 있습니다.
    # Gitaly 클라이언트에서 Gitaly 서버로 `/etc/gitlab/gitlab-secrets.json` 복사를 잊지 마세요.
    gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
    
    gitaly['configuration'] = {
       # ...
       #
       # Gitaly이 모든 네트워크 인터페이스에서 연결을 수락하도록 설정합니다. 방화벽을 사용하여 이 주소/포트에 대한 액세스를 제한해야 합니다.
       # TLS 연결만 지원하려면 다음 줄을 주석 처리하십시오.
       listen_addr: '0.0.0.0:8075',
       auth: {
         # ...
         #
         # 인증 토큰으로 인해 권한이 부여된 서버만 Gitaly 서버와 통신할 수 있습니다.
         token: 'AUTH_TOKEN',
       },
    }
    
  2. 각 Gitaly 서버에 대해 /etc/gitlab/gitlab.rb에 다음을 추가합니다:

    gitaly1.internal에서:

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

    gitaly2.internal에서:

    gitaly['configuration'] = {
       # ...
       storage: [
          {
             name: 'storage2',
             path: '/srv/gitlab/git-data/repositories',
          },
       ],
    }
    
  3. 파일을 저장하고 GitLab 재구성을 수행합니다.

  4. Gitaly가 GitLab 내부 API에 콜백을 수행할 수 있는지 확인합니다:

    • GitLab 15.3 이상인 경우 sudo -u git -- /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml을 실행합니다.
    • GitLab 15.2 이하인 경우 sudo -u git -- /opt/gitlab/embedded/bin/gitaly-hooks check /var/opt/gitlab/gitaly/config.toml을 실행합니다.
자체 컴파일 (소스)
  1. /home/git/gitaly/config.toml을 편집합니다:

    listen_addr = '0.0.0.0:8075'
    
    runtime_dir = '/var/opt/gitlab/gitaly'
    
    [logging]
    format = 'json'
    level = 'info'
    dir = '/var/log/gitaly'
    
  2. 각 Gitaly 서버에 대해 /home/git/gitaly/config.toml에 다음을 추가합니다:

    gitaly1.internal에서:

    [[storage]]
    name = 'default'
    path = '/var/opt/gitlab/git-data/repositories'
    
    [[storage]]
    name = 'storage1'
    path = '/mnt/gitlab/git-data/repositories'
    

    gitaly2.internal에서:

    [[storage]]
    name = 'storage2'
    path = '/srv/gitlab/git-data/repositories'
    
  3. /home/git/gitlab-shell/config.yml을 편집합니다:

    gitlab_url: https://gitlab.example.com
    
  4. 파일을 저장하고 GitLab 재시작을 수행합니다.

  5. Gitaly가 GitLab 내부 API에 콜백을 수행할 수 있는지 확인합니다:

    • GitLab 15.3 이상인 경우 sudo -u git -- /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml을 실행합니다.
    • GitLab 15.2 이하인 경우 sudo -u git -- /opt/gitlab/embedded/bin/gitaly-hooks check /var/opt/gitlab/gitaly/config.toml을 실행합니다.

경고: GitLab 서버에서 Gitaly로 리포지토리 데이터를 직접 복사하는 경우 메타데이터 파일인 기본 경로 /var/opt/gitlab/git-data/repositories/.gitaly-metadata가 전송에 포함되지 않도록 해야 합니다. 이 파일을 복사하면 GitLab이 Gitaly 서버에 호스팅된 리포지토리로 직접 디스크 액세스를 사용하게 되어 파이프라인 생성 오류커밋을 찾을 수 없음 오류 또는 stale 데이터가 발생할 수 있습니다.

Gitaly 클라이언트 구성

마지막 단계로, Gitaly 클라이언트를 업데이트하여 로컬 Gitaly 서비스에서 방금 구성한 Gitaly 서버를 사용하도록 전환해야 합니다.

note
GitLab은 default 리포지토리 저장소가 구성되어 있어야 합니다.

이 제한 사항에 대해 더 읽어보세요.

이는 Gitaly 클라이언트가 Gitaly 서버에 도달하지 못하게 하는 모든 사항이 모든 Gitaly 요청을 실패하게 만들 수 있으므로 위험할 수 있습니다. 예를 들어, 네트워크, 방화벽 또는 이름 해석 문제 등이 있습니다.

Gitaly는 다음과 같은 가정을 합니다:

  • gitaly1.internal Gitaly 서버는 Gitaly 클라이언트에서 gitaly1.internal:8075로 접근할 수 있으며, Gitaly 서버는 /var/opt/gitlab/git-data/mnt/gitlab/git-data에서 읽기, 쓰기 및 권한 설정이 가능합니다.
  • gitaly2.internal Gitaly 서버는 Gitaly 클라이언트에서 gitaly2.internal:8075로 접근할 수 있으며, Gitaly 서버는 /srv/gitlab/git-data에서 읽기, 쓰기 및 권한 설정이 가능합니다.
  • gitaly1.internalgitaly2.internal Gitaly 서버는 서로 접근할 수 있습니다.

로컬 Gitaly 서버(꺼져 있는 gitaly_address)와 원격 서버(gitaly_address)를 서로 혼합하여 정의할 수 없습니다.

Gitaly 클라이언트를 두 가지 방법 중 하나로 구성하십시오. 이러한 지침은 암호화되지 않은 연결을 위한 것이지만 TLS 지원도 활성화할 수 있습니다:

리눅스 패키지 (Omnibus)
  1. /etc/gitlab/gitlab.rb를 엽니다:

    # 모든 Gitaly 서버에서 구성된 동일한 토큰 값을 사용합니다.
    gitlab_rails['gitaly_token'] = '<AUTH_TOKEN>'
    
    git_data_dirs({
      'default'  => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
    })
    

    또는 각각의 Gitaly 서버가 다른 인증 토큰을 사용하도록 구성되어 있는 경우:

    git_data_dirs({
      'default'  => { 'gitaly_address' => 'tcp://gitaly1.internal:8075', 'gitaly_token' => '<AUTH_TOKEN_1>' },
      'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075', 'gitaly_token' => '<AUTH_TOKEN_1>' },
      'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075', 'gitaly_token' => '<AUTH_TOKEN_2>' },
    })
    
  2. 파일을 저장하고 GitLab 재구성을 수행합니다.

  3. Gitaly 클라이언트(예: Rails 애플리케이션)에서 sudo gitlab-rake gitlab:gitaly:check를 실행하여 Gitaly 서버에 연결할 수 있는지 확인합니다.

  4. 로그를 실시간으로 보려면:

    sudo gitlab-ctl tail gitaly
    
소스에서 컴파일한 경우
  1. /home/git/gitlab/config/gitlab.yml을 엽니다:

    gitlab:
      repositories:
        storages:
          default:
            gitaly_address: tcp://gitaly1.internal:8075
            gitaly_token: AUTH_TOKEN_1
          storage1:
            gitaly_address: tcp://gitaly1.internal:8075
            gitaly_token: AUTH_TOKEN_1
          storage2:
            gitaly_address: tcp://gitaly2.internal:8075
            gitaly_token: AUTH_TOKEN_2
    
  2. 파일을 저장하고 GitLab 재시작을 수행합니다.

  3. sudo -u git -H bundle exec rake gitlab:gitaly:check RAILS_ENV=production을 실행하여 Gitaly 클라이언트가 Gitaly 서버에 연결할 수 있는지 확인합니다.

  4. 로그를 실시간으로 보려면:

    tail -f /home/git/gitlab/log/gitaly.log
    

Gitaly 서버에서 Gitaly 로그를 tail하면 요청이 들어오는 것을 볼 수 있어야 합니다. Gitaly 요청을 트리거하는 확실한 방법 중 하나는 GitLab에서 HTTP 또는 HTTPS를 통해 리포지토리를 클론하는 것입니다.

caution

서버 후크가 서버 후크로 구성되어 있는 경우, 리포지토리별 또는 전역으로 구성되어 있으면 이를 Gitaly 서버로 이동해야 합니다. 여러 Gitaly 서버가 있는 경우, 서버 후크를 모든 Gitaly 서버에 복사해야 합니다.

혼합 구성

GitLab은 여러 Gitaly 서버 중 하나와 동일한 서버에 존재할 수 있지만, 로컬 및 원격 구성을 혼합하는 구성을 지원하지 않습니다. 다음 설정은 잘못된 것입니다. 이유는 다음과 같습니다:

  • 모든 주소는 다른 Gitaly 서버에서 도달할 수 있어야 합니다.

  • storage1은 일부 Gitaly 서버에 대해 유효하지 않은 gitaly_address에 Unix 소켓이 할당되어 있습니다.

git_data_dirs({
  'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
  'storage1' => { 'path' => '/mnt/gitlab/git-data' },
  'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
})

로컬 및 원격 Gitaly 서버를 결합하려면 로컬 Gitaly 서버에 외부 주소를 사용하십시오. 예를 들어:

git_data_dirs({
  'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
  # Gitaly가 실행 중인 GitLab 서버의 주소
  'storage1' => { 'gitaly_address' => 'tcp://gitlab.internal:8075' },
  'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
})

gitaly['configuration'] = {
  # ...
  #
  # Gitaly 가 모든 네트워크 인터페이스에서 연결을 수용하도록 설정
  listen_addr: '0.0.0.0:8075',
  # 또는 TLS의 경우
  tls_listen_addr: '0.0.0.0:9999',
  tls: {
    certificate_path:  '/etc/gitlab/ssl/cert.pem',
    key_path: '/etc/gitlab/ssl/key.pem',
  },
  storage: [
    {
      name: 'storage1',
      path: '/mnt/gitlab/git-data/repositories',
    },
  ],
}

path는 로컬 Gitaly 서버의 스토리지 샤드에 대해서만 포함될 수 있습니다. 제외될 경우, 해당 스토리지 샤드에 대해 기본 Git 저장소 디렉토리가 사용됩니다.

GitLab은 기본 저장소 스토리지를 필요로 합니다

Gitaly 서버를 환경에 추가할 때 원래의 default Gitaly 서비스를 교체하고 싶을 수 있습니다. 그러나 GitLab은 git_data_dirs에서 default 항목을 제거하도록 GitLab 애플리케이션 서버를 재구성할 수 없습니다. GitLab은 default라는 git_data_dirs 항목을 필요로 합니다. 이 제한 사항에 대해 자세히 읽어보기.

제한 사항을 우회하는 방법:

  1. 새로운 Gitaly 서비스에서 추가 스토리지 위치를 정의하고 추가 스토리지를 default로 구성하십시오.
  2. 관리자 영역에서, default를 0의 가중치로 설정하여 저장소가 거기에 저장되지 않도록 합니다.

필요하지 않은 Gitaly 비활성화 (선택 사항)

Gitaly를 원격 서비스로 실행할 경우, 기본적으로 GitLab 서버에서 실행되는 로컬 Gitaly 서비스를 비활성화하고 필요한 경우에만 실행하는 것을 고려하십시오.

GitLab 인스턴스에서 Gitaly를 비활성화하는 것은 Gitaly가 GitLab 인스턴스와 별도의 머신에서 실행되는 사용자 정의 클러스터 구성에서 GitLab을 실행할 때만 의미가 있습니다. 클러스터의 모든 머신에서 Gitaly를 비활성화하는 것은 유효한 구성(일부 머신은 Gitaly 서버 역할을 해야 함)이 아닙니다.

GitLab 서버에서 Gitaly를 비활성화하는 방법은 두 가지입니다:

리눅스 패키지 (Omnibus)
  1. /etc/gitlab/gitlab.rb를 편집하십시오:

    gitaly['enable'] = false
    
  2. 파일을 저장하고 GitLab을 재구성합니다.

소스에서 컴파일 (Self-compiled)
  1. /etc/default/gitlab를 편집하십시오:

    gitaly_enabled=false
    
  2. 파일을 저장하고 GitLab을 재시작합니다.

제어 그룹

경고:

환경에 대한 제한을 활성화하는 것은 신중하게 수행해야 하며

예기치 않은 트래픽으로부터 보호할 필요가 있는 특정 상황에서만 수행해야 합니다.

제한에 도달하면 실제로 연결이 끊어져 사용자가 부정적으로 영향을 받을 수 있습니다.

일관되고 안정적인 성능을 위해서는 먼저 노드 사양을 조정하거나

대규모 리포지토리 검토 또는 작업 부하를 탐색하는 등의 다른 옵션을 고려해야 합니다.

메모리에 대한 cgroups를 활성화할 때는

프로세스가 종료되지 않고 그 대신 스왑을 사용하게 될 수 있으므로,

Gitaly 노드에서 스왑이 구성되지 않도록 해야 합니다.

이런 상황은 성능이 크게 저하될 수 있습니다.

Linux에서 제어 그룹(cgroups)을 사용하여 Gitaly 프로세스가 사용할 수 있는 메모리 및 CPU 양에 제한을 둘 수 있습니다.

자세한 내용은 cgroups Linux 매뉴얼 페이지를 참조하세요.

cgroups는 메모리 및 CPU 과소비로 인한 예기치 않은 리소스 고갈로부터 시스템을 보호하는 데 도움이 될 수 있습니다.

일부 Git 작업은 다음과 같은 상황에서 고갈까지 상당한 리소스를 소모할 수 있습니다:

  • 예기치 않게 높은 트래픽.
  • 모범 사례를 따르지 않는 대규모 리포지토리에 대한 작업.

하드 보호로, cgroups를 사용하여 이러한 작업이 시스템 리소스를 모두 소모하고 불안정을 초래하기 전에 종료하도록 커널을 구성할 수 있습니다.

Gitaly에는 내장된 cgroups 제어가 있습니다. 설정되면 Gitaly는 Git 프로세스를 Git 명령이 작동하는 리포지토리를 기반으로 cgroup에 할당합니다. 이러한 cgroups는 리포지토리 cgroups라고 합니다. 각 리포지토리 cgroup:

  • 메모리 및 CPU 제한이 있습니다.
  • 단일 리포지토리를 위한 Git 프로세스를 포함합니다.
  • 주어진 리포지토리를 위한 Git 프로세스가 항상 동일한 cgroup에 배치되도록 일관된 해시를 사용합니다.

리포지토리 cgroup이 다음에 도달하면:

  • 메모리 제한에 도달하면, 커널은 종료할 후보 프로세스를 검색합니다.
  • CPU 제한에 도달해도 프로세스는 종료되지 않고, 프로세스가 허용된 것 이상으로 CPU를 소모하는 것을 방지합니다.

노트:

이러한 제한에 도달하면 성능이 저하될 수 있으며 사용자가 연결이 끊어질 수 있습니다.

리포지토리 cgroups 구성 (새로운 방법)

  • 이 리포지토리 cgroups 구성 방법은 GitLab 15.1에서 도입되었습니다.
  • cpu_quota_us는 GitLab 15.10에서 도입됨.
  • max_cgroups_per_repo는 GitLab 16.7에서 도입됨.

Gitaly에서 새로운 방법을 사용하여 리포지토리 cgroups를 구성하기 위해서는

다음 설정을 /etc/gitlab/gitlab.rbgitaly['configuration'][:cgroups]에 사용하세요:

  • mountpoint는 부모 cgroup 디렉토리가 마운트되는 위치입니다. 기본값은 /sys/fs/cgroup입니다.
  • hierarchy_root는 Gitaly에서 그룹을 생성하는 부모 cgroup으로, Gitaly가 실행되는 사용자 및 그룹이 소유할 것으로 간주됩니다. Linux 패키지 설치 시 Gitaly가 시작할 때 mountpoint/<cpu|memory>/hierarchy_root 디렉토리 세트를 생성합니다.
  • memory_bytes는 Gitaly에서 생성하는 모든 Git 프로세스에 집합적으로 부여되는 총 메모리 제한입니다. 0은 제한이 없음을 의미합니다.
  • cpu_shares는 Gitaly에서 생성하는 모든 Git 프로세스에 집합적으로 부여되는 CPU 제한입니다. 0은 제한이 없음을 의미합니다. 최대치는 1024 shares로, 이는 100%의 CPU를 나타냅니다.
  • cpu_quota_us는 이 할당량 값을 초과할 경우 cgroups 프로세스를 제한하기 위한 cfs_quota_us입니다. 우리는 cfs_period_us100ms로 설정하여 1 코어는 100000입니다. 0은 제한이 없음을 의미합니다.
  • repositories.count는 cgroups 풀에 있는 cgroups 수입니다. 새 Git 명령이 생성될 때마다 Gitaly는 이 명령을 위해 해당 리포지토리에 기반하여 이러한 cgroups 중 하나에 할당합니다. 순환 해싱 알고리즘이 Git 명령을 이러한 cgroups에 할당하므로 특정 리포지토리를 위한 Git 명령은 항상 동일한 cgroup에 할당됩니다.
  • repositories.memory_bytes는 리포지토리 cgroup에 포함된 모든 Git 프로세스에 부여되는 총 메모리 제한입니다. 0은 제한이 없음을 의미합니다. 이 값은 최상위 memory_bytes 값을 초과할 수 없습니다.
  • repositories.cpu_shares는 리포지토리 cgroup에 포함된 모든 Git 프로세스에 부여되는 CPU 제한입니다. 0은 제한이 없음을 의미합니다. 최대치는 1024 shares로, 이는 100%의 CPU를 나타냅니다. 이 값은 최상위 cpu_shares 값을 초과할 수 없습니다.
  • repositories.cpu_quota_us는 리포지토리 cgroup에 포함된 모든 Git 프로세스에 부여되는 cfs_quota_us입니다. Git 프로세스는 주어진 할당량 이상을 사용할 수 없습니다. 우리는 cfs_period_us100ms로 설정하여 1 코어는 100000입니다. 0은 제한이 없음을 의미합니다.
  • repositories.max_cgroups_per_repo는 특정 리포지토리를 대상으로 하는 Git 프로세스가 분산될 수 있는 리포지토리 cgroups의 수입니다. 이는 리포지토리 cgroups에 대해 보다 보수적인 CPU 및 메모리 제한을 구성할 수 있게 하면서도 작업 부하가 폭발적으로 증가하는 것을 허용합니다. 예를 들어, max_cgroups_per_repo2이고 memory_bytes 제한이 10GB인 경우, 특정 리포지토리에 대한 독립 Git 작업은 최대 20GB의 메모리를 소모할 수 있습니다.

예: (반드시 권장되는 설정은 아님)

# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
  # ...
  cgroups: {
    mountpoint: '/sys/fs/cgroup',
    hierarchy_root: 'gitaly',
    memory_bytes: 64424509440, # 60gb
    cpu_shares: 1024,
    cpu_quota_us: 400000 # 4 cores
    repositories: {
      count: 1000,
      memory_bytes: 32212254720, # 20gb
      cpu_shares: 512,
      cpu_quota_us: 200000, # 2 cores
      max_cgroups_per_repo: 2
    },
  },
}

저장소 cgroups 구성 (구식 방법)

Gitaly에서 저장소 cgroups를 구식 방법으로 구성하려면 /etc/gitlab/gitlab.rb에서 다음 설정을 사용하세요:

  • cgroups_count는 생성된 cgroups의 수입니다. 새로운 명령이 시작될 때마다 Gitaly는 명령의 명령줄 인수에 따라 이러한 cgroups 중 하나에 할당합니다. 순환 해싱 알고리즘이 이 cgroups에 명령을 할당합니다.
  • cgroups_mountpoint는 부모 cgroup 디렉토리가 마운트되는 위치입니다. 기본값은 /sys/fs/cgroup입니다.
  • cgroups_hierarchy_root는 Gitaly에서 그룹을 생성하는 부모 cgroup이며, Gitaly가 실행되는 사용자 및 그룹에 의해 소유되어야 합니다. Linux 패키지 설치는 Gitaly가 시작될 때 mountpoint/<cpu|memory>/hierarchy_root라는 디렉토리 집합을 생성합니다.
  • cgroups_memory_enabled는 cgroups의 메모리 제한을 활성화하거나 비활성화합니다.
  • cgroups_memory_bytes는 각 cgroup이 추가된 프로세스에 부과하는 총 메모리 제한입니다.
  • cgroups_cpu_enabled는 cgroups의 CPU 제한을 활성화하거나 비활성화합니다.
  • cgroups_cpu_shares는 각 cgroup이 추가된 프로세스에 부과하는 CPU 제한입니다. 최대는 1024 shares로, 이는 100% CPU를 나타냅니다.

예를 들어:

# in /etc/gitlab/gitlab.rb
gitaly['cgroups_count'] = 1000
gitaly['cgroups_mountpoint'] = "/sys/fs/cgroup"
gitaly['cgroups_hierarchy_root'] = "gitaly"
gitaly['cgroups_memory_limit'] = 32212254720
gitaly['cgroups_memory_enabled'] = true
gitaly['cgroups_cpu_shares'] = 1024
gitaly['cgroups_cpu_enabled'] = true

과잉 할당 구성

새로운 구성 방법을 사용한 이전 예제에서:

  • 최상위 메모리 제한은 60 GB로 제한됩니다.
  • 저장소 풀의 1000개 cgroup 각각은 20 GB로 제한됩니다.

이 구성은 “과잉 할당”으로 이어집니다. 풀의 각 cgroup은 최상위 메모리 제한의 1/1000보다 훨씬 큰 용량을 가지고 있습니다.

이 전략에는 두 가지 주요 이점이 있습니다:

  • 이는 호스트를 전반적인 메모리 고갈(OOM)로부터 보호합니다. 최상위 cgroup의 메모리 제한은 호스트의 용량보다 작은 임계값으로 설정할 수 있기 때문입니다. 해당 cgroup 외부의 프로세스는 OOM의 위험이 없습니다.
  • 이는 저장소 풀의 각 개별 cgroup이 모계 cgroup의 제한보다 작은 관대한 상한선(이 예에서 20 GB)까지 갑자기 증가할 수 있게 합니다. 하지만 그 용량은 모계의 제한의 1/N보다 상당히 큽니다. 이 예에서는 최대 3개의 자식 cgroup이 동시에 최대치까지 증가할 수 있습니다. 일반적으로 1000개의 모든 cgroup은 20 GB보다 훨씬 적은 용량을 사용할 것입니다.

백그라운드 저장소 최적화

비어 있는 디렉토리 및 불필요한 구성 설정이 저장소에 누적되어 Git 작업을 느리게 할 수 있습니다. Gitaly는 이러한 항목을 정리하고 성능을 향상시키기 위해 최대 지속 시간으로 매일 백그라운드 작업을 예약할 수 있습니다.

경고: 백그라운드 저장소 최적화는 실험적인 기능이며 실행 중 호스트에 상당한 부하를 줄 수 있습니다. 비수기 시간에 예약하고 지속 시간을 짧게 유지하세요(예: 30-60 분).

다음 중 하나의 방법으로 백그라운드 저장소 최적화를 구성하세요:

Linux 패키지 (Omnibus)

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

gitaly['configuration'] = {
  # ...
  daily_maintenance: {
    # ...
    start_hour: 4,
    start_minute: 30,
    duration: '30m',
    storages: ['default'],
  },
}
소스에서 컴파일한 버전

/home/git/gitaly/config.toml를 편집하고 다음을 추가하세요:

[daily_maintenance]
start_hour = 4
start_minute = 30
duration = '30m'
storages = ["default"]

Gitaly 인증 토큰 회전

운영 환경에서 자격 증명을 회전하는 것은 종종 다운타임을 필요로 하거나, 장애를 일으키거나, 둘 다를 초래합니다.

하지만 서비스 중단 없이 Gitaly 자격 증명을 회전할 수 있습니다. Gitaly 인증 토큰을 회전하는 과정은 다음과 같습니다:

이 절차는 단일 서버에서 GitLab을 실행하는 경우에도 작동합니다. 이 경우 “Gitaly 서버”와 “Gitaly 클라이언트”는 동일한 머신을 의미합니다.

인증 모니터링 확인

Gitaly 인증 토큰을 회전하기 전에, Prometheus를 사용하여 GitLab 설치의 인증 동작을 모니터링 할 수 있는지 확인하세요.

이후에는 나머지 절차를 진행할 수 있습니다.

“auth transitioning” 모드 활성화

Gitaly 서버에서 Gitaly 인증을 일시적으로 비활성화하려면 다음과 같이 “auth transitioning” 모드로 전환합니다:

# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
  # ...
  auth: {
    # ...
    transitioning: true,
  },
}

이 변경을 수행한 후, Prometheus 쿼리가 다음과 같은 값을 반환해야 합니다:

{enforced="false",status="would be ok"}  4424.985419441742

enforced="false"이므로, 새로운 토큰을 배포하는 것이 안전합니다.

Gitaly 인증 토큰 업데이트

새로운 Gitaly 인증 토큰으로 업데이트하려면 각 Gitaly 클라이언트 Gitaly 서버에서 다음을 수행합니다:

  1. 구성 업데이트:

    # in /etc/gitlab/gitlab.rb
    gitaly['configuration'] = {
       # ...
       auth: {
          # ...
          token: '<new secret token>',
       },
    }
    
  2. Gitaly 재시작:

    gitlab-ctl restart gitaly
    

이 변경이 배포되는 동안 Prometheus 쿼리를 실행하면 enforced="false",status="denied" 카운터에 대해 0이 아닌 값을 보게 됩니다.

인증 실패가 없도록 보장

새로운 토큰이 설정되고 관련된 모든 서비스가 재시작된 후, 인증 모니터링 확인에서 다음과 같은 혼합 상태를 잠시 보게 됩니다:

  • status="would be ok".
  • status="denied".

모든 Gitaly 클라이언트와 Gitaly 서버가 새로운 토큰을 수집한 후, 유일한 비제로 비율enforced="false",status="would be ok"이어야 합니다.

“auth transitioning” 모드 비활성화

Gitaly 인증을 다시 활성화하려면 “auth transitioning” 모드를 비활성화합니다. Gitaly 서버의 구성은 다음과 같이 업데이트합니다:

# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
  # ...
  auth: {
    # ...
    transitioning: false,
  },
}

경고:

이 단계를 완료하지 않으면 Gitaly 인증이 없습니다.

인증이 시행되는지 확인

Prometheus 쿼리를 새로 고치세요. 이제 시작할 때와 유사한 결과를 볼 수 있어야 합니다. 예를 들면:

{enforced="true",status="ok"}  4424.985419441742

enforced="true"는 인증이 시행되고 있음을 의미합니다.

Pack-objects 캐시

Tier: Free, Premium, Ultimate Offering: Self-managed

Gitaly는 Git 저장소용 스토리지 서비스를 제공하며, Git fetch 응답의 짧은 롤링 윈도우를 캐시하도록 구성할 수 있습니다. 이는 서버가 많은 CI fetch 트래픽을 받을 때 서버 부하를 줄일 수 있습니다.

pack-objects 캐시는 git pack-objects를 래핑하며, 이는 PostUploadPack과 SSHUploadPack Gitaly RPC를 사용하여 간접적으로 호출되는 Git의 내부 부분입니다. Gitaly는 사용자가 HTTP를 사용하여 Git fetch를 수행할 때 PostUploadPack을 실행하고, 사용자가 SSH를 사용하여 Git fetch를 수행할 때 SSHUploadPack을 실행합니다.

캐시가 활성화되면 PostUploadPack 또는 SSHUploadPack을 사용하는 모든 작업이 이로부터 이점이 있을 수 있습니다. 이는 다음과는 독립적입니다:

  • 전송 방식 (HTTP 또는 SSH).
  • Git 프로토콜 버전 (v0 또는 v2).
  • 전체 복제, 증분 fetch, 얕은 복제 또는 부분 복제와 같은 fetch 유형.

이 캐시의 강점은 동시 동일 fetch를 중복 제거할 수 있는 능력입니다. 이 캐시는:

  • 사용자가 많은 동시 작업이 있는 CI/CD 파이프라인을 실행하는 GitLab 인스턴스에서 이점을 얻을 수 있습니다. 서버 CPU 사용량에서 눈에 띄는 감소가 있어야 합니다.
  • 독특한 fetch에는 전혀 이점이 없습니다. 예를 들어, 저장소를 로컬 컴퓨터에 복제하여 점검하는 경우, 해당 fetch가 아마도 독특할 것이기 때문에 이 캐시로부터 이점을 보지 못할 가능성이 높습니다.

pack-objects 캐시는 로컬 캐시입니다. 이 캐시는:

  • 활성화된 Gitaly 프로세스의 메모리에 메타데이터를 저장합니다.
  • 캐시된 실제 Git 데이터는 로컬 스토리지의 파일에 저장됩니다.

로컬 파일을 사용하는 장점은 운영 체제가 pack-objects 캐시 파일의 일부를 RAM에 자동으로 유지할 수 있어 빠르게 만들 수 있다는 것입니다.

pack-objects 캐시가 디스크 쓰기 IO를 상당히 증가시킬 수 있으므로 기본적으로 비활성화되어 있습니다. GitLab 15.11 이상에서는 쓰기 작업 부하가 약 50% 낮아지지만, 캐시는 여전히 기본적으로 비활성화되어 있습니다.

캐시 구성

pack-objects 캐시에 대해 사용할 수 있는 구성 설정입니다. 각 설정에 대한 자세한 내용은 아래에서 설명합니다.

설정 기본값 설명
enabled false 캐시를 켭니다. 비활성화되면 Gitaly는 각 요청에 대해 전용 git pack-objects 프로세스를 실행합니다.
dir <PATH TO FIRST STORAGE>/+gitaly/PackObjectsCache 캐시 파일이 저장되는 로컬 디렉터리입니다.
max_age 5m (5분) 이보다 오래된 캐시 항목은 퇴출되고 디스크에서 제거됩니다.
min_occurrences 1 캐시 항목이 생성되기 전에 키가 발생해야 하는 최소 횟수입니다.

/etc/gitlab/gitlab.rb에서 다음을 설정하세요:

gitaly['configuration'] = {
  # ...
  pack_objects_cache: {
    # ...
    enabled: true,
    # dir: '/var/opt/gitlab/git-data/repositories/+gitaly/PackObjectsCache',
    # max_age: '5m',
    # min_occurrences: 1,
  },
}

enabled는 기본적으로 false입니다.

캐시는 기본적으로 비활성화되어 있습니다. 이는 경우에 따라 디스크에 쓰여지는 바이트 수가
극도로 증가할 수 있기 때문입니다.
GitLab.com에서는 우리 저장소 스토리지 디스크가 이 추가 작업 부하를 처리할 수 있다는 것을 확인했지만,
어디에서나 이 사실을 가정할 수는 없다고 생각했습니다.

캐시 저장 디렉토리 dir

캐시는 파일을 저장할 디렉토리가 필요합니다. 이 디렉토리는 다음과 같아야 합니다:

  • 충분한 공간이 있는 파일 시스템에 있어야 합니다. 캐시 파일 시스템의 공간이 부족하면 모든
    가져오기가 실패하기 시작합니다.

  • 충분한 IO 대역폭이 있는 디스크에 있어야 합니다. 캐시 디스크의 IO 대역폭이 부족해지면 모든
    가져오기 및 아마도 전체 서버가 느려지게 됩니다.

기본적으로 캐시 저장 디렉토리는 구성 파일에서 정의된 첫 번째 Gitaly 스토리지의
하위 디렉토리로 설정됩니다.

여러 Gitaly 프로세스가 동일한 디렉토리를 캐시 저장 용도로 사용할 수 있습니다. 각 Gitaly 프로세스는
생성하는 캐시 파일 이름의 일부로 고유한 무작위 문자열을 사용합니다. 이 말은:

  • 충돌이 발생하지 않습니다.

  • 다른 프로세스의 파일을 재사용하지 않습니다.

기본 디렉토리는 캐시 파일을 저장소 데이터와 같은 파일 시스템에 놓지만, 이는 필수가 아닙니다.
인프라에 더 잘 맞는 경우 다른 파일 시스템에 캐시 파일을 놓을 수 있습니다.

디스크에서 필요한 IO 대역폭의 양은 다음에 따라 달라집니다:

  • Gitaly 서버의 저장소의 크기와 형태.

  • 사용자가 생성하는 트래픽의 종류.

gitaly_pack_objects_generated_bytes_total 메트릭을 사용하여
최악의 경우를 가정할 수 있으며, 캐시 적중 비율이 0%라고 가정합니다.

필요한 공간의 양은 다음에 따라 달라집니다:

  • 사용자가 캐시에서 가져오는 초당 바이트 수.

  • max_age 캐시 퇴출 창의 크기.

사용자가 100MB/s로 가져오고 5분 창을 사용하는 경우, 평균적으로
5*60*100MB = 30GB의 데이터가 캐시 디렉토리에 있습니다. 이 평균은 예상 평균이며 보장이 아닙니다.
피크 크기는 이 평균을 초과할 수 있습니다.

캐시 퇴출 창 max_age

max_age 구성 설정을 사용하면 캐시 적중의 확률과 캐시 파일에 사용되는 평균 저장 공간을 제어할 수 있습니다.
max_age보다 오래된 항목은 디스크에서 삭제됩니다.

퇴출은 진행 중인 요청에 방해가 되지 않습니다. 느린 연결을 통해 가져오는 데 걸리는 시간보다 max_age가 적어도
괜찮습니다. Unix 파일 시스템은 삭제된 파일을 읽고 있는 모든 프로세스가 파일을 닫을 때까지 진정으로 삭제하지 않기 때문입니다.

최소 키 발생 수 min_occurrences

min_occurrences 설정은 동일한 요청이 새 캐시 항목을 생성하기 전에 얼마나 자주 발생해야 하는지를 제어합니다.
기본값은 1로 설정되어 있으므로 고유 요청은 캐시에 기록되지 않습니다.

다음과 같은 경우:

  • 이 숫자를 늘리면 캐시 적중률이 감소하고 캐시는 디스크 공간을 덜 사용합니다.

  • 이 숫자를 줄이면 캐시 적중률이 증가하고 캐시는 디스크 공간을 더 사용합니다.

min_occurrences1로 설정해야 합니다. GitLab.com에서는
0에서 1로 변경하는 것으로 캐시 디스크 공간을 50% 절약하면서 캐시 적중률에는 거의 영향을 주지 않았습니다.

캐시 관찰

메트릭스를 사용하여 캐시를 관찰할 수 있으며, 다음의 기록된 정보에서도 확인할 수 있습니다. 이러한 로그는 gRPC 로그의 일부이며 호출이 실행될 때 발견될 수 있습니다.

필드 설명
pack_objects_cache.hit 현재 pack-objects 캐시가 적중했는지 여부를 나타냅니다 (true 또는 false)
pack_objects_cache.key pack-objects 캐시에 사용된 캐시 키
pack_objects_cache.generated_bytes 작성 중인 새 캐시의 크기 (바이트 단위)
pack_objects_cache.served_bytes 제공된 캐시의 크기 (바이트 단위)
pack_objects.compression_statistics pack-objects 생성에 대한 통계
pack_objects.enumerate_objects_ms 클라이언트에 의해 전송된 객체를 열거하는 데 소요된 총 시간 (ms 단위)
pack_objects.prepare_pack_ms 클라이언트에 다시 전송하기 전에 packfile을 준비하는 데 소요된 총 시간 (ms 단위)
pack_objects.write_pack_file_ms 클라이언트에 packfile을 다시 전송하는 데 소요된 총 시간 (ms 단위). 클라이언트의 인터넷 연결에 크게 의존합니다.
pack_objects.written_object_count Gitaly가 클라이언트에 다시 전송하는 객체의 총 수

다음과 같은 경우:

  • 캐시 누락 시, Gitaly는 pack_objects_cache.generated_bytespack_objects_cache.served_bytes 메시지를 모두 기록합니다. Gitaly는 pack-object 생성에 대한 좀 더 자세한 통계도 기록합니다.
  • 캐시 적중 시, Gitaly는 pack_objects_cache.served_bytes 메시지만 기록합니다.

예:

{
  "bytes":26186490,
  "correlation_id":"01F1MY8JXC3FZN14JBG1H42G9F",
  "grpc.meta.deadline_type":"none",
  "grpc.method":"PackObjectsHook",
  "grpc.request.fullMethod":"/gitaly.HookService/PackObjectsHook",
  "grpc.request.glProjectPath":"root/gitlab-workhorse",
  "grpc.request.glRepository":"project-2",
  "grpc.request.repoPath":"@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git",
  "grpc.request.repoStorage":"default",
  "grpc.request.topLevelGroup":"@hashed",
  "grpc.service":"gitaly.HookService",
  "grpc.start_time":"2021-03-25T14:57:52.747Z",
  "level":"info",
  "msg":"finished unary call with code OK",
  "peer.address":"@",
  "pid":20961,
  "span.kind":"server",
  "system":"grpc",
  "time":"2021-03-25T14:57:53.543Z",
  "pack_objects.compression_statistics": "총 145991 (델타 68), 재사용 6 (델타 2), pack-reused 145911",
  "pack_objects.enumerate_objects_ms": 170,
  "pack_objects.prepare_pack_ms": 7,
  "pack_objects.write_pack_file_ms": 786,
  "pack_objects.written_object_count": 145991,
  "pack_objects_cache.generated_bytes": 49533030,
  "pack_objects_cache.hit": "false",
  "pack_objects_cache.key": "123456789",
  "pack_objects_cache.served_bytes": 49533030,
  "peer.address": "127.0.0.1",
  "pid": 8813,
}

cat-file 캐시

많은 Gitaly RPC는 저장소에서 Git 객체를 조회해야 합니다.

대부분의 경우 우리는 이를 위해 git cat-file --batch 프로세스를 사용합니다.

더 나은 성능을 위해 Gitaly는 이러한 git cat-file 프로세스를 RPC 호출 간에 재사용할 수 있습니다.

이전에 사용된 프로세스는 “Git cat-file 캐시”로 보관됩니다.

이것이 사용하는 시스템 리소스의 양을 제어하기 위해, 우리는 캐시에 들어갈 수 있는 최대 cat-file 프로세스 수를 설정합니다.

기본 한도는 100 cat-file로, 이는 git cat-file --batchgit cat-file --batch-check 프로세스 쌍을 구성합니다.

“너무 많은 열린 파일”에 대한 오류나 새 프로세스 생성 불능이 발생하는 경우 이 한도를 낮추는 것이 좋습니다.

이상적으로, 숫자는 표준 트래픽을 처리할 수 있을 만큼 충분히 커야 합니다.

한도를 높이는 경우, 그 전후의 캐시 적중률을 측정해야 합니다.

적중률이 개선되지 않으면, 더 높은 한도는 의미 있는 차이를 만들지 않을 가능성이 높습니다.

다음은 적중률을 확인하기 위한 Prometheus 쿼리의 예입니다:

sum(rate(gitaly_catfile_cache_total{type="hit"}[5m])) / sum(rate(gitaly_catfile_cache_total{type=~"(hit)|(miss)"}[5m]))

Gitaly 구성 파일에서 cat-file 캐시를 구성하세요.

GitLab UI 커밋에 대한 커밋 서명 구성하기

  • GitLab 15.4에서 도입됨.
  • 서명된 GitLab UI 커밋에 대한 Verified 배지를 표시하는 기능은 GitLab 16.3에서 도입됨으로, 이름이 gitaly_gpg_signing인 플래그가 활성화되어 있습니다. 기본적으로 비활성화되어 있습니다.
  • rotated_signing_keys 옵션에 지정된 여러 키를 사용하여 서명을 검증하는 기능은 GitLab 16.3에서 도입됨.
  • GitLab 17.0에서 GitLab Dedicated와 자체 관리형에 대해 기본적으로 활성화됨.
자체 관리형 GitLab에서는 기본적으로 이 기능이 사용 가능합니다.

기능을 숨기려면 관리자가 gitaly_gpg_signing이라는 이름의 기능 플래그를 비활성화할 수 있습니다.

GitLab.com에서는 이 기능을 사용할 수 없습니다. GitLab Dedicated에서는 이 기능을 사용할 수 있습니다.

기본적으로 Gitaly는 GitLab UI를 사용하여 생성된 커밋에 대해 서명을 하지 않습니다. 예를 들어, 다음을 사용하여 생성된 커밋:

  • 웹 편집기.
  • 웹 IDE.
  • 병합 요청.

Gitaly를 구성하여 GitLab UI로 만든 커밋에 서명하도록 설정할 수 있습니다.

기본적으로 Gitaly는 커밋의 저자를 커밋터로 설정합니다.

이 경우, 커밋의 서명이 저자나 커밋터의 소속이 아니기 때문에 로컬에서 커밋 검증하기가 더 어렵습니다.

Gitaly를 구성하여 커밋이 인스턴스에서 생성되었음을 반영하려면 committer_emailcommitter_name을 설정하세요.

예를 들어, GitLab.com에서는 이 구성 옵션이 noreply@gitlab.comGitLab으로 설정됩니다.

rotated_signing_keys는 검증에만 사용할 키 목록입니다.

Gitaly는 구성된 signing_key를 사용하여 웹 커밋을 검증하려고 시도한 다음, 성공할 때까지 하나씩 순회하는 회전된 키를 사용합니다.

서명 키가 회전되었거나 여러 키를 지정하여 다른 인스턴스에서 프로젝트를 이전하고 웹 커밋을 Verified로 표시하려는 경우 rotated_signing_keys 옵션을 설정하세요.

GitLab UI에서 생성된 커밋에 서명하기 위해 Gital이를 다음 두 가지 방법 중 하나로 구성하세요:

리눅스 패키지 (Omnibus)
  1. GPG 키 생성하기 및 내보내거나 SSH 키 생성하기. 최적의 성능을 위해 EdDSA 키를 사용하세요.

    GPG 키 내보내기:

    gpg --export-secret-keys <ID> > signing_key.gpg
    

    또는 SSH 키 생성하기(비밀번호 없음):

    ssh-keygen -t ed25519 -f signing_key.ssh
    
  2. Gitaly 노드에서 키를 /etc/gitlab/gitaly/로 복사합니다.
  3. /etc/gitlab/gitlab.rb를 편집하고 gitaly['git']['signing_key']를 구성합니다:

    gitaly['configuration'] = {
       # ...
       git: {
         # ...
         committer_name: 'Your Instance',
         committer_email: 'noreply@yourinstance.com',
         signing_key: '/etc/gitlab/gitaly/signing_key.gpg',
         rotated_signing_keys: ['/etc/gitlab/gitaly/previous_signing_key.gpg'],
         # ...
       },
    }
    
  4. 파일을 저장하고 GitLab 구성 재설정하기.
소스에서 컴파일한 경우
  1. GPG 키 생성하기 및 내보내거나 SSH 키 생성하기. 최적의 성능을 위해 EdDSA 키를 사용하세요.

    GPG 키 내보내기:

    gpg --export-secret-keys <ID> > signing_key.gpg
    

    또는 SSH 키 생성하기(비밀번호 없음):

    ssh-keygen -t ed25519 -f signing_key.ssh
    
  2. Gitaly 노드에서 키를 /etc/gitlab로 복사합니다.
  3. /home/git/gitaly/config.toml을 편집하고 signing_key를 구성합니다:

    [git]
    committer_name = "Your Instance"
    committer_email = "noreply@yourinstance.com"
    signing_key = "/etc/gitlab/gitaly/signing_key.gpg"
    rotated_signing_keys = ["/etc/gitlab/gitaly/previous_signing_key.gpg"]
    
  4. 파일을 저장하고 GitLab 재시작하기.

외부 명령어를 사용하여 구성 생성

외부 명령어를 사용하여 Gitaly 구성의 일부를 생성할 수 있습니다. 이렇게 할 수 있는 이유는 다음과 같습니다:

  • 전체 구성을 각 노드에 배포하지 않고 노드를 구성하기 위해.
  • 노드의 설정을 자동 발견하여 구성하기 위해. 예를 들어, DNS 항목을 사용하여.
  • 노드의 시작 시 비밀을 구성하여 평문으로 보이지 않게 하려는 경우.

외부 명령어를 사용하여 구성을 생성하려면, Gitaly 노드의 원하는 구성을 JSON 형식으로 표준 출력에 덤프하는 스크립트를 제공해야 합니다.

예를 들어, 다음 명령은 AWS 비밀을 사용하여 GitLab 내부 API에 연결하는 데 사용되는 HTTP 비밀번호를 구성합니다:

#!/usr/bin/env ruby
require 'json'
JSON.generate({"gitlab": {"http_settings": {"password": `aws get-secret-value --secret-id ...`}}})

그런 다음 두 가지 방법 중 하나로 Gitaly에 스크립트 경로를 알려야 합니다:

리눅스 패키지 (Omnibus)

/etc/gitlab/gitlab.rb를 편집하고 config_command를 구성합니다:

gitaly['configuration'] = {
    config_command: '/path/to/config_command',
}
직접 컴파일 (소스)

/home/git/gitaly/config.toml을 편집하고 config_command를 구성합니다:

config_command = "/path/to/config_command"

구성이 완료된 후 Gitaly는 시작 시 명령을 실행하고 그 표준 출력을 JSON으로 구문 분석합니다. 결과 구성은 다른 Gitaly 구성에 다시 병합됩니다.

Gitaly는 다음 중 하나가 실패하면 시작하지 않습니다:

  • 구성 명령이 실패한 경우.
  • 명령으로 생성된 출력이 유효한 JSON으로 구문 분석할 수 없는 경우.

서버 측 백업 구성

  • GitLab 16.3에 도입됨 소개됨.
  • 최신 백업 대신 지정된 백업을 복원하는 서버 측 지원 도입됨 GitLab 16.6에서.
  • 증분 백업 생성을 위한 서버 측 지원 도입됨 GitLab 16.6에서.
  • GitLab 17.0에서 Helm 차트 설치에 서버 측 지원 추가.

저장소 백업은 각 저장소를 호스팅하는 Gitaly 노드가 백업을 생성하고 객체 저장소로 스트리밍하는 책임을 지도록 구성할 수 있습니다. 이는 백업을 생성하고 복원하는 데 필요한 네트워크 자원을 줄이는 데 도움이 됩니다.

각 Gitaly 노드는 백업을 위해 객체 저장소에 연결하도록 구성해야 합니다.

서버 측 백업 구성을 완료한 후, 서버 측 저장소 백업 생성을 할 수 있습니다.

Azure Blob 저장소 구성

Azure Blob 저장소를 백업을 위해 구성하는 방법은 설치 유형에 따라 다릅니다. 직접 컴파일된 설치의 경우, GitLab 외부에서 AZURE_STORAGE_ACCOUNTAZURE_STORAGE_KEY 환경 변수를 설정해야 합니다.

리눅스 패키지 (Omnibus)

/etc/gitlab/gitlab.rb를 편집하고 go_cloud_url을 구성합니다:

gitaly['env'] = {
    'AZURE_STORAGE_ACCOUNT' => 'azure_storage_account',
    'AZURE_STORAGE_KEY' => 'azure_storage_key' # 또는 'AZURE_STORAGE_SAS_TOKEN'
}
gitaly['configuration'] = {
    backup: {
        go_cloud_url: 'azblob://<bucket>'
    }
}
Helm 차트 (Kubernetes)

Helm 기반 배포에 대해서는 Gitaly 차트의 서버 측 백업 문서를 참조하세요.

직접 컴파일 (소스)

/home/git/gitaly/config.toml을 편집하고 go_cloud_url을 구성합니다:

[backup]
go_cloud_url = "azblob://<bucket>"

Google Cloud 스토리지 구성

Google Cloud 스토리지(GCP)는 애플리케이션 기본 자격 증명을 사용하여 인증합니다. 각 Gitaly 서버에서 다음 방법 중 하나를 사용하여 애플리케이션 기본 자격 증명을 설정하세요:

  • gcloud auth application-default login 명령어.
  • GOOGLE_APPLICATION_CREDENTIALS 환경 변수. 소스에서 컴파일된 설치의 경우, GitLab 외부에서 환경 변수를 설정하세요.

자세한 내용은 Application Default Credentials를 참조하세요.

대상 버킷은 go_cloud_url 옵션을 사용하여 구성됩니다.

리눅스 패키지 (Omnibus)

/etc/gitlab/gitlab.rb를 편집하고 go_cloud_url을 구성하세요:

gitaly['env'] = {
    'GOOGLE_APPLICATION_CREDENTIALS' => '/path/to/service.json'
}
gitaly['configuration'] = {
    backup: {
        go_cloud_url: 'gs://<bucket>'
    }
}
헬름 차트 (Kubernetes)

헬름 기반 배포의 경우, Gitaly 차트의 서버 측 백업 문서를 참조하세요.

소스에서 직접 컴파일

/home/git/gitaly/config.toml을 편집하고 go_cloud_url을 구성하세요:

[backup]
go_cloud_url = "gs://<bucket>"

S3 스토리지 구성

S3 스토리지 인증을 구성하려면:

  • AWS CLI로 인증하는 경우, 기본 AWS 세션을 사용할 수 있습니다.
  • 그렇지 않은 경우, AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 환경 변수를 사용하세요. 소스에서 컴파일된 설치의 경우, GitLab 외부에서 환경 변수를 설정하세요.

자세한 내용은 AWS Session 문서를 참조하세요.

대상 버킷과 리전은 go_cloud_url 옵션을 사용하여 구성됩니다.

리눅스 패키지 (Omnibus)

/etc/gitlab/gitlab.rb를 편집하고 go_cloud_url을 구성하세요:

gitaly['env'] = {
    'AWS_ACCESS_KEY_ID' => 'aws_access_key_id',
    'AWS_SECRET_ACCESS_KEY' => 'aws_secret_access_key'
}
gitaly['configuration'] = {
    backup: {
        go_cloud_url: 's3://<bucket>?region=us-west-1'
    }
}
헬름 차트 (Kubernetes)

헬름 기반 배포의 경우, Gitaly 차트의 서버 측 백업 문서를 참조하세요.

소스에서 직접 컴파일

/home/git/gitaly/config.toml을 편집하고 go_cloud_url을 구성하세요:

[backup]
go_cloud_url = "s3://<bucket>?region=us-west-1"

S3 호환 서버 구성

MinIO와 같은 S3 호환 서버는 endpoint 매개 변수를 추가하여 S3와 유사하게 구성됩니다.

지원되는 매개 변수는 다음과 같습니다:

  • region: AWS 리전.
  • endpoint: 엔드포인트 URL.
  • disabledSSL: true 값을 설정하면 SSL이 비활성화됩니다.
  • s3ForcePathStyle: true 값을 설정하면 경로 스타일 주소 지정이 강제됩니다.
헬름 차트 (Kubernetes)

헬름 기반 배포의 경우, Gitaly 차트의 서버 측 백업 문서를 참조하세요.

리눅스 패키지 (Omnibus)

/etc/gitlab/gitlab.rb를 편집하고 go_cloud_url을 구성하세요:

gitaly['env'] = {
    'AWS_ACCESS_KEY_ID' => 'minio_access_key_id',
    'AWS_SECRET_ACCESS_KEY' => 'minio_secret_access_key'
}
gitaly['configuration'] = {
    backup: {
        go_cloud_url: 's3://<bucket>?region=minio&endpoint=my.minio.local:8080&disableSSL=true&s3ForcePathStyle=true'
    }
}
소스에서 직접 컴파일

/home/git/gitaly/config.toml을 편집하고 go_cloud_url을 구성하세요:

[backup]
go_cloud_url = "s3://<bucket>?region=minio&endpoint=my.minio.local:8080&disableSSL=true&s3ForcePathStyle=true"