Gitaly 구성
GitLab v19.5Offering: GitLab Self-Managed
요약
Gitaly는 다음 두 가지 방법 중 하나로 구성합니다. 다음 구성 옵션도 사용할 수 있습니다. Gitaly 문서 전반에서 언급하는 토큰은 관리자가 임의로 정하는 비밀번호일 뿐입니다. 기본적으로 Gitaly는 Gitaly 클라이언트와 같은 서버에서 실행되며, 앞서 설명한 대로 구성됩니다.
Gitaly는 다음 두 가지 방법 중 하나로 구성합니다.
/etc/gitlab/gitlab.rb를 편집하여 Gitaly 설정을 추가하거나 변경합니다. Gitaly 구성 파일 예제를 참고합니다. 예제 파일의 설정은 Ruby로 변환해야 합니다.- 파일을 저장하고 GitLab을 재구성합니다.
- Gitaly 차트를 구성합니다.
- Helm 릴리스를 업그레이드합니다.
/home/git/gitaly/config.toml을 편집하여 Gitaly 설정을 추가하거나 변경합니다. Gitaly 구성 파일 예제를 참고합니다.- 파일을 저장하고 GitLab을 재시작합니다.
다음 구성 옵션도 사용할 수 있습니다.
- TLS 지원 활성화
- RPC 동시성 제한
- pack-objects 동시성 제한
Gitaly 토큰 정보#
Gitaly 문서 전반에서 언급하는 토큰은 관리자가 임의로 정하는 비밀번호일 뿐입니다. GitLab API 또는 이와 유사한 웹 API 토큰용으로 생성한 토큰과는 관련이 없습니다.
Gitaly를 별도 서버에서 실행#
기본적으로 Gitaly는 Gitaly 클라이언트와 같은 서버에서 실행되며, 앞서 설명한 대로 구성됩니다. 단일 서버 설치에는 다음에서 사용하는 이 기본 구성이 가장 적합합니다.
다만 Gitaly를 별도 서버에 배포할 수도 있으며, 여러 머신에 걸친 GitLab 설치에서 이점이 될 수 있습니다.
Gitaly를 별도 서버에서 실행하도록 구성한 경우, Gitaly 서버를 클러스터의 Gitaly 클라이언트보다 먼저 업그레이드해야 합니다.
Gitaly를 별도 서버에 설정하는 과정은 다음과 같습니다.
디스크 요구 사항은 Gitaly 노드에도 적용됩니다.
네트워크 아키텍처#
다음 목록은 Gitaly의 네트워크 아키텍처를 설명합니다.
- GitLab Rails는 리포지터리를 리포지터리 스토리지로 샤딩합니다.
/config/gitlab.yml에는 스토리지 이름에서(Gitaly address, Gitaly token)쌍으로 가는 매핑이 들어 있습니다./config/gitlab.yml의storage name->(Gitaly address, Gitaly token)매핑은 Gitaly 네트워크 토폴로지의 단일 진실 공급원(Single Source Of Truth, SSOT)입니다.(Gitaly address, Gitaly token)쌍 하나는 Gitaly 서버 하나에 해당합니다.- Gitaly 서버 하나는 스토리지를 하나 이상 호스팅합니다.
- Gitaly 클라이언트는 Gitaly 서버를 하나 이상 사용할 수 있습니다.
- Gitaly 주소는 모든 Gitaly 클라이언트에서 올바르게 확인되도록 지정해야 합니다.
- Gitaly 클라이언트는 다음과 같습니다.
- Puma
- Sidekiq
- GitLab Workhorse
- GitLab Shell
- Elasticsearch indexer
- Gitaly 자체
- Gitaly 서버는
/config/gitlab.yml에 지정된 자신의(Gitaly address, Gitaly token)쌍을 사용해 스스로에게 RPC 호출을 보낼 수 있어야 합니다. - 인증은 Gitaly 노드와 GitLab Rails 노드가 공유하는 고정 토큰으로 수행합니다. nodes.
다음 다이어그램은 Gitaly 서버와 GitLab Rails 간의 통신을 나타내며, HTTP와 HTTPS 통신의 기본 포트를 보여 줍니다.

Gitaly 네트워크 트래픽은 기본적으로 암호화되지 않으므로 Gitaly 서버를 공용 인터넷에 노출해서는 안 됩니다. Gitaly 서버에 대한 접근을 제한하려면 방화벽을 사용하는 것을 강력히 권장합니다. 다른 방법으로 TLS를 사용할 수도 있습니다.
다음 절에서는 비밀 토큰 abc123secret을 사용하는
Gitaly 서버 두 대를 구성하는 방법을 설명합니다.
gitaly1.internalgitaly2.internal
GitLab 설치에는 리포지터리 스토리지가 세 개 있다고 가정합니다.
defaultstorage1storage2
원한다면 리포지터리 스토리지 하나를 가진 서버 한 대만 사용할 수도 있습니다.
Gitaly 설치#
Gitaly 서버마다 다음 중 하나의 방법으로 Gitaly를 설치합니다.
- Linux 패키지 설치: 원하는 Linux 패키지를 다운로드하여 설치하되,
EXTERNAL_URL=값은 지정하지 않습니다. - 자체 컴파일 설치: Gitaly 설치의 단계를 따릅니다.
Gitaly 서버 구성#
Gitaly 서버를 구성하려면 다음을 수행해야 합니다.
- 인증 구성
- 스토리지 경로 구성
- 네트워크 리스너 활성화
git 사용자는 구성된 스토리지 경로에 대해 읽기, 쓰기, 권한 설정을 할 수 있어야 합니다.
Gitaly 토큰을 교체하는 동안 가동 중지 시간을 피하려면 gitaly['auth_transitioning'] 설정을 사용해 인증을 일시적으로 비활성화할 수 있습니다. 자세한 내용은
인증 전환 모드 활성화를 참고합니다.
인증 구성#
히스토리
token_file지원이 GitLab 18.11에서 도입되었습니다.
Gitaly와 GitLab은 인증에 두 개의 공유 시크릿을 사용합니다.
- Gitaly 토큰: Gitaly에 대한 gRPC 요청을 인증하는 데 사용합니다. Gitaly 토큰은 GitLab 구성에 직접 지정하거나
토큰 파일에 지정할 수 있습니다. 토큰 파일을 사용하면 시작 시점에 시크릿이 구성에 렌더링되지 않으므로 더 안전하고
컨테이너 환경에 더 적합합니다. 토큰 파일은 다음 조건을 충족해야 합니다.
- 토큰 문자열만 포함해야 합니다. 공백은 자동으로 제거됩니다.
- 파일 권한이
0600또는0400이어야 합니다.
- GitLab Shell 토큰: GitLab Shell에서 GitLab 내부 API로 보내는 인증 콜백에 사용합니다.
-
_Gitaly 토큰_을 구성하려면
/etc/gitlab/gitlab.rb를 편집합니다.-
토큰 파일을 사용하는 경우:
gitaly['configuration'] = { # ... auth: { # ... token_file: '/etc/gitlab/gitaly_token', }, } -
토큰을 직접 지정하는 경우:
gitaly['configuration'] = { # ... auth: { # ... token: 'abc123secret', }, }
token과token_file은 동시에 사용할 수 없습니다. -
-
_GitLab Shell 토큰_은 다음 두 가지 방법 중 하나로 구성합니다.
-
방법 1(권장): Gitaly 클라이언트의
/etc/gitlab/gitlab-secrets.json을 Gitaly 서버와 다른 모든 Gitaly 클라이언트의 같은 경로로 복사합니다. -
방법 2:
-
GitLab Rails를 실행하는 모든 노드에서
/etc/gitlab/gitlab.rb를 편집합니다. -
GITLAB_SHELL_SECRET_TOKEN을 실제 시크릿으로 바꿉니다.-
GitLab 17.5 이상:
gitaly['gitlab_secret'] = 'GITLAB_SHELL_SECRET_TOKEN' -
GitLab 17.4 이하:
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
-
-
Gitaly를 실행하는 모든 노드에서
/etc/gitlab/gitlab.rb를 편집합니다. -
GITLAB_SHELL_SECRET_TOKEN을 실제 시크릿으로 바꿉니다.-
GitLab 17.5 이상:
gitaly['gitlab_secret'] = 'GITLAB_SHELL_SECRET_TOKEN' -
GitLab 17.4 이하:
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
-
-
변경 후 GitLab을 재구성합니다.
sudo gitlab-ctl reconfigure -
-
-
Gitaly 클라이언트의
/home/git/gitlab/.gitlab_shell_secret을 Gitaly 서버(및 다른 모든 Gitaly 클라이언트)의 같은 경로로 복사합니다. -
Gitaly 클라이언트에서
/home/git/gitlab/config/gitlab.yml을 편집합니다.gitlab: gitaly: token: 'abc123secret' -
파일을 저장하고 GitLab을 재시작합니다.
-
Gitaly 서버에서
/home/git/gitaly/config.toml을 편집합니다.-
토큰 파일을 사용하는 경우:
[auth] token_file = '/etc/gitaly/token' -
토큰을 직접 지정하는 경우:
[auth] token = 'abc123secret'
token과token_file은 동시에 사용할 수 없습니다. -
-
파일을 저장하고 GitLab을 재시작합니다.
Gitaly 서버 구성#
Gitaly 서버를 구성합니다.
Gitaly에는 클라이언트(예: Rails 또는 Sidekiq)가 제공한 주소를 사용해 자기 자신에게 네트워크 호출을 보내는 RPC가 일부 있습니다.
네트워크 구성 때문에 Gitaly가 이 방식으로 자기 자신에 접근할 수 없는 경우(예: Gitaly가 헤어피닝 연결을 지원하지 않는 로드 밸런서 뒤에 있는 경우)
- Gitaly 서버의
/etc/hosts파일을 편집합니다. - 클라이언트가 사용하는 Gitaly 주소를 Gitaly 서버 자신의 IP 주소로 리다이렉트하는 항목을 추가합니다. 예를 들어
127.0.0.1 gitaly.example.com또는<local-ip> gitaly.example.com을 추가합니다.
-
/etc/gitlab/gitlab.rb를 편집합니다.# Avoid running unnecessary services on the Gitaly server 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 # If you run a separate monitoring node you can disable these services prometheus['enable'] = false alertmanager['enable'] = false # If you don't run a separate monitoring node you can # enable Prometheus access & disable these extra services. # This makes Prometheus listen on all interfaces. You must use firewalls to restrict access to this address/port. # prometheus['listen_address'] = '0.0.0.0:9090' # prometheus['monitor_kubernetes'] = false # If you don't want to run monitoring services uncomment the following (not recommended) # node_exporter['enable'] = false # Prevent database connections during 'gitlab-ctl reconfigure' 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. # Don't forget to copy `/etc/gitlab/gitlab-secrets.json` from Gitaly client to Gitaly server. gitlab_rails['internal_api_url'] = 'https://gitlab.example.com' 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', auth: { # ... # # Authentication token to ensure only authorized servers can communicate with # Gitaly server token: 'AUTH_TOKEN', }, } -
각 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', }, ], } -
파일을 저장하고 GitLab을 재구성합니다.
-
Gitaly가 GitLab 내부 API로 콜백을 수행할 수 있는지 확인합니다.
sudo -u git -- /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
-
/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' -
각 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' -
/home/git/gitlab-shell/config.yml을 편집합니다.gitlab_url: https://gitlab.example.com -
파일을 저장하고 GitLab을 재시작합니다.
-
Gitaly가 GitLab 내부 API로 콜백을 수행할 수 있는지 확인합니다.
sudo -u git -- /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
GitLab 서버에서 Gitaly로 리포지터리 데이터를 직접 복사하는 경우, 메타데이터 파일인
기본 경로 /var/opt/gitlab/git-data/repositories/.gitaly-metadata가 전송에 포함되지 않도록 합니다.
이 파일을 복사하면 GitLab이 Gitaly 서버에 호스팅된 리포지터리에 직접 디스크 접근을 사용하게 되어
Error creating pipeline, Commit not found 오류나 오래된 데이터가 발생합니다.
Gitaly 클라이언트 구성#
마지막 단계로, Gitaly 클라이언트가 로컬 Gitaly 서비스 대신 방금 구성한 Gitaly 서버를 사용하도록 업데이트해야 합니다.
GitLab에는 default 리포지터리 스토리지가 구성되어 있어야 합니다.
이 제한 사항에 대해 더 알아봅니다.
이 작업에는 위험이 따를 수 있습니다. Gitaly 클라이언트가 Gitaly 서버에 접근하지 못하게 하는 문제가 있으면 모든 Gitaly 요청이 실패하기 때문입니다. 예를 들어 네트워크, 방화벽, 이름 확인 관련 문제가 이에 해당합니다.
Gitaly는 다음을 가정합니다.
gitaly1.internalGitaly 서버는 Gitaly 클라이언트에서gitaly1.internal:8075로 접근할 수 있으며, 해당 Gitaly 서버는/var/opt/gitlab/git-data와/mnt/gitlab/git-data에 대해 읽기, 쓰기, 권한 설정을 할 수 있습니다.gitaly2.internalGitaly 서버는 Gitaly 클라이언트에서gitaly2.internal:8075로 접근할 수 있으며, 해당 Gitaly 서버는/srv/gitlab/git-data에 대해 읽기, 쓰기, 권한 설정을 할 수 있습니다.gitaly1.internal과gitaly2.internalGitaly 서버는 서로 접근할 수 있습니다.
혼합 구성을 사용하지 않는 한, 일부는 로컬 Gitaly 서버
(gitaly_address 없음)로, 일부는 원격
서버(gitaly_address 있음)로 Gitaly 서버를 정의할 수
없습니다.
Gitaly 클라이언트는 다음 두 가지 방법 중 하나로 구성합니다. 다음 안내는 암호화되지 않은 연결을 기준으로 하지만 TLS 지원을 활성화할 수도 있습니다.
-
/etc/gitlab/gitlab.rb를 편집합니다.# Use the same token value configured on all Gitaly servers gitlab_rails['gitaly_token'] = '' 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' }, }각 Gitaly 서버가 서로 다른 인증 토큰을 사용하도록 구성된 경우에는 다음과 같이 합니다.
gitlab_rails['repositories_storages'] = { 'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075', 'gitaly_token' => '' }, 'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075', 'gitaly_token' => '' }, 'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075', 'gitaly_token' => '' }, } -
파일을 저장하고 GitLab을 재구성합니다.
-
Gitaly 클라이언트(예: Rails 애플리케이션)에서
sudo gitlab-rake gitlab:gitaly:check를 실행하여 Gitaly 서버에 연결할 수 있는지 확인합니다. -
로그를 tail하여 요청을 확인합니다.
sudo gitlab-ctl tail gitaly
-
/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 -
파일을 저장하고 GitLab을 재시작합니다.
-
sudo -u git -H bundle exec rake gitlab:gitaly:check RAILS_ENV=production을 실행하여 Gitaly 클라이언트가 Gitaly 서버에 연결할 수 있는지 확인합니다. -
로그를 tail하여 요청을 확인합니다.
tail -f /home/git/gitlab/log/gitaly.log
Gitaly 서버에서 Gitaly 로그를 tail하면 들어오는 요청을 확인할 수 있습니다. Gitaly 요청을 확실하게 발생시키는 방법 하나는 HTTP 또는 HTTPS로 GitLab에서 리포지터리를 클론하는 것입니다.
리포지터리별 또는 전역으로 서버 훅을 구성했다면 이를 Gitaly 서버로 옮겨야 합니다. Gitaly 서버가 여러 대인 경우 모든 Gitaly 서버에 서버 훅을 복사합니다.
혼합 구성#
GitLab은 여러 Gitaly 서버 중 하나와 같은 서버에 있을 수 있지만, 로컬 구성과 원격 구성을 섞는 구성은 지원하지 않습니다. 다음 설정은 잘못된 예이며, 그 이유는 다음과 같습니다.
- 모든 주소는 다른 Gitaly 서버에서 접근할 수 있어야 합니다.
storage1에gitaly_address로 Unix 소켓이 할당되어 있는데, 이는 일부 Gitaly 서버에서 유효하지 않습니다.
gitlab_rails['repositories_storages'] = {
'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
'storage1' => { 'gitaly_address' => 'unix:/var/opt/gitlab/gitaly/gitaly.socket' },
'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
}
로컬 Gitaly 서버와 원격 Gitaly 서버를 함께 사용하려면 로컬 Gitaly 서버에 외부 주소를 사용합니다. 예를 들면 다음과 같습니다.
gitlab_rails['repositories_storages'] = {
'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
# Address of the GitLab server that also has Gitaly running on it
'storage1' => { 'gitaly_address' => 'tcp://gitlab.internal:8075' },
'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
}
gitaly['configuration'] = {
# ...
#
# Make Gitaly accept connections on all network interfaces
listen_addr: '0.0.0.0:8075',
# Or for 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에는 default라는 스토리지가 필요하므로,
GitLab 애플리케이션 서버를 다시 구성해 default 스토리지를 제거할 수 없습니다.
이 제한 사항에 대해 더 알아봅니다.
이 제한을 우회하려면 다음과 같이 합니다.
- 새 Gitaly 서비스에 스토리지 위치를 추가로 정의하고, 이 추가 스토리지를
default로 구성합니다. 스토리지 위치에는 Gitaly 서비스가 실행 중이며 사용 가능해야 합니다. 그래야 정상 동작하는 스토리지를 전제로 하는 데이터베이스 마이그레이션에서 문제가 생기지 않습니다. - Admin area에서
default의 가중치를 0으로 설정하여 그곳에 리포지터리가 저장되지 않도록 합니다.
필요하지 않은 곳에서 Gitaly 비활성화(선택 사항)#
Gitaly를 원격 서비스로 실행한다면, 기본적으로 GitLab 서버에서 실행되는 로컬 Gitaly 서비스를 비활성화하고 필요한 곳에서만 실행하는 것을 고려합니다.
GitLab 인스턴스에서 Gitaly를 비활성화하는 것은 Gitaly가 GitLab 인스턴스와 별도의 머신에서 실행되는 사용자 지정 클러스터 구성으로 GitLab을 실행할 때에만 의미가 있습니다. 클러스터의 모든 머신에서 Gitaly를 비활성화하는 구성은 올바르지 않습니다(일부 머신은 Gitaly 서버 역할을 해야 합니다).
GitLab 서버에서 Gitaly를 비활성화하려면 다음 두 가지 방법 중 하나를 사용합니다.
-
/etc/gitlab/gitlab.rb를 편집합니다.gitaly['enable'] = false -
파일을 저장하고 GitLab을 재구성합니다.
-
/etc/default/gitlab을 편집합니다.gitaly_enabled=false -
파일을 저장하고 GitLab을 재시작합니다.
Gitaly 수신 인터페이스 변경#
Gitaly가 수신 대기하는 인터페이스를 변경할 수 있습니다. Gitaly와 통신해야 하는 외부 서비스가 있을 때 수신 인터페이스를 변경할 수 있습니다. 예를 들어 Zoekt를 사용하는 정확한 코드 검색이 활성화되어 있지만 실제 서비스는 다른 서버에서 실행되는 경우입니다.
gitaly_token은 Gitaly 서비스 인증에 사용되므로 비밀 문자열이어야 합니다.
이 비밀 값은 openssl rand -base64 24로 무작위 32자 문자열을 생성하여 만들 수 있습니다.
Gitaly 수신 인터페이스를 0.0.0.0:8075로 변경하는 예는 다음과 같습니다.
# /etc/gitlab/gitlab.rb
# Add a shared token for Gitaly authentication
gitlab_shell['secret_token'] = 'your_secure_token_here'
gitlab_rails['gitaly_token'] = 'your_secure_token_here'
# Gitaly configuration
gitaly['gitlab_secret'] = 'your_secure_token_here'
gitaly['configuration'] = {
listen_addr: '0.0.0.0:8075',
auth: {
token: 'your_secure_token_here',
},
storage: [
{
name: 'default',
path: '/var/opt/gitlab/git-data/repositories',
},
]
}
# Tell Rails where to find Gitaly
gitlab_rails['repositories_storages'] = {
'default' => { 'gitaly_address' => 'tcp://ip_address_here:8075' },
}
# Internal API URL (important for multi-server setups)
gitlab_rails['internal_api_url'] = 'http://ip_address_here'
제어 그룹#
제어 그룹에 대한 자세한 내용은 Cgroups를 참고합니다.
백그라운드 리포지터리 최적화#
Git 리포지터리의 오브젝트 데이터베이스에 데이터가 저장되는 방식은 시간이 지나면서 비효율적이 될 수 있으며, 이로 인해 Git 작업이 느려집니다. Gitaly가 최대 실행 시간을 지정한 일일 백그라운드 작업으로 이러한 항목을 정리하고 성능을 개선하도록 예약할 수 있습니다.
백그라운드 리포지터리 최적화는 실행되는 동안 호스트에 상당한 부하를 줄 수 있습니다. 사용량이 적은 시간대에 예약하고 실행 시간을 짧게(예: 30~60분) 유지합니다.
백그라운드 리포지터리 최적화는 다음 두 가지 방법 중 하나로 구성합니다.
/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 설치의 인증 동작을 모니터링할 수 있는지 확인합니다.
그런 다음 나머지 절차를 계속 진행할 수 있습니다.
인증 전환 모드 활성화#
다음과 같이 Gitaly 서버를 인증 전환 모드로 전환하여 Gitaly 서버에서 Gitaly 인증을 일시적으로 비활성화합니다.
# 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 서버에서 다음을 수행합니다.
-
구성을 업데이트합니다.
# in /etc/gitlab/gitlab.rb gitaly['configuration'] = { # ... auth: { # ... token: '<new secret token>', }, }token_file을 사용하는 경우 참조하는 파일의 내용을 새 토큰으로 업데이트합니다. 구성 변경은 필요하지 않습니다. 토큰 파일은 시작 시 읽습니다. -
Gitaly를 재시작합니다.
gitlab-ctl restart gitaly
이 변경 사항을 배포하는 동안 Prometheus 쿼리를 실행하면
enforced="false",status="denied" 카운터에 0이 아닌 값이 표시됩니다.
인증 실패가 없는지 확인#
새 토큰을 설정하고 관련된 모든 서비스를 재시작한 후에는 다음 두 값이 일시적으로 함께 표시됩니다.
status="would be ok"status="denied"
모든 Gitaly 클라이언트와 Gitaly 서버가 새 토큰을 인식하고 나면
0이 아닌 비율은 enforced="false",status="would be ok"뿐이어야 합니다.
인증 전환 모드 비활성화#
Gitaly 인증을 다시 활성화하려면 인증 전환 모드를 비활성화합니다. Gitaly 서버에서 구성을 다음과 같이 업데이트합니다.
# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
# ...
auth: {
# ...
transitioning: false,
},
}
이 단계를 완료하지 않으면 Gitaly 인증이 적용되지 않습니다.
인증이 적용되는지 확인#
Prometheus 쿼리를 새로 고칩니다. 이제 처음과 비슷한 결과가 표시됩니다. 예를 들면 다음과 같습니다.
{enforced="true",status="ok"} 4424.985419441742
enforced="true"는 인증이 적용되고 있음을 의미합니다.
Pack-objects 캐시#
Git 리포지터리의 스토리지를 제공하는 서비스인 Gitaly는 Git fetch 응답을 짧은 롤링 윈도우 동안 캐시하도록 구성할 수 있습니다. 이렇게 하면 서버가 CI fetch 트래픽을 많이 받을 때 서버 부하를 줄일 수 있습니다.
pack-objects 캐시는 git pack-objects를 감쌉니다. git pack-objects는 Git의 내부 구성 요소로,
PostUploadPack 및 SSHUploadPack Gitaly RPC를 통해 간접적으로 호출됩니다.
사용자가 HTTP로 Git fetch를 하면 Gitaly가 PostUploadPack을 실행하고,
SSH로 Git fetch를 하면
SSHUploadPack을 실행합니다.
캐시를 활성화하면 PostUploadPack 또는 SSHUploadPack을 사용하는 모든 작업이 이점을 얻을 수 있습니다.
이 캐시는 다음과 무관하며 영향을 받지 않습니다.
- 전송 방식(HTTP 또는 SSH)
- Git 프로토콜 버전(v0 또는 v2)
- 전체 클론, 증분 fetch, 얕은 클론, 부분 클론과 같은 fetch 유형
이 캐시의 강점은 동시에 발생하는 동일한 fetch를 중복 제거하는 능력입니다. 이 캐시는 다음과 같습니다.
- 동시 job이 많은 CI/CD 파이프라인을 사용자가 실행하는 GitLab 인스턴스에 도움이 될 수 있습니다. 서버 CPU 사용률이 눈에 띄게 감소할 것입니다.
- 고유한 fetch에는 전혀 도움이 되지 않습니다. 예를 들어 로컬 컴퓨터로 리포지터리를 클론하여 간단히 확인해 보는 경우 해당 fetch는 고유할 가능성이 높으므로 이 캐시의 이점을 보기 어렵습니다.
pack-objects 캐시는 로컬 캐시입니다. 이 캐시는 다음과 같이 동작합니다.
- 메타데이터를 캐시가 활성화된 Gitaly 프로세스의 메모리에 저장합니다.
- 캐시하는 실제 Git 데이터를 로컬 스토리지의 파일에 저장합니다.
로컬 파일을 사용하면 운영 체제가 pack-objects 캐시 파일의 일부를 자동으로 RAM에 유지할 수 있어 속도가 빨라지는 이점이 있습니다.
pack-objects 캐시는 디스크 쓰기 IO를 크게 증가시킬 수 있으므로 기본적으로 꺼져 있습니다.
캐시 구성#
pack-objects 캐시에 사용할 수 있는 구성 설정은 다음과 같습니다. 각 설정은 아래에서 더 자세히 설명합니다.
| 설정 | 기본값 | 설명 |
|---|---|---|
enabled |
false |
캐시를 켭니다. 꺼져 있으면 Gitaly는 요청마다 전용 git pack-objects 프로세스를 실행합니다. |
dir |
/+gitaly/PackObjectsCache |
캐시 파일이 저장되는 로컬 디렉터리입니다. |
max_age |
5m (5분) |
이보다 오래된 캐시 항목은 제거되며 디스크에서 삭제됩니다. |
min_occurrences |
1 | 캐시 항목이 생성되기 전에 키가 발생해야 하는 최소 횟수입니다. |
/etc/gitlab/gitlab.rb에서 다음을 설정합니다.
gitaly['configuration'] = {
# ...
pack_objects_cache: {
enabled: true,
# The default settings for "dir", "max_age" and "min_occurences" should be fine.
# If you want to customize these, see details below.
},
}
enabled 기본값은 false#
경우에 따라 디스크에 기록되는 바이트 수가 극단적으로 증가할 수 있으므로 캐시는 기본적으로 비활성화되어 있습니다. GitLab.com에서는 리포지터리 스토리지 디스크가 이 추가 작업량을 처리할 수 있음을 확인했지만, 이것이 모든 환경에서 성립한다고 가정할 수는 없다고 판단했습니다.
캐시 스토리지 디렉터리 dir#
캐시에는 파일을 저장할 디렉터리가 필요합니다. 이 디렉터리는 다음 조건을 충족해야 합니다.
- 공간이 충분한 파일 시스템에 있어야 합니다. 캐시 파일 시스템의 공간이 부족해지면 모든 fetch가 실패하기 시작합니다.
- IO 대역폭이 충분한 디스크에 있어야 합니다. 캐시 디스크의 IO 대역폭이 부족해지면 모든 fetch가 느려지고, 서버 전체도 느려질 가능성이 큽니다.
지정한 디렉터리에 있는 기존 데이터는 모두 삭제됩니다. 기존 데이터가 있는 디렉터리를 사용하지 않도록 주의합니다.
기본적으로 캐시 스토리지 디렉터리는 구성 파일에 정의된 첫 번째 Gitaly 스토리지의 하위 디렉터리로 설정됩니다.
여러 Gitaly 프로세스가 같은 디렉터리를 캐시 스토리지로 사용할 수 있습니다. 각 Gitaly 프로세스는 자신이 만드는 캐시 파일 이름에 고유한 무작위 문자열을 포함합니다. 따라서 다음과 같습니다.
- 서로 충돌하지 않습니다.
- 다른 프로세스의 파일을 재사용하지 않습니다.
기본 디렉터리는 캐시 파일을 리포지터리 데이터와 같은 파일 시스템에 두지만, 이것이 필수는 아닙니다. 인프라에 더 적합하다면 캐시 파일을 다른 파일 시스템에 둘 수 있습니다.
디스크에서 필요한 IO 대역폭은 다음에 따라 달라집니다.
- Gitaly 서버에 있는 리포지터리의 크기와 형태
- 사용자가 발생시키는 트래픽의 종류
캐시 적중률이 0%라고 가정한 비관적 추정치로
gitaly_pack_objects_generated_bytes_total 메트릭을 사용할 수 있습니다.
필요한 공간은 다음에 따라 달라집니다.
- 사용자가 캐시에서 초당 가져오는 바이트 수
- 캐시 제거 윈도우
max_age의 크기
사용자가 100 MB/s를 가져오고 5분 윈도우를 사용한다면 캐시 디렉터리에는 평균적으로
5*60*100 MB = 30 GB의 데이터가 있습니다. 이 평균은 예상 평균일 뿐 보장값이 아닙니다.
최대 크기는 이 평균을 넘을 수 있습니다.
캐시 제거 윈도우 max_age#
max_age 구성 설정으로 캐시 적중 확률과 캐시 파일이 사용하는 평균 스토리지 양을
제어할 수 있습니다.
max_age보다 오래된 항목은 디스크에서 삭제됩니다.
제거는 진행 중인 요청에 영향을 주지 않습니다. max_age가 느린 연결로 fetch를 수행하는 데 걸리는 시간보다 짧아도 문제가 없습니다.
Unix 파일 시스템은 삭제된 파일을 읽는 모든 프로세스가
그 파일을 닫기 전까지는 파일을 실제로 삭제하지 않기 때문입니다.
최소 키 발생 횟수 min_occurrences#
min_occurrences 설정은 새 캐시 항목을 만들기 전에 동일한 요청이
몇 번 발생해야 하는지를 제어합니다. 기본값은 1이며,
고유한 요청은 캐시에 기록되지 않는다는 뜻입니다.
이 값을 다음과 같이 바꾸면 결과가 달라집니다.
- 값을 늘리면 캐시 적중률이 낮아지고 캐시가 디스크 공간을 덜 사용합니다.
- 값을 줄이면 캐시 적중률이 높아지고 캐시가 디스크 공간을 더 사용합니다.
min_occurrences는 1로 설정합니다. GitLab.com에서는 0에서 1로 바꾸어
캐시 디스크 공간을 50% 절약했으며,
캐시 적중률에는 거의 영향이 없었습니다.
캐시 관찰#
Prometheus 메트릭과 로그 필드를 사용해 캐시를 관찰할 수 있습니다.
Prometheus 메트릭#
Gitaly는 pack-objects 캐시를 모니터링하기 위해 다음 Prometheus 메트릭을 내보냅니다.
| 메트릭 | 유형 | 설명 |
|---|---|---|
gitaly_pack_objects_served_bytes_total |
Counter | 클라이언트에 제공한 git-pack-objects 데이터의 총 바이트 수 |
gitaly_pack_objects_cache_lookups_total |
Counter | 캐시 조회 횟수. result 레이블은 hit 또는 miss를 나타냅니다 |
gitaly_pack_objects_generated_bytes_total |
Counter | git-pack-objects 실행으로 생성된 총 바이트 수 |
Prometheus 쿼리 예시
캐시 적중률:
sum(rate(gitaly_pack_objects_cache_lookups_total{result="hit"}[5m])) /
sum(rate(gitaly_pack_objects_cache_lookups_total[5m]))
캐시에서 초당 제공한 바이트 수:
rate(gitaly_pack_objects_served_bytes_total[5m])
초당 생성된 바이트 수(캐시 미스):
rate(gitaly_pack_objects_generated_bytes_total[5m])
캐시 효율(제공한 바이트 수 대비 생성된 바이트 수):
rate(gitaly_pack_objects_served_bytes_total[5m]) /
rate(gitaly_pack_objects_generated_bytes_total[5m])
로그 필드#
이 로그는 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_bytes와pack_objects_cache.served_bytes메시지를 모두 기록합니다. 또한 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": "Total 145991 (delta 68), reused 6 (delta 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 프로세스 수에 최댓값이 있습니다.
기본 한도는 cat-file 100개이며, 하나의 cat-file은 git cat-file --batch와
git cat-file --batch-check 프로세스 한 쌍으로 구성됩니다.
"too many open files" 오류가 표시되거나
새 프로세스를 만들 수 없다면 이 한도를 낮추는 것이 좋을 수 있습니다.
이상적으로는 일반적인 트래픽을 처리할 수 있을 만큼 큰 수여야 합니다. 한도를 높였다면 변경 전후의 캐시 적중률을 측정합니다. 적중률이 개선되지 않는다면 한도를 높여도 의미 있는 차이가 없을 가능성이 큽니다. 다음은 적중률을 확인하는 Prometheus 쿼리 예시입니다.
sum(rate(gitaly_catfile_cache_total{type="hit"}[5m])) / sum(rate(gitaly_catfile_cache_total{type=~"(hit)|(miss)"}[5m]))
cat-file 캐시는 Gitaly 구성 파일에서 구성합니다.
GitLab UI 커밋에 대한 커밋 서명 구성#
히스토리
- GitLab UI에서 서명된 커밋에 Verified 배지를 표시하는 기능이 GitLab 16.3에서
gitaly_gpg_signing이라는 기능 플래그와 함께 도입되었습니다. 기본적으로 비활성화되어 있습니다. - GitLab 17.0에서 GitLab Self-Managed와 GitLab Dedicated에 기본적으로 활성화되었습니다.
GitLab Self-Managed에서는 기본적으로 이 기능을 사용할 수 있습니다. 기능을 숨기려면
관리자가 gitaly_gpg_signing이라는 기능 플래그를 비활성화할 수 있습니다.
GitLab.com에서는 이 기능을 사용할 수 없습니다. GitLab Dedicated에서는 이 기능을 사용할 수 있습니다.
기본적으로 Gitaly는 GitLab UI를 사용해 만든 커밋에 서명하지 않습니다. 예를 들어 다음을 사용해 만든 커밋이 이에 해당합니다.
- 웹 에디터
- Web IDE
- 머지 리퀘스트
Gitaly에서 커밋 서명을 활성화하면 다음과 같이 동작합니다.
- GitLab이 UI를 통해 만든 모든 커밋에 서명합니다.
- 서명은 작성자의 신원이 아니라 커미터의 신원을 검증합니다.
committer_email과committer_name을 설정하여 커밋이 인스턴스에서 커밋되었음을 반영하도록 Gitaly를 구성할 수 있습니다. 예를 들어 GitLab.com에서는 이 구성 옵션이noreply@gitlab.com과GitLab으로 설정되어 있습니다.
rotated_signing_keys는 검증에만 사용할 키 목록입니다. Gitaly는 구성된 signing_key로 웹 커밋을 먼저 검증하고, 성공할 때까지
교체된 키를 하나씩 사용합니다. 다음 중 하나에 해당하면 rotated_signing_keys 옵션을 설정합니다.
- 서명 키를 교체한 경우
- 다른 인스턴스에서 프로젝트를 마이그레이션하기 위해 여러 키를 지정하고, 해당 웹 커밋을 Verified로 표시하려는 경우
GitLab UI로 만든 커밋에 서명하도록 Gitaly를 구성하려면 다음 두 가지 방법 중 하나를 사용합니다.
-
GPG 키를 생성하여 내보내거나 SSH 키를 생성합니다. 최적의 성능을 위해 EdDSA 키를 사용합니다.
GPG 키 내보내기:
gpg --export-secret-keys > signing_key.gpg또는 SSH 키를 생성합니다(암호 없이).
ssh-keygen -t ed25519 -f signing_key.ssh -
Gitaly 노드에서 키를
/etc/gitlab/gitaly/로 복사하고git사용자에게 파일을 읽을 권한이 있는지 확인합니다. -
/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'], # ... }, } -
파일을 저장하고 GitLab을 재구성합니다.
-
GPG 키를 생성하여 내보내거나 SSH 키를 생성합니다. 최적의 성능을 위해 EdDSA 키를 사용합니다.
GPG 키 내보내기:
gpg --export-secret-keys > signing_key.gpg또는 SSH 키를 생성합니다(암호 없이).
ssh-keygen -t ed25519 -f signing_key.ssh -
Gitaly 노드에서 키를
/etc/gitlab으로 복사합니다. -
/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"] -
파일을 저장하고 GitLab을 재시작합니다.
사용자 정의 Git 구성 구성#
Gitaly는 시스템 수준 또는 사용자 수준의 Git 구성 파일을 읽지 않습니다. Gitaly 서버에서 사용자 정의 Git
구성을 제공하려면 git.config 설정을 사용합니다.
/etc/gitlab/gitlab.rb를 편집합니다.
gitaly['configuration'] = {
# ...
git: {
# ...
config: [
{ key: "fsck.badDate", value: "ignore" },
...
],
},
}
/home/git/gitaly/config.toml을 편집합니다.
[[git.config]]
key = "fsck.badDate"
value = "ignore"
Gitaly에서 설정하는 Git 구성#
Gitaly는 다음 Git 구성 값을 설정하며, 이 값은 git.config 설정으로
덮어쓸 수 없습니다.
advice.fetchShowForcedUpdatesattr.treebundle.heuristicbundle.modebundle.versioncore.alternateRefsCommandcore.autocrlfcore.bigFileThresholdcore.filesRefLockTimeoutcore.fsynccore.fsyncMethodcore.hooksPathcore.packedRefsTimeoutcore.useReplaceRefsdiff.noprefixfetch.fsck.badTimezonefetch.fsck.missingSpaceBeforeDatefetch.fsck.zeroPaddedFilemodefetch.fsckObjectsfetch.negotiationAlgorithmfetch.recurseSubmodulesfetch.writeCommitGraphfsck.badTimezonefsck.missingSpaceBeforeDatefsck.zeroPaddedFilemodegc.autogrep.threadshttp.<url>.extraHeaderhttp.curloptResolvehttp.extraHeaderhttp.followRedirectsinit.defaultBranchinit.templateDirmaintenance.autopack.allowPackReusepack.islandpack.islandCorepack.threadspack.windowMemorypack.writeBitmapLookupTablepack.writeReverseIndexreceive.advertisePushOptionsreceive.autogcreceive.fsck.badTimezonereceive.fsck.missingSpaceBeforeDatereceive.fsck.zeroPaddedFilemodereceive.hideRefsreceive.procReceiveRefsremote.inmemory.fetchremote.inmemory.urlremote.origin.fetchremote.origin.urlrepack.updateServerInforepack.writeBitmapstransfer.bundleURItransfer.fsckObjectsuploadpack.advertiseBundleURIsuploadpack.allowAnySHA1InWantuploadpack.allowFilteruploadpack.hideRefs
외부 명령을 사용하여 구성 생성#
외부 명령을 사용하여 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에 알려야 합니다.
/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으로 파싱할 수 없는 경우
서버 측 백업 구성#
히스토리
- Helm 차트 설치에 대한 서버 측 지원이 GitLab 17.0에 추가되었습니다.
각 리포지터리를 호스팅하는 Gitaly 노드가 백업을 생성하고 오브젝트 스토리지로 스트리밍하도록 리포지터리 백업을 구성할 수 있습니다. 이렇게 하면 백업을 생성하고 복원하는 데 필요한 네트워크 리소스를 줄일 수 있습니다.
각 Gitaly 노드는 백업을 위해 오브젝트 스토리지에 연결하도록 구성해야 합니다.
서버 측 백업을 구성한 후에는 서버 측 리포지터리 백업을 생성할 수 있습니다.
Azure Blob 스토리지 구성#
백업용 Azure Blob 스토리지를 구성하는 방법은 설치 유형에 따라 다릅니다. 자체 컴파일 설치에서는
GitLab 외부에서 AZURE_STORAGE_ACCOUNT와 AZURE_STORAGE_KEY 환경 변수를 설정해야 합니다.
/etc/gitlab/gitlab.rb를 편집하고 go_cloud_url을 구성합니다.
gitaly['env'] = {
'AZURE_STORAGE_ACCOUNT' => 'azure_storage_account',
'AZURE_STORAGE_KEY' => 'azure_storage_key' # or 'AZURE_STORAGE_SAS_TOKEN'
}
gitaly['configuration'] = {
backup: {
go_cloud_url: 'azblob://<bucket>'
}
}
Helm 기반 배포는 Gitaly 차트의 서버 측 백업 문서를 참고합니다.
/home/git/gitaly/config.toml을 편집하고 go_cloud_url을 구성합니다.
[backup]
go_cloud_url = "azblob://<bucket>"
Azure 관리형 ID 사용#
공유 액세스 키나 SAS 토큰 대신 Gitaly는 Gitaly 노드에 연결된 관리형 ID를 사용하여
Azure Blob 스토리지에 인증할 수 있습니다.
이 ID에는 백업 컨테이너에 대한 Storage Blob Data Contributor 역할이
있어야 합니다.
스토리지 계정은 go_cloud_url의 storage_account 쿼리 매개변수로 지정합니다.
AZURE_STORAGE_KEY, AZURE_STORAGE_SAS_TOKEN, AZURE_STORAGE_CONNECTION_STRING은
설정하지 않은 상태로 둡니다. Gitaly는 이러한 자격 증명이 하나도 없으면
노드에 연결된 관리형 ID로 인증합니다.
/etc/gitlab/gitlab.rb를 편집하고 go_cloud_url을 구성합니다.
gitaly['configuration'] = {
backup: {
go_cloud_url: 'azblob://<bucket>?storage_account=<azure_storage_account>'
}
}
Helm 기반 배포는 Gitaly 차트의 서버 측 백업 문서를 참고합니다.
/home/git/gitaly/config.toml을 편집하고 go_cloud_url을 구성합니다.
[backup]
go_cloud_url = "azblob://<bucket>?storage_account=<azure_storage_account>"
사용자 할당 관리형 ID를 사용하려면 Gitaly 프로세스의 환경에서
AZURE_CLIENT_ID도 해당 ID의 클라이언트 ID로 설정합니다.
gitaly['env'] = {
'AZURE_CLIENT_ID' => '<user_assigned_identity_client_id>'
}
Gitaly는 Azure ID 체인을 통해 관리형 ID 자격 증명을 확인하며,
이 체인은 환경에서만 AZURE_CLIENT_ID와 AZURE_TOKEN_CREDENTIALS를 읽습니다.
이 값은 go_cloud_url에서 설정할 수 없습니다.
Google Cloud 스토리지 구성#
Google Cloud 스토리지(GCP)는 Application Default Credentials로 인증합니다. 각 Gitaly 서버에서 다음 중 하나로 Application Default Credentials를 설정합니다.
gcloud auth application-default login명령GOOGLE_APPLICATION_CREDENTIALS환경 변수. 자체 컴파일 설치에서는 GitLab 외부에서 환경 변수를 설정합니다.
자세한 내용은 Application Default Credentials를 참고합니다.
대상 버킷은 go_cloud_url 옵션으로 구성합니다.
/etc/gitlab/gitlab.rb를 편집하고 go_cloud_url을 구성합니다.
gitaly['env'] = {
'GOOGLE_APPLICATION_CREDENTIALS' => '/path/to/service.json'
}
gitaly['configuration'] = {
backup: {
go_cloud_url: 'gs://<bucket>'
}
}
Helm 기반 배포는 Gitaly 차트의 서버 측 백업 문서를 참고합니다.
/home/git/gitaly/config.toml을 편집하고 go_cloud_url을 구성합니다.
[backup]
go_cloud_url = "gs://<bucket>"
S3 스토리지 구성#
S3 스토리지 인증을 구성하는 방법은 다음과 같습니다.
- AWS CLI로 인증하는 경우 기본 AWS 세션을 사용할 수 있습니다.
- 그렇지 않으면
AWS_ACCESS_KEY_ID와AWS_SECRET_ACCESS_KEY환경 변수를 사용할 수 있습니다. 자체 컴파일 설치에서는 GitLab 외부에서 환경 변수를 설정합니다.
자세한 내용은 AWS Session 문서를 참고합니다.
대상 버킷과 리전은 go_cloud_url 옵션으로 구성합니다.
/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'
}
}
Helm 기반 배포는 Gitaly 차트의 서버 측 백업 문서를 참고합니다.
/home/git/gitaly/config.toml을 편집하고 go_cloud_url을 구성합니다.
[backup]
go_cloud_url = "s3://<bucket>?region=us-west-1"
S3 호환 서버 구성#
S3 호환 서버는 endpoint 매개변수가 추가된다는 점만 제외하면 S3와 비슷하게 구성합니다.
지원되는 매개변수는 다음과 같습니다.
region: AWS 리전endpoint: 엔드포인트 URLdisabledSSL:true로 설정하면 SSL을 비활성화합니다.s3ForcePathStyle:true로 설정하면 경로 스타일 주소 지정을 강제합니다.
Helm 기반 배포는 Gitaly 차트의 서버 측 백업 문서를 참고합니다.
/etc/gitlab/gitlab.rb를 편집하고 go_cloud_url을 구성합니다.
gitaly['env'] = {
'AWS_ACCESS_KEY_ID' => '<your_access_key_id>',
'AWS_SECRET_ACCESS_KEY' => '<your_secret_access_key>'
}
gitaly['configuration'] = {
backup: {
go_cloud_url: 's3://<bucket>?region=us-east-1&endpoint=s3.example.com:9000&disableSSL=true&s3ForcePathStyle=true'
}
}
/home/git/gitaly/config.toml을 편집하고 go_cloud_url을 구성합니다.
[backup]
go_cloud_url = "s3://<bucket>?region=us-east-1&endpoint=s3.example.com:9000&disableSSL=true&s3ForcePathStyle=true"