GitLab 컨테이너 레지스트리 관리
GitLab v19.2Offering: GitLab Self-Managed
차세대 컨테이너 레지스트리는 이제 GitLab Self-Managed 인스턴스에서 업그레이드할 수 있습니다. GitLab 컨테이너 레지스트리를 사용하면, 모든 프로젝트에서 Docker 이미지를 저장할 수 있는 고유한 공간을 가질 수 있습니다.
차세대 컨테이너 레지스트리는 이제 GitLab Self-Managed 인스턴스에서 업그레이드할 수 있습니다. 이 업그레이드된 레지스트리는 온라인 가비지 컬렉션을 지원하며, 성능과 안정성이 크게 향상되었습니다.
GitLab 컨테이너 레지스트리를 사용하면, 모든 프로젝트에서 Docker 이미지를 저장할 수 있는 고유한 공간을 가질 수 있습니다.
Distribution Registry에 대한 자세한 내용:
이 문서는 관리자 가이드입니다. GitLab 컨테이너 레지스트리 사용 방법은 사용자 문서를 참고하세요.
컨테이너 레지스트리 활성화#
컨테이너 레지스트리를 활성화하는 방법은 설치 유형에 따라 다릅니다.
Linux 패키지 설치#
GitLab을 Linux 패키지로 설치한 경우, 컨테이너 레지스트리는 기본적으로 활성화되어 있거나 그렇지 않을 수 있습니다.
내장된 Let's Encrypt 통합을 사용하는 경우, 컨테이너 레지스트리는 자동으로 활성화되어 GitLab 도메인의 포트 5050에서 사용할 수 있습니다.
그 외의 경우, 컨테이너 레지스트리는 활성화되지 않습니다. 활성화하려면:
-
GitLab 도메인에서 구성하거나,
-
별도 도메인에서 구성할 수 있습니다.
컨테이너 레지스트리는 기본적으로 HTTPS에서 동작합니다. HTTP를 사용할 수 있지만 권장하지 않으며, 이 문서의 범위를 벗어납니다.
Helm Charts 설치#
Helm Charts 설치의 경우, Helm Charts 문서의 컨테이너 레지스트리 사용을 참고하세요.
소스 직접 컴파일 설치#
GitLab을 직접 컴파일하여 설치한 경우:
-
설치하는 GitLab 버전에 맞는 이미지를 사용하여 레지스트리를 배포해야 합니다. (예:
registry.gitlab.com/gitlab-org/build/cng/gitlab-container-registry:v3.15.0-gitlab) -
설치가 완료되면, 활성화하기 위해
gitlab.yml에서 Registry의 설정을 구성해야 합니다. -
lib/support/nginx/registry-ssl의 샘플 NGINX 설정 파일을 사용하고,host,port, TLS 인증서 경로에 맞게 편집하세요.
gitlab.yml의 내용은 다음과 같습니다:
registry:
enabled: true
host: <registry.gitlab.example.com>
port: <5005>
api_url: <http://localhost:5000/>
key: <config/registry.key>
path: <shared/registry>
issuer: <gitlab-issuer>
각 파라미터 설명:
| 파라미터 | 설명 |
|---|---|
| enabled | true 또는 false. GitLab에서 Registry를 활성화합니다. 기본값은 false입니다. |
| host | Registry가 실행되고 사용자가 접속할 수 있는 호스트 URL입니다. |
| port | 외부 Registry 도메인이 수신하는 포트입니다. |
| api_url | Registry가 노출되는 내부 API URL입니다. 기본값은 http://localhost:5000입니다. 외부 Docker 레지스트리를 설정하는 경우가 아니면 변경하지 마세요. |
| key | Registry의 rootcertbundle과 쌍을 이루는 개인 키 위치입니다. |
| path | Registry의 rootdirectory에 지정된 것과 동일한 디렉터리여야 합니다. 이 경로는 GitLab 사용자, 웹 서버 사용자, Registry 사용자 모두 읽을 수 있어야 합니다. |
| issuer | Registry의 issuer에 구성된 것과 동일한 값이어야 합니다. |
소스에서 설치한 경우 GitLab과 함께 Registry 초기화 파일이 제공되지 않습니다. 따라서 설정을 수정해도 GitLab을 재시작해도 Registry는 재시작되지 않습니다. 이를 위한 방법은 업스트림 문서를 참고하세요.
최소한 Registry 구성에 서비스로 container_registry가, realm으로 https://gitlab.example.com/jwt/auth가 포함되어 있는지 확인하세요:
auth:
token:
realm: <https://gitlab.example.com/jwt/auth>
service: container_registry
issuer: gitlab-issuer
rootcertbundle: /root/certs/certbundle
auth가 설정되지 않으면, 사용자는 인증 없이 Docker 이미지를 풀할 수 있습니다.
컨테이너 레지스트리 도메인 구성#
Registry의 외부 도메인은 다음 두 가지 방법으로 구성할 수 있습니다:
-
기존 GitLab 도메인 사용. Registry는 포트에서 수신하고 GitLab의 TLS 인증서를 재사용합니다.
-
별도의 도메인 사용: 해당 도메인에 새로운 TLS 인증서가 필요합니다.
컨테이너 레지스트리는 TLS 인증서가 필요하기 때문에, 비용이 고려사항이 될 수 있습니다.
컨테이너 레지스트리를 처음 구성하기 전에 이 점을 고려하세요.
기존 GitLab 도메인에서 컨테이너 레지스트리 구성#
컨테이너 레지스트리가 기존 GitLab 도메인을 사용하도록 구성된 경우, 포트에서 컨테이너 레지스트리를 노출할 수 있습니다. 이 방법으로 기존 GitLab TLS 인증서를 재사용할 수 있습니다.
GitLab 도메인이 https://gitlab.example.com이고 외부 포트가 5050인 경우, 컨테이너 레지스트리를 구성하려면:
-
Linux 패키지 설치를 사용하는 경우
gitlab.rb를 편집합니다. -
소스 직접 컴파일 설치를 사용하는 경우
gitlab.yml을 편집합니다.
Registry가 수신하는 포트(5000 기본값)와 다른 포트를 선택해야 합니다. 그렇지 않으면 충돌이 발생합니다.
호스트와 컨테이너 방화벽 규칙은 gitlab_rails['registry_port'](기본값 5000)가 아닌 registry_external_url 행에 나열된 포트를 통해 트래픽이 통과하도록 구성되어야 합니다.
Linux package (Omnibus)
/etc/gitlab/gitlab.rb에 레지스트리 URL과 GitLab에서 사용하는 기존 TLS 인증서 및 키 경로가 포함되어야 합니다:
registry_external_url '<https://gitlab.example.com:5050>'
registry_external_url은 기존 GitLab URL에서 HTTPS를 통해 수신하지만 다른 포트를 사용합니다.
TLS 인증서가 /etc/gitlab/ssl/gitlab.example.com.crt에 없거나 키가 /etc/gitlab/ssl/gitlab.example.com.key에 없으면 다음 줄의 주석을 해제하세요:
registry_nginx['ssl_certificate'] = "</path/to/certificate.pem>"
registry_nginx['ssl_certificate_key'] = "</path/to/certificate.key>"
-
파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
-
다음을 사용하여 검증합니다:
openssl s_client -showcerts -servername gitlab.example.com -connect gitlab.example.com:5050 > cacert.pem
인증서 공급자가 CA 번들 인증서를 제공하는 경우, TLS 인증서 파일에 추가하세요.
관리자는 컨테이너 레지스트리가 5678과 같은 임의 포트에서 수신하도록 할 수 있습니다. 그러나 레지스트리와 애플리케이션 서버가 포트 80과 443에서만 수신하는 AWS 애플리케이션 로드 밸런서 뒤에 있는 경우, 관리자는 registry_external_url에서 포트 번호를 제거하여 HTTP 또는 HTTPS로 가정할 수 있습니다. 그런 다음, 로드 밸런서를 포트 80 또는 443에서 임의 포트로 레지스트리에 매핑하는 규칙이 적용됩니다. 이는 사용자가 컨테이너 레지스트리의 docker login 예제를 사용하는 경우 중요합니다. 다음은 예제입니다:
registry_external_url '<https://registry-gitlab.example.com>'
registry_nginx['redirect_http_to_https'] = true
registry_nginx['listen_port'] = 5678
Self-compiled (source)
/home/git/gitlab/config/gitlab.yml을 열고registry항목을 찾아 다음 설정으로 구성하세요:
registry:
enabled: true
host: <gitlab.example.com>
port: 5050
-
파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작하세요.
-
NGINX에서도 관련 변경(도메인, 포트, TLS 인증서 경로)을 적용하세요.
이제 사용자는 다음을 사용하여 GitLab 자격 증명으로 컨테이너 레지스트리에 로그인할 수 있습니다:
docker login <gitlab.example.com:5050>
자체 도메인에서 컨테이너 레지스트리 구성#
Registry가 자체 도메인을 사용하도록 구성된 경우, 해당 특정 도메인(예: registry.example.com)의 TLS 인증서가 필요합니다. 기존 GitLab 도메인의 하위 도메인에서 호스팅하는 경우 와일드카드 인증서가 필요할 수 있습니다. 예를 들어, *.gitlab.example.com은 registry.gitlab.example.com과 일치하는 와일드카드이며 *.example.com과는 다릅니다.
수동으로 생성된 SSL 인증서(여기서 설명) 외에도, Let's Encrypt에서 자동으로 생성된 인증서도 Linux 패키지 설치에서 지원됩니다.
컨테이너 레지스트리를 https://registry.gitlab.example.com에서 접근 가능하게 하려면:
Linux package (Omnibus)
- TLS 인증서와 키를
/etc/gitlab/ssl/<registry.gitlab.example.com>.crt와/etc/gitlab/ssl/<registry.gitlab.example.com>.key에 배치하고 올바른 권한이 있는지 확인하세요:
chmod 600 /etc/gitlab/ssl/<registry.gitlab.example.com>.*
- TLS 인증서가 준비된 후
/etc/gitlab/gitlab.rb를 다음과 같이 편집하세요:
registry_external_url '<https://registry.gitlab.example.com>'
registry_external_url은 HTTPS에서 수신합니다.
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
와일드카드 인증서를 사용하는 경우, URL에 더해 인증서 경로도 지정해야 합니다. 이 경우 /etc/gitlab/gitlab.rb는 다음과 같습니다:
registry_nginx['ssl_certificate'] = "/etc/gitlab/ssl/certificate.pem"
registry_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/certificate.key"
Self-compiled (source)
/home/git/gitlab/config/gitlab.yml을 열고registry항목을 찾아 다음 설정으로 구성하세요:
registry:
enabled: true
host: <registry.gitlab.example.com>
-
파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작하세요.
-
NGINX에서도 관련 변경(도메인, 포트, TLS 인증서 경로)을 적용하세요.
이제 사용자는 GitLab 자격 증명을 사용하여 컨테이너 레지스트리에 로그인할 수 있습니다:
docker login <registry.gitlab.example.com>
자체 서명 인증서 구성#
컨테이너 레지스트리에 자체 서명 인증서를 사용하려면, Docker 데몬이 자체 서명 인증서를 신뢰하도록 구성해야 합니다:
-
Docker 데몬이 자체 서명 인증서를 사용하도록 지시하세요. 이 단계는 운영 체제에 따라 다릅니다.
-
GitLab Runner
config.toml파일에서 Docker 데몬을 마운트하고privileged = false를 설정하세요:
[runners.docker]
image = "ruby:2.6"
privileged = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
privileged = true로 설정하면 Docker 데몬 설정보다 우선합니다.
- Docker를 재시작하세요.
컨테이너 레지스트리 사이트 전체 비활성화#
다음 단계에 따라 Registry를 비활성화해도 기존 Docker 이미지는 제거되지 않습니다. Docker 이미지 제거는 Registry 애플리케이션 자체에서 처리합니다.
Linux package (Omnibus)
/etc/gitlab/gitlab.rb를 열고registry['enable']을false로 설정하세요:
registry['enable'] = false
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
Self-compiled (source)
/home/git/gitlab/config/gitlab.yml을 열고registry항목을 찾아enabled를false로 설정하세요:
registry:
enabled: false
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작하세요.
새 프로젝트에 대해 컨테이너 레지스트리 사이트 전체 비활성화#
컨테이너 레지스트리가 활성화된 경우, 모든 새 프로젝트에서 사용할 수 있어야 합니다. 이 기능을 비활성화하고 프로젝트 Owner가 직접 컨테이너 레지스트리를 활성화할 수 있도록 하려면 다음 단계를 따르세요.
Linux package (Omnibus)
/etc/gitlab/gitlab.rb를 편집하고 다음 줄을 추가하세요:
gitlab_rails['gitlab_default_projects_features_container_registry'] = false
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
Self-compiled (source)
/home/git/gitlab/config/gitlab.yml을 열고default_projects_features항목을 찾아container_registry를false로 설정하세요:
## Default project features settings
default_projects_features:
issues: true
merge_requests: true
wiki: true
snippets: false
builds: true
container_registry: false
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작하세요.
토큰 유효 기간 연장#
GitLab에서 컨테이너 레지스트리 토큰은 5분마다 만료됩니다. 토큰 유효 기간을 늘리려면:
-
오른쪽 상단에서 Admin을 선택하세요.
-
왼쪽 사이드바에서 Settings > CI/CD를 선택하세요.
-
Container Registry를 펼치세요.
-
**Authorization token duration (minutes)**에서 값을 업데이트하세요.
-
Save changes를 선택하세요.
컨테이너 레지스트리 기능 플래그#
컨테이너 레지스트리 기능 플래그는 컨테이너 레지스트리의 실험적이거나 전환 중인 기능을 제어하는 환경 변수 토글입니다.
GitLab 애플리케이션 기능 플래그와 달리, 컨테이너 레지스트리 기능 플래그는:
-
레지스트리 전용 환경 변수로 관리됩니다.
-
컨테이너 레지스트리 코드베이스에서 정의됩니다.
-
변경하려면 레지스트리 재구성이 필요합니다.
컨테이너 레지스트리 기능 플래그 구성#
다음 표에는 활성 컨테이너 레지스트리 기능 플래그가 나열되어 있습니다:
| 기능 플래그 | 설명 | 마일스톤 | 기본 상태 | 제거 마일스톤 |
|---|---|---|---|---|
| REGISTRY_FF_ONGOING_RENAME_CHECK | 이름 변경 작업 중인 프로젝트에 대해 Redis를 확인합니다. | 16.2 | 비활성화됨 | |
| REGISTRY_FF_DYNAMIC_MEDIA_TYPES | 런타임 중 새 미디어 타입 생성을 허용합니다. | 17.1 | 비활성화됨 | |
| REGISTRY_FF_BBM | 비동기 일괄 백그라운드 마이그레이션 프로세스를 제어합니다. | 17.2 | 비활성화됨 | |
| REGISTRY_FF_ENFORCE_LOCKFILES | 데이터베이스 또는 레거시 메타데이터 스토리지에 대한 잠금 파일 확인을 활성화합니다. | GitLab 17.6에서 도입됨. | GitLab 18.9의 GitLab Self-Managed에서 활성화됨. | GitLab 18.10에서 제거됨. |
컨테이너 레지스트리 기능 플래그를 구성하려면 사용하는 플랫폼에 맞는 지침을 따르세요.
Linux package
/etc/gitlab/gitlab.rb에서 기능 플래그를 구성하세요:
registry['env'] = {
'' => 'true' # or 'false' to disable
}
그런 다음, 컨테이너 레지스트리를 재구성하세요:
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart registry
Helm chart (Kubernetes)
values.yaml에서 기능 플래그를 구성하세요:
registry:
extraEnv:
: "true" # or "false" to disable
그런 다음, values.yaml을 업그레이드하세요:
helm upgrade gitlab gitlab/gitlab -f values.yaml
Docker
Docker Compose에서 환경 변수를 직접 설정하는 것은 작동하지 않습니다. gitlab.rb를 통해 구성해야 합니다.
Docker 또는 Docker Compose의 경우, gitlab.rb를 생성하거나 편집하세요:
registry['env'] = {
'' => 'true'
}
이 구성을 Docker Compose 설정에 마운트하고 GitLab이 시작 시 재구성되도록 하세요.
컨테이너 레지스트리 스토리지 구성#
컨테이너 레지스트리에 저장된 파일이나 객체를 직접 수정하지 마세요. 레지스트리가 항목을 쓰거나 삭제하는 것 외에 다른 방식으로 접근하면 인스턴스 전체의 데이터 일관성 및 안정성 문제가 발생할 수 있으며, 복구가 불가능할 수 있습니다.
스토리지 드라이버를 구성하여 컨테이너 레지스트리가 다양한 스토리지 백엔드를 사용하도록 구성할 수 있습니다. 기본적으로 GitLab 컨테이너 레지스트리는 파일 시스템 드라이버 구성을 사용하도록 설정되어 있습니다.
지원하는 스토리지 백엔드의 경우, 버킷에 저장된 모든 객체의 이전 버전을 보존, 검색 및 복원하기 위해 객체 버전 관리를 사용할 수 있습니다. 그러나 이로 인해 스토리지 사용량과 비용이 높아질 수 있습니다. 레지스트리 운영 방식으로 인해 이미지 업로드는 먼저 임시 경로에 저장된 후 최종 위치로 이전됩니다. S3 및 GCS를 포함한 객체 스토리지 백엔드의 경우, 이 이전은 복사 후 삭제로 수행됩니다. 객체 버전 관리가 활성화되면, 삭제된 임시 업로드 아티팩트가 이전 버전으로 유지되어 스토리지 버킷 크기가 증가합니다. 일정 시간이 지나면 이전 버전이 삭제되도록, 스토리지 공급자에서 객체 수명 주기 정책을 구성해야 합니다.
지원되는 드라이버는 다음과 같습니다:
| 드라이버 | 설명 |
|---|---|
| filesystem | 로컬 파일 시스템의 경로를 사용합니다. |
| azure | Microsoft Azure Blob Storage |
| gcs | Google Cloud Storage |
| s3 | Amazon Simple Storage Service. 버킷에 올바른 S3 권한 범위를 구성했는지 확인하세요. |
대부분의 S3 호환 서비스는 컨테이너 레지스트리에서 작동하지만, AWS S3만 공식적으로 지원합니다. 타사 S3 구현의 정확성을 보증할 수 없으므로 문제를 디버그할 수는 있지만, AWS S3 버킷에서 재현 가능한 문제가 아니면 레지스트리를 패치할 수 없습니다.
파일 시스템 사용#
파일 시스템에 이미지를 저장하려면, 컨테이너 레지스트리의 스토리지 경로를 변경할 수 있습니다. 다음 단계를 따르세요.
이 경로는 다음 사용자가 접근할 수 있어야 합니다:
-
컨테이너 레지스트리 데몬을 실행하는 사용자.
-
GitLab을 실행하는 사용자.
모든 GitLab, Registry, 웹 서버 사용자가 이 디렉터리에 접근할 수 있어야 합니다.
Linux package (Omnibus)
Linux 패키지 설치에서 이미지가 기본적으로 저장되는 위치는 /var/opt/gitlab/gitlab-rails/shared/registry입니다. 변경하려면:
/etc/gitlab/gitlab.rb를 편집하세요:
gitlab_rails['registry_path'] = "</path/to/registry/storage>"
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
Self-compiled (source)
소스 직접 컴파일 설치에서 이미지가 기본적으로 저장되는 위치는 /home/git/gitlab/shared/registry입니다. 변경하려면:
/home/git/gitlab/config/gitlab.yml을 열고registry항목을 찾아path설정을 변경하세요:
registry:
path: shared/registry
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작하세요.
객체 스토리지 사용#
로컬 파일 시스템 대신 객체 스토리지에 컨테이너 레지스트리 이미지를 저장하려면, 지원되는 스토리지 드라이버 중 하나를 구성할 수 있습니다.
자세한 내용은 객체 스토리지를 참고하세요.
GitLab은 파일 시스템에 저장되지 않은 Docker 이미지를 백업하지 않습니다. 원하는 경우 객체 스토리지 공급자를 통해 백업을 활성화하세요.
Linux 패키지 설치에서 객체 스토리지 구성#
컨테이너 레지스트리에 객체 스토리지를 구성하려면:
-
사용할 스토리지 드라이버를 선택하세요.
-
/etc/gitlab/gitlab.rb를 적절한 구성으로 편집하세요. -
파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
S3
S3 스토리지 드라이버는 Amazon S3 또는 S3 호환 객체 스토리지 서비스와 통합됩니다.
s3_v2 드라이버(베타)는 AWS SDK v2를 사용하며 인증에 서명 버전 4만 지원합니다.
이 드라이버는 성능과 안정성을 향상시키는 동시에, 이전 서명 방식에 대한 지원이 더 이상 사용되지 않으므로 AWS 인증 요구사항과의 호환성을 보장합니다. 자세한 내용은 에픽 16272를 참고하세요.
각 드라이버의 전체 구성 파라미터 목록은 s3_v1 및 s3_v2를 참고하세요.
S3 스토리지 드라이버를 구성하려면, /etc/gitlab/gitlab.rb 파일에 다음 구성 중 하나를 추가하세요:
# Deprecated: Will be removed in GitLab 19.0
registry['storage'] = {
's3' => {
'accesskey' => '<s3-access-key>',
'secretkey' => '<s3-secret-key-for-access-key>',
'bucket' => '<your-s3-bucket>',
'region' => '<your-s3-region>',
'regionendpoint' => '<your-s3-regionendpoint>'
}
}
또는
# Beta: s3_v2 driver
registry['storage'] = {
's3_v2' => {
'accesskey' => '<s3-access-key>',
'secretkey' => '<s3-secret-key-for-access-key>',
'bucket' => '<your-s3-bucket>',
'region' => '<your-s3-region>',
'regionendpoint' => '<your-s3-regionendpoint>'
}
}
보안을 강화하려면, accesskey와 secretkey 파라미터를 포함하지 않고 IAM 역할을 사용할 수 있습니다.
스토리지 비용 증가를 방지하려면, S3 버킷에 불완전한 멀티파트 업로드를 제거하는 수명 주기 정책을 구성하세요. 컨테이너 레지스트리는 이를 자동으로 정리하지 않습니다. 불완전한 멀티파트 업로드에 대한 3일 만료 정책은 대부분의 사용 패턴에 적합합니다.
loglevel 설정은 s3_v1과 s3_v2 드라이버 간에 다릅니다.
잘못된 드라이버에 loglevel을 설정하면 무시되고 경고 메시지가 출력됩니다.
일부 S3 호환 서비스에서 s3_v2 드라이버를 사용할 때, AWS 체크섬을 비활성화하기 위해 checksum_disabled 파라미터를 추가해야 할 수 있습니다:
registry['storage'] = {
's3_v2' => {
'accesskey' => '<s3-access-key>',
'secretkey' => '<s3-secret-key-for-access-key>',
'bucket' => '<your-s3-bucket>',
'region' => '<your-s3-region>',
'regionendpoint' => '<your-s3-regionendpoint>',
'checksum_disabled' => true
}
}
S3 VPC 엔드포인트의 경우:
registry['storage'] = {
's3_v2' => { # Beta driver
'accesskey' => '<s3-access-key>',
'secretkey' => '<s3-secret-key-for-access-key>',
'bucket' => '<your-s3-bucket>',
'region' => '<your-s3-region>',
'regionendpoint' => '<your-s3-vpc-endpoint>',
'pathstyle' => false
}
}
S3 구성 파라미터:
-
<your-s3-bucket>: 기존 버킷의 이름입니다. 하위 디렉터리는 포함할 수 없습니다. -
regionendpoint: S3 호환 서비스 또는 AWS S3 VPC 엔드포인트를 사용할 때만 필요합니다. -
pathstyle: URL 형식을 제어합니다.host/bucket_name/object형식(대부분의 S3 호환 서비스)에는true로,bucket_name.host/object형식(AWS S3)에는false로 설정하세요.
S3 API의 503 오류를 방지하려면, maxrequestspersecond 파라미터를 추가하여 연결 속도 제한을 설정하세요:
registry['storage'] = {
's3' => {
'accesskey' => '<s3-access-key>',
'secretkey' => '<s3-secret-key-for-access-key>',
'bucket' => '<your-s3-bucket>',
'region' => '<your-s3-region>',
'regionendpoint' => '<your-s3-regionendpoint>',
'maxrequestspersecond' => 100
}
}
Azure
Azure 스토리지 드라이버는 Microsoft Azure Blob Storage와 통합됩니다.
레거시 Azure 스토리지 드라이버는 GitLab 17.10에서 더 이상 사용되지 않게 되었으며 GitLab 19.0에서 제거될 예정입니다.
대신 azure_v2 드라이버(베타)를 사용하세요. 이 드라이버는 향상된 성능, 안정성, 현대적인 인증 방법을 제공합니다. 이는 주요 변경 사항이지만, 새 드라이버는 대부분의 구성에서 원활한 전환을 보장하도록 광범위하게 테스트되었습니다.
프로덕션 배포 전에 비프로덕션 환경에서 새 드라이버를 테스트하여 환경 및 사용 패턴에 특정한 엣지 케이스를 식별하고 해결하세요.
문제나 피드백은 이슈 525855를 통해 보고하세요.
각 드라이버의 전체 구성 파라미터 목록은 azure_v1 및 azure_v2를 참고하세요.
Azure 스토리지 드라이버를 구성하려면, /etc/gitlab/gitlab.rb 파일에 다음 구성 중 하나를 추가하세요:
# Deprecated: Will be removed in GitLab 19.0
registry['storage'] = {
'azure' => {
'accountname' => '<your_storage_account_name>',
'accountkey' => '<base64_encoded_account_key>',
'container' => '<container_name>'
}
}
또는
# Beta: azure_v2 driver
registry['storage'] = {
'azure_v2' => {
'credentials_type' => '<client_secret>',
'tenant_id' => '<your_tenant_id>',
'client_id' => '<your_client_id>',
'secret' => '<your_secret>',
'container' => '<your_container>',
'accountname' => '<your_account_name>'
}
}
기본적으로 Azure 스토리지 드라이버는 core.windows.net realm을 사용합니다. Azure 섹션에서 다른 realm 값을 설정할 수 있습니다(예: Azure Government Cloud의 경우 core.usgovcloudapi.net).
GCS
GCS 스토리지 드라이버는 Google Cloud Storage와 통합됩니다.
registry['storage'] = {
'gcs' => {
'bucket' => '<your_bucket_name>',
'keyfile' => '<path/to/keyfile>',
# If you have the bucket shared with other apps beyond the registry, uncomment the following:
# 'rootdirectory' => '/gcs/object/name/prefix'
}
}
GitLab은 사용 가능한 모든 파라미터를 지원합니다.
소스 직접 컴파일 설치#
스토리지 드라이버 구성은 Docker 레지스트리를 배포할 때 생성된 레지스트리 구성 YAML 파일에서 수행됩니다.
s3 스토리지 드라이버 예제:
storage:
s3:
accesskey: '<s3-access-key>' # Not needed if IAM role used
secretkey: '<s3-secret-key-for-access-key>' # Not needed if IAM role used
bucket: '<your-s3-bucket>'
region: '<your-s3-region>'
regionendpoint: '<your-s3-regionendpoint>'
cache:
blobdescriptor: inmemory
delete:
enabled: true
<your-s3-bucket>은 기존 버킷의 이름이어야 하며, 하위 디렉터리는 포함할 수 없습니다.
다운타임 없이 객체 스토리지로 마이그레이션#
AWS DataSync를 사용하여 레지스트리 데이터를 S3 버킷으로 또는 버킷 간에 복사하면, 버킷에 잘못된 메타데이터 객체가 생성됩니다.
자세한 내용은 이름이 비어 있는 태그를 참고하세요.
S3 버킷 간 데이터 이동에는 AWS CLI sync 작업을 권장합니다.
컨테이너 레지스트리를 중지하지 않고 스토리지를 마이그레이션하려면, 컨테이너 레지스트리를 읽기 전용 모드로 설정하세요. 대규모 인스턴스의 경우, 이 작업으로 인해 컨테이너 레지스트리가 한동안 읽기 전용 모드로 유지될 수 있습니다. 이 기간 동안 컨테이너 레지스트리에서 풀은 가능하지만 푸시는 불가능합니다.
-
선택 사항. 마이그레이션할 데이터 양을 줄이려면 다운타임 없이 가비지 컬렉션 도구를 실행하세요.
-
이 예제에서는
awsCLI를 사용합니다. CLI를 이전에 구성하지 않은 경우,sudo aws configure를 실행하여 자격 증명을 구성해야 합니다. 관리자가 아닌 사용자는 컨테이너 레지스트리 폴더에 접근하지 못할 수 있으므로,sudo를 사용하세요. 자격 증명 구성을 확인하려면ls를 실행하여 모든 버킷을 나열하세요.
sudo aws --endpoint-url <https://your-object-storage-backend.com> s3 ls
AWS를 백엔드로 사용하는 경우, --endpoint-url은 필요하지 않습니다.
sudo aws --endpoint-url <https://your-object-storage-backend.com> s3 sync registry s3://mybucket
데이터가 많은 경우, 병렬 동기화 작업을 실행하여 성능을 향상시킬 수 있습니다.
-
최종 데이터 동기화를 수행하려면, 컨테이너 레지스트리를
read-only모드로 설정하고 GitLab을 재구성하세요. -
초기 데이터 로드 이후 변경된 내용을 S3 버킷에 동기화하고, 소스에는 없지만 대상 버킷에 존재하는 파일을 삭제하세요:
sudo aws --endpoint-url <https://your-object-storage-backend.com> s3 sync registry s3://mybucket --delete --dryrun
명령이 예상대로 수행되는지 확인한 후, --dryrun 플래그를 제거하고 명령을 실행하세요.
--delete 플래그는 소스에는 없고 대상에 있는 파일을 삭제합니다. 소스와 대상을 바꾸면 Registry의 모든 데이터가 삭제됩니다.
- 이 두 명령에서 반환된 파일 수를 비교하여 모든 컨테이너 레지스트리 파일이 객체 스토리지에 업로드되었는지 확인하세요:
sudo find registry -type f | wc -l
sudo aws --endpoint-url <https://your-object-storage-backend.com> s3 ls s3://<mybucket> --recursive | wc -l
이 명령의 출력은 _uploads 디렉터리와 하위 디렉터리의 콘텐츠를 제외하고 일치해야 합니다.
-
S3 버킷을 스토리지로 사용하도록 레지스트리를 구성하세요.
-
변경 사항을 적용하려면, Registry를
read-write모드로 다시 설정하고 GitLab을 재구성하세요.
Azure 객체 스토리지로 이동#
Linux package (Omnibus)
registry['storage'] = {
'azure' => {
'accountname' => '<your_storage_account_name>',
'accountkey' => '<base64_encoded_account_key>',
'container' => '<container_name>',
'trimlegacyrootprefix' => true
}
}
Self-compiled (source)
storage:
azure:
accountname: <your_storage_account_name>
accountkey: <base64_encoded_account_key>
container: <container_name>
trimlegacyrootprefix: true
기본적으로 Azure Storage Driver는 core.windows.net realm을 사용합니다. azure 섹션에서 realm에 다른 값을 설정할 수 있습니다(예: Azure Government Cloud의 경우 core.usgovcloudapi.net).
스토리지 드라이버의 리다이렉트 비활성화#
기본적으로 원격 백엔드로 구성된 레지스트리에 접근하는 사용자는 스토리지 드라이버의 기본 백엔드로 리다이렉트됩니다. 예를 들어, s3 스토리지 드라이버를 사용하는 레지스트리는 GitLab 서버의 부하를 줄이기 위해 원격 S3 버킷으로 요청을 리다이렉트할 수 있습니다.
그러나 이 동작은 일반적으로 퍼블릭 서버에 접근할 수 없는 내부 호스트에서 사용하는 레지스트리에는 바람직하지 않습니다. 리다이렉트를 비활성화하고 프록시 다운로드를 사용하려면 다음과 같이 disable 플래그를 true로 설정하세요. 이렇게 하면 모든 트래픽이 항상 Registry 서비스를 통해 전달됩니다. 이는 보안이 향상(스토리지 백엔드가 공개적으로 접근할 수 없으므로 공격 표면이 줄어듦)되지만 성능은 저하(모든 트래픽이 서비스를 통해 리다이렉트됨)됩니다.
Linux package (Omnibus)
/etc/gitlab/gitlab.rb를 편집하세요:
registry['storage'] = {
's3' => {
'accesskey' => '<s3_access_key>',
'secretkey' => '<s3_secret_key_for_access_key>',
'bucket' => '<your_s3_bucket>',
'region' => '<your_s3_region>',
'regionendpoint' => '<your_s3_regionendpoint>'
},
'redirect' => {
'disable' => true
}
}
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
Self-compiled (source)
- 레지스트리 구성 YAML 파일에
redirect플래그를 추가하세요:
storage:
s3:
accesskey: '<s3_access_key>'
secretkey: '<s3_secret_key_for_access_key>'
bucket: '<your_s3_bucket>'
region: '<your_s3_region>'
regionendpoint: '<your_s3_regionendpoint>'
redirect:
disable: true
cache:
blobdescriptor: inmemory
delete:
enabled: true
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작하세요.
암호화된 S3 버킷#
SSE-S3 또는 SSE-KMS 암호화가 기본으로 활성화된 S3 버킷에 AWS KMS 서버 측 암호화를 사용할 수 있습니다. Customer master keys(CMK)와 SSE-C 암호화는 모든 요청에 암호화 키를 전송해야 하므로 지원되지 않습니다.
SSE-S3의 경우, 레지스트리 설정에서 encrypt 옵션을 활성화해야 합니다. 방법은 GitLab 설치 방법에 따라 다릅니다. 설치 방법에 맞는 지침을 따르세요.
Linux package (Omnibus)
/etc/gitlab/gitlab.rb를 편집하세요:
registry['storage'] = {
's3' => {
'accesskey' => '<s3_access_key>',
'secretkey' => '<s3_secret_key_for_access_key>',
'bucket' => '<your_s3_bucket>',
'region' => '<your_s3_region>',
'regionendpoint' => '<your_s3_regionendpoint>',
'encrypt' => true
}
}
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
Self-compiled (source)
- 레지스트리 구성 YAML 파일을 편집하세요:
storage:
s3:
accesskey: '<s3_access_key>'
secretkey: '<s3_secret_key_for_access_key>'
bucket: '<your_s3_bucket>'
region: '<your_s3_region>'
regionendpoint: '<your_s3_regionendpoint>'
encrypt: true
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작하세요.
스토리지 제한#
스토리지 제한이 없으므로, 사용자는 임의의 크기로 무한히 많은 Docker 이미지를 업로드할 수 있습니다. 이 설정은 향후 릴리스에서 구성 가능해질 예정입니다.
레지스트리 내부 포트 변경#
Registry 서버는 기본적으로 localhost의 포트 5000에서 수신하는데, 이는 Registry 서버가 연결을 수락해야 하는 주소입니다.
아래 예제에서는 Registry의 포트를 5010으로 설정합니다.
Linux package (Omnibus)
/etc/gitlab/gitlab.rb를 열고registry['registry_http_addr']를 설정하세요:
registry['registry_http_addr'] = "localhost:5010"
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
Self-compiled (source)
- Registry 서버의 구성 파일을 열고
http:addr값을 편집하세요:
http:
addr: localhost:5010
- 파일을 저장하고 Registry 서버를 재시작하세요.
프로젝트별 컨테이너 레지스트리 비활성화#
GitLab 인스턴스에서 Registry가 활성화되어 있지만 프로젝트에서 필요하지 않은 경우, 프로젝트 설정에서 비활성화할 수 있습니다.
GitLab을 인증 엔드포인트로 사용하는 외부 컨테이너 레지스트리#
GitLab에서 타사 컨테이너 레지스트리 사용은 GitLab 15.8에서 더 이상 사용되지 않게 되었으며, GitLab 16.0에서 지원이 종료되었습니다. 타사 컨테이너 레지스트리를 GitLab 컨테이너 레지스트리 대신 사용해야 하는 경우, 피드백 이슈 958에서 사용 사례를 알려주세요.
외부 컨테이너 레지스트리를 사용하는 경우, 컨테이너 레지스트리와 관련된 일부 기능을 사용할 수 없거나 고유한 위험이 있을 수 있습니다.
통합이 작동하려면 외부 레지스트리가 JSON Web Token을 사용하여 GitLab과 인증하도록 구성되어야 합니다. 외부 레지스트리의 런타임 구성에는 다음 항목이 포함되어야 합니다:
auth:
token:
realm: https://<gitlab.example.com>/jwt/auth
service: container_registry
issuer: gitlab-issuer
rootcertbundle: /root/certs/certbundle
이 항목이 없으면 레지스트리 로그인이 GitLab과 인증되지 않습니다.
GitLab도
registry.example.com/group/project/image-name:tag 또는
registry.example.com/group/project/my/image-name:tag와 같은 프로젝트 계층 아래의 중첩 이미지 이름을 인식하지 못하고, registry.example.com/group/project:tag만 인식합니다.
Linux 패키지 설치#
GitLab을 외부 컨테이너 레지스트리의 인증 엔드포인트로 사용할 수 있습니다.
/etc/gitlab/gitlab.rb를 열고 필요한 구성을 설정하세요:
gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_api_url'] = "https://<external_registry_host>:5000"
gitlab_rails['registry_issuer'] = "gitlab-issuer"
gitlab_rails['registry_enabled'] = true는 GitLab 컨테이너 레지스트리 기능과 인증 엔드포인트를 활성화하는 데 필요합니다. 이를 활성화해도 GitLab 번들 컨테이너 레지스트리 서비스는 시작되지 않습니다.
-
gitlab_rails['registry_api_url'] = "http://<external_registry_host>:5000"은 Registry가 설치된 호스트와 일치하도록 변경해야 합니다. 외부 레지스트리가 TLS를 사용하도록 구성된 경우https도 지정해야 합니다. -
GitLab과 외부 컨테이너 레지스트리가 안전하게 통신하려면 인증서-키 쌍이 필요합니다. 인증서-키 쌍을 생성하고, 외부 컨테이너 레지스트리에 공개 인증서(
rootcertbundle)를 구성하고, GitLab에 개인 키를 구성해야 합니다. 이를 위해/etc/gitlab/gitlab.rb에 다음을 추가하세요:
# registry['internal_key'] should contain the contents of the custom key
# file. Line breaks in the key file should be marked using `\n` character
# Example:
registry['internal_key'] = "---BEGIN RSA PRIVATE KEY---\nMIIEpQIBAA\n"
# Optionally define a custom file for a Linux package installation to write the contents
# of registry['internal_key'] to.
gitlab_rails['registry_key_path'] = "/custom/path/to/registry-key.key"
재구성이 실행될 때마다 registry_key_path에 지정된 파일이 internal_key에 지정된 내용으로 채워집니다. 파일이 지정되지 않으면 Linux 패키지 설치의 기본 경로는 /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key이며 자동으로 채워집니다.
- GitLab 컨테이너 레지스트리 페이지에 표시되는 컨테이너 레지스트리 URL을 변경하려면 다음 구성을 설정하세요:
gitlab_rails['registry_host'] = "<registry.gitlab.example.com>"
gitlab_rails['registry_port'] = "5005"
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
소스 직접 컴파일 설치#
/home/git/gitlab/config/gitlab.yml을 열고registry아래의 구성 설정을 편집하세요:
## Container registry
registry:
enabled: true
host: "<registry.gitlab.example.com>"
port: "5005"
api_url: "https://<external_registry_host>:5000"
path: /var/lib/registry
key: </path/to/keyfile>
issuer: gitlab-issuer
이 파라미터의 의미에 대해 자세히 읽어보세요.
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작하세요.
컨테이너 레지스트리 알림 구성#
히스토리
threshold는 GitLab 17.0에서 더 이상 사용되지 않게 되었지만, 이전 버전과의 호환성을 위해 여전히 사용 가능합니다.
컨테이너 레지스트리에서 발생하는 이벤트에 응답하여 웹훅 알림을 보내도록 컨테이너 레지스트리를 구성할 수 있습니다.
컨테이너 레지스트리 알림 구성 옵션에 대한 자세한 내용은 Docker Registry 알림 문서를 참고하세요.
threshold 파라미터는 GitLab 17.0에서 더 이상 사용되지 않게 되었지만, 이전 버전과의 호환성을 위해 여전히 사용 가능합니다. 이 파라미터는 향후 마일스톤에서 제거될 수 있습니다.
대신 maxretries를 사용하세요. 레지스트리는 구성된 backoff 기간을 기반으로 기존 threshold 구성을 동등한 maxretries 값으로 자동 변환하고, 변환된 값을 로그에 경고로 출력합니다.
기존 구성이 계속 작동하지만, 자동 변환을 피하기 위해 maxretries를 설정해야 합니다.
컨테이너 레지스트리에 여러 엔드포인트를 구성할 수 있습니다.
Linux package (Omnibus)
Linux 패키지 설치에서 알림 엔드포인트를 구성하려면:
/etc/gitlab/gitlab.rb를 편집하세요:
registry['notifications'] = [
{
'name' => '<test_endpoint>',
'url' => 'https://<gitlab.example.com>/api/v4/container_registry_event/events',
'timeout' => '500ms',
'threshold' => 5, # DEPRECATED: use `maxretries` instead.
'maxretries' => 5,
'backoff' => '1s',
'headers' => {
"Authorization" => [""]
}
}
]
gitlab_rails['registry_notification_secret'] = '' # Must match the auth token in registry['notifications']
을 문자로 시작하는 대소문자를 구분하는 영숫자 문자열로 교체하세요. < /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c 32 | sed "s/^[0-9]*//"; echo로 생성할 수 있습니다.
- 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성하세요.
Self-compiled (source)
알림 엔드포인트 구성은 Docker 레지스트리를 배포할 때 생성된 레지스트리 구성 YAML 파일에서 수행됩니다.
예제:
notifications:
endpoints:
- name: <alistener>
disabled: false
url: https://<my.listener.com>/event
headers: <http.Header>
timeout: 500
threshold: 5 # DEPRECATED: use `maxretries` instead.
maxretries: 5
backoff: 1000
정리 정책 실행#
사전 요구 사항:
- 컨테이너 레지스트리가 Sidekiq와 다른 노드에서 실행되는 분산 아키텍처를 사용하는 경우, 외부 Sidekiq를 사용할 때 컨테이너 레지스트리 구성 단계를 따르세요.
정리 정책을 생성한 후, 컨테이너 레지스트리 저장 공간을 줄이기 위해 즉시 실행할 수 있습니다. 예약된 정리를 기다릴 필요가 없습니다.
주어진 프로젝트에서 사용하는 컨테이너 레지스트리 디스크 공간을 줄이기 위해 관리자는 다음을 수행할 수 있습니다:
-
프로젝트별 디스크 공간 사용량 확인으로 정리가 필요한 프로젝트를 식별합니다.
-
GitLab Rails 콘솔을 사용하여 정리 정책을 실행하여 이미지 태그를 제거합니다.
-
가비지 컬렉션 실행으로 참조되지 않는 레이어와 태그 없는 매니페스트를 제거합니다.
프로젝트별 레지스트리 디스크 공간 사용량#
각 프로젝트에서 사용하는 디스크 공간을 확인하려면 GitLab Rails 콘솔에서 다음을 실행하세요:
projects_and_size = [["project_id", "creator_id", "registry_size_bytes", "project path"]]
# You need to specify the projects that you want to look through. You can get these in any manner.
projects = Project.last(100)
registry_metadata_database = ContainerRegistry::GitlabApiClient.supports_gitlab_api?
if registry_metadata_database
projects.each do |project|
size = project.container_repositories_size
if size > 0
projects_and_size << [project.project_id, project.creator&.id, size, project.full_path]
end
end
else
projects.each do |project|
project_layers = {}
project.container_repositories.each do |repository|
repository.tags.each do |tag|
tag.layers.each do |layer|
project_layers[layer.digest] ||= layer.size
end
end
end
total_size = project_layers.values.compact.sum
if total_size > 0
projects_and_size << [project.project_id, project.creator&.id, total_size, project.full_path]
end
end
end
# print it as comma separated output
projects_and_size.each do |ps|
puts "%s,%s,%s,%s" % ps
end
스크립트는 컨테이너 이미지 레이어를 기반으로 크기를 계산합니다. 레이어는 여러 프로젝트에서 공유될 수 있으므로 결과는 근사치이지만 프로젝트 간의 상대적 디스크 사용량을 잘 나타냅니다.
정리 정책을 실행하여 이미지 태그를 제거하려면 GitLab Rails 콘솔에서 다음 명령을 실행하세요:
# Numeric ID of the project whose container registry should be cleaned up
P = <project_id>
# Numeric ID of a user with Developer, Maintainer, or Owner role for the project
U = <user_id>
# Get required details / objects
user = User.find_by_id(U)
project = Project.find_by_id(P)
policy = ContainerExpirationPolicy.find_by(project_id: P)
# Loop through each container repository
project.container_repositories.find_each do |repo|
puts repo.attributes
# Start the tag cleanup
puts Projects::ContainerRepository::CleanupTagsService.new(container_repository: repo, current_user: user, params: policy.attributes.except("created_at", "updated_at")).execute
end
예약에 따라 정리를 실행할 수도 있습니다.
모든 프로젝트에 인스턴스 전체 정리 정책을 활성화하려면, 컨테이너 레지스트리가 있지만 정리 정책이 비활성화된 모든 프로젝트를 찾아야 합니다:
# Find all projects where Container registry is enabled, and cleanup policies disabled
projects = Project.find_by_sql ("SELECT * FROM projects WHERE id IN (SELECT project_id FROM container_expiration_policies WHERE enabled=false AND id IN (SELECT project_id FROM container_repositories))")
# Loop through each project
projects.each do |p|
# Print project IDs and project full names
puts "#{p.id},#{p.full_name}"
end
컨테이너 레지스트리 메타데이터 데이터베이스#
Offering: GitLab Self-Managed
히스토리
- GitLab 17.3에서 일반적으로 사용 가능해짐.
메타데이터 데이터베이스는 온라인 가비지 컬렉션을 포함한 많은 새 레지스트리 기능을 활성화하고, 여러 레지스트리 작업의 효율성을 높입니다. 자세한 내용은 컨테이너 레지스트리 메타데이터 데이터베이스 페이지를 참고하세요.
컨테이너 레지스트리 가비지 컬렉션#
사전 요구 사항:
- Linux 패키지 또는 GitLab Helm 차트를 사용하여 GitLab을 설치해야 합니다.
Amazon S3 Lifecycle과 같은 객체 스토리지 공급자의 보존 정책으로 인해 객체가 제대로 삭제되지 않을 수 있습니다.
컨테이너 레지스트리는 상당한 양의 스토리지 공간을 사용할 수 있으므로, 스토리지 사용량을 줄이는 방법을 고려할 수 있습니다. 나열된 옵션 중 태그 삭제가 가장 효과적입니다. 그러나 태그 삭제만으로는 이미지 레이어가 삭제되지 않으며, 기본 이미지 매니페스트만 태그 없이 남아 있습니다.
보다 효과적으로 공간을 확보하기 위해, 컨테이너 레지스트리에는 참조되지 않는 레이어와 (선택적으로) 태그 없는 매니페스트를 삭제할 수 있는 가비지 컬렉터가 있습니다.
가비지 컬렉터를 시작하려면 다음 gitlab-ctl 명령을 실행하세요:
sudo gitlab-ctl registry-garbage-collect
가비지 컬렉션을 수행하는 데 걸리는 시간은 컨테이너 레지스트리 데이터 크기에 비례합니다.
registry-garbage-collect 명령은 가비지 컬렉션 전에 컨테이너 레지스트리를 종료하고, 가비지 컬렉션이 완료된 후에만 다시 시작합니다. 다운타임을 피하려면, 컨테이너 레지스트리를 수동으로 읽기 전용 모드로 설정하고 gitlab-ctl을 우회할 수 있습니다.
이 명령은 레거시 메타데이터가 사용 중인 경우에만 진행됩니다. 컨테이너 레지스트리 메타데이터 데이터베이스가 활성화된 경우에는 이 명령이 진행되지 않습니다.
콘텐츠 주소 지정 가능 레이어 이해#
다음 예제를 고려하세요. 먼저 이미지를 빌드합니다:
# This builds an image with content of sha256:<111111...>
docker build -t <my.registry.com>/<my.group>/<my.project>:latest .
docker push <my.registry.com>/<my.group>/<my.project>:latest
이제 latest를 새 버전으로 덮어씁니다:
# This builds a image with content of sha256:<222222...>
docker build -t <my.registry.com>/<my.group>/<my.project>:latest .
docker push <my.registry.com>/<my.group>/<my.project>:latest
이제 latest 태그는 sha256:<222222...>의 매니페스트를 가리킵니다.
레지스트리 아키텍처상, 이 데이터는 <my.registry.com>/<my.group>/<my.project>@sha256:<111111...> 이미지를 풀할 때 여전히 접근 가능하지만, latest 태그를 통해 직접 접근할 수는 없습니다.
참조되지 않는 레이어 제거#
이미지 레이어는 컨테이너 레지스트리 스토리지의 대부분을 차지합니다. 레이어는 이미지 매니페스트가 참조하지 않을 때 참조되지 않는 것으로 간주됩니다. 참조되지 않는 레이어는 컨테이너 레지스트리 가비지 컬렉터의 기본 타깃입니다.
구성 파일의 기본 위치를 변경하지 않은 경우 다음을 실행하세요:
sudo gitlab-ctl registry-garbage-collect
컨테이너 레지스트리 config.yml의 위치를 변경한 경우:
sudo gitlab-ctl registry-garbage-collect /path/to/config.yml
추가 공간을 확보하기 위해 모든 태그 없는 매니페스트와 참조되지 않는 레이어를 제거할 수도 있습니다.
태그 없는 매니페스트 및 참조되지 않는 레이어 제거#
기본적으로 컨테이너 레지스트리 가비지 컬렉터는 태그 없는 이미지를 무시하며, 사용자는 다이제스트로 태그 없는 이미지를 계속 풀할 수 있습니다. 사용자는 향후 이미지를 다시 태그하여 GitLab UI 및 API에서 다시 표시할 수도 있습니다.
태그 없는 이미지와 이러한 이미지만 참조하는 레이어가 필요하지 않은 경우, 모두 삭제할 수 있습니다. registry-garbage-collect 명령에 -m 플래그를 사용하세요:
sudo gitlab-ctl registry-garbage-collect -m
태그 없는 이미지 삭제가 확실하지 않으면 진행하기 전에 레지스트리 데이터를 백업하세요.
다운타임 없이 가비지 컬렉션 수행#
컨테이너 레지스트리를 온라인 상태로 유지하면서 가비지 컬렉션을 수행하려면, 레지스트리를 읽기 전용 모드로 설정하고 내장된 gitlab-ctl registry-garbage-collect 명령을 우회하세요.
컨테이너 레지스트리가 읽기 전용 모드인 동안 이미지를 풀할 수 있지만 푸시할 수는 없습니다. 컨테이너 레지스트리는 가비지 컬렉션의 전체 기간 동안 읽기 전용 모드로 유지해야 합니다.
기본적으로 레지스트리 스토리지 경로는 /var/opt/gitlab/gitlab-rails/shared/registry입니다.
읽기 전용 모드를 활성화하려면:
/etc/gitlab/gitlab.rb에서 읽기 전용 모드를 지정하세요:
registry['storage'] = {
'filesystem' => {
'rootdirectory' => "<your_registry_storage_path>"
},
'maintenance' => {
'readonly' => {
'enabled' => true
}
}
}
- GitLab을 저장하고 재구성하세요:
sudo gitlab-ctl reconfigure
이 명령은 컨테이너 레지스트리를 읽기 전용 모드로 설정합니다.
- 다음으로, 가비지 컬렉션 명령 중 하나를 트리거하세요:
# Remove unreferenced layers
sudo /opt/gitlab/embedded/bin/registry garbage-collect /var/opt/gitlab/registry/config.yml
# Remove untagged manifests and unreferenced layers
sudo /opt/gitlab/embedded/bin/registry garbage-collect -m /var/opt/gitlab/registry/config.yml
이 명령은 가비지 컬렉션을 시작합니다. 완료 시간은 레지스트리 데이터 크기에 비례합니다.
- 완료 후
/etc/gitlab/gitlab.rb에서 읽기-쓰기 모드로 다시 변경하세요:
registry['storage'] = {
'filesystem' => {
'rootdirectory' => "<your_registry_storage_path>"
},
'maintenance' => {
'readonly' => {
'enabled' => false
}
}
}
- GitLab을 저장하고 재구성하세요:
sudo gitlab-ctl reconfigure
스케줄에 따라 가비지 컬렉션 실행#
이상적으로는 레지스트리가 사용되지 않는 시간대에 매주 정기적으로 가비지 컬렉션을 실행하는 것이 좋습니다. 가장 간단한 방법은 주기적으로 매주 한 번 실행되는 새 crontab job을 추가하는 것입니다.
/etc/cron.d/registry-garbage-collect 아래에 파일을 생성하세요:
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Run every Sunday at 04:05am
5 4 * * 0 root gitlab-ctl registry-garbage-collect
태그 없는 매니페스트와 참조되지 않는 레이어를 제거하기 위해 -m 플래그를 추가할 수도 있습니다.
가비지 컬렉션 중지#
가비지 컬렉션을 중지하려는 경우, 다운타임 없이 가비지 컬렉션 수행에 설명된 대로 수동으로 가비지 컬렉션을 실행해야 합니다. 그런 다음 Control+C를 눌러 가비지 컬렉션을 중지할 수 있습니다.
그렇지 않으면 gitlab-ctl을 중단하면 레지스트리 서비스가 다운 상태로 남을 수 있습니다. 이 경우, gitlab-ctl 명령이 레지스트리 서비스를 다시 가동시킬 수 있도록 시스템에서 가비지 컬렉션 프로세스 자체를 찾아야 합니다.
또한, 프로세스의 mark 단계 중에는 진행 상황이나 결과를 저장할 방법이 없습니다. blob 삭제가 시작된 후에야 영구적인 작업이 수행됩니다.
지속적인 무중단 가비지 컬렉션#
메타데이터 데이터베이스로 마이그레이션하면, 예약하거나 읽기 전용 모드가 필요 없이 백그라운드에서 가비지 컬렉션을 실행할 수 있습니다.
컴포넌트별 확장#
이 섹션에서는 레지스트리 트래픽이 컴포넌트별로 증가함에 따라 발생할 수 있는 잠재적 성능 병목 지점을 설명합니다. 각 하위 섹션은 소규모에서 대규모 레지스트리 워크로드에 이르기까지 혜택을 주는 권장 사항을 대략적인 순서로 나열합니다. 레지스트리는 참조 아키텍처에 포함되어 있지 않으며, 시트 수나 초당 요청 수를 타깃으로 하는 확장 가이드도 없습니다.
데이터베이스#
-
별도 데이터베이스로 이동: 데이터베이스 부하가 증가함에 따라, 레지스트리 메타데이터 데이터베이스를 별도의 물리적 데이터베이스로 이동하여 수직으로 확장합니다. 별도 데이터베이스는 레지스트리가 생성하는 트래픽을 분리하면서 레지스트리 데이터베이스에 사용 가능한 리소스를 늘릴 수 있습니다.
-
HA PostgreSQL 타사 솔루션으로 이동: Praefect와 유사하게, 신뢰할 수 있는 공급자나 솔루션으로 이동하면 HA가 가능하고 다중 노드 레지스트리 배포에 적합합니다. 레지스트리가 기본 Postgres 파티셔닝, 트리거, 함수를 많이 사용하므로, 이를 지원하는 공급자를 선택해야 합니다.
레지스트리 서버#
-
별도 노드로 이동: 별도 노드는 컨테이너 레지스트리 서버 프로세스에 사용 가능한 리소스를 늘리기 위해 수직으로 확장하는 방법 중 하나입니다.
-
로드 밸런서 뒤에 여러 레지스트리 노드 실행: 레지스트리는 단일 대형 노드로 많은 트래픽을 처리할 수 있지만, 일반적으로 여러 배포를 통해 수평으로 확장하도록 설계되어 있습니다. 여러 소형 노드를 구성하면 자동 확장과 같은 기술도 활성화됩니다.
Redis 캐시#
Redis 캐시를 활성화하면 성능이 향상되며, 리포지터리 이름 변경과 같은 기능도 활성화됩니다.
-
Redis 서버: 단일 Redis 인스턴스가 지원되며, Redis 캐싱의 이점을 활용하는 가장 간단한 방법입니다.
-
Redis Sentinel: Redis Sentinel도 지원되어 캐시를 HA로 만들 수 있습니다.
-
Redis Cluster: 배포가 성장함에 따라 추가 확장을 위해 Redis Cluster도 사용할 수 있습니다.
스토리지#
-
로컬 파일 시스템: 로컬 파일 시스템이 기본값이며 비교적 성능이 좋지만, 다중 노드 배포나 대량의 레지스트리 데이터에는 적합하지 않습니다.
-
객체 스토리지: 객체 스토리지 사용으로 더 많은 레지스트리 데이터를 실용적으로 저장할 수 있습니다. 객체 스토리지는 다중 노드 레지스트리 배포에도 적합합니다.
온라인 가비지 컬렉션#
-
기본값 조정: 온라인 가비지 컬렉션이 검토 큐를 안정적으로 지우지 않는 경우,
gc구성 섹션의manifests및blobs섹션 아래의interval설정을 조정할 수 있습니다. 기본값은5s이며, 예를 들어500ms와 같이 밀리초로도 구성할 수 있습니다. -
레지스트리 서버로 수평 확장: 다중 노드 배포로 레지스트리 애플리케이션을 수평 확장하는 경우, 온라인 가비지 컬렉션은 구성 변경 없이 자동으로 확장됩니다.
별도 노드에서 GitLab과 레지스트리 구성 (Linux 패키지 설치)#
기본적으로 GitLab 패키지는 두 서비스가 동일한 노드에서 실행된다고 가정합니다. 별도의 노드에서 실행하려면 별도의 구성이 필요합니다.
구성 옵션#
다음 구성 옵션은 해당 노드의 /etc/gitlab/gitlab.rb에 설정해야 합니다.
레지스트리 노드 설정#
| 옵션 | 설명 |
|---|---|
| registry['registry_http_addr'] | 레지스트리가 수신하는 네트워크 주소 및 포트. 웹 서버 또는 로드 밸런서에서 접근 가능해야 합니다. 기본값: 프로그래밍 방식으로 설정됨. |
| registry['token_realm'] | 인증 엔드포인트 URL, 일반적으로 GitLab 인스턴스 URL. 사용자가 접근 가능해야 합니다. 기본값: 프로그래밍 방식으로 설정됨. |
| registry['http_secret'] | 클라이언트 측 변조로부터 보호하는 데 사용되는 보안 토큰. 임의 문자열로 생성됩니다. |
| registry['internal_key'] | 레지스트리 서버에서 생성되지만 GitLab에서 사용하는 토큰 서명 키. 기본값: 자동 생성됨. |
| registry['internal_certificate'] | 토큰 서명용 인증서. 기본값: 자동 생성됨. |
| registry['rootcertbundle'] | internal_certificate가 저장되는 파일 경로. 기본값: 프로그래밍 방식으로 설정됨. |
| registry['health_storagedriver_enabled'] | 스토리지 드라이버의 상태 모니터링을 활성화합니다. 기본값: 프로그래밍 방식으로 설정됨. |
| gitlab_rails['registry_key_path'] | internal_key가 저장되는 파일 경로. 기본값: 프로그래밍 방식으로 설정됨. |
| gitlab_rails['registry_issuer'] | 토큰 발급자 이름. 레지스트리와 GitLab 구성 간에 일치해야 합니다. 기본값: 프로그래밍 방식으로 설정됨. |
컨테이너 레지스트리에서 Amazon S3 서명 버전 2를 사용하여 요청을 인증하는 기능은 GitLab 17.8에서 더 이상 사용되지 않게 되었으며 19.0에서 제거될 예정입니다. 대신 서명 버전 4를 사용하세요. 이는 주요 변경 사항입니다. 자세한 내용은 이슈 1449를 참고하세요.
GitLab 노드 설정#
| 옵션 | 설명 |
|---|---|
| gitlab_rails['registry_enabled'] | GitLab 레지스트리 API 통합을 활성화합니다. true로 설정해야 합니다. |
| gitlab_rails['registry_api_url'] | GitLab에서 사용하는 내부 레지스트리 URL(사용자에게 표시되지 않음). 스키마와 함께 registry['registry_http_addr']를 사용합니다. 기본값: 프로그래밍 방식으로 설정됨. |
| gitlab_rails['registry_host'] | 스키마 없는 공개 레지스트리 호스트명(예: registry.gitlab.example). 사용자에게 표시됩니다. |
| gitlab_rails['registry_port'] | 사용자에게 표시되는 공개 레지스트리 포트 번호. |
| gitlab_rails['registry_issuer'] | 레지스트리 구성과 일치해야 하는 토큰 발급자 이름. |
| gitlab_rails['registry_key_path'] | 레지스트리에서 사용하는 인증서 키 파일 경로. |
| gitlab_rails['internal_key'] | GitLab에서 사용하는 토큰 서명 키 내용. |
노드 설정#
GitLab과 컨테이너 레지스트리를 별도 노드에 구성하려면:
- 레지스트리 노드에서
/etc/gitlab/gitlab.rb를 다음 설정으로 편집하세요:
# Registry server details
# - IP address: 10.30.227.194
# - Domain: registry.example.com
# Disable unneeded services
gitlab_workhorse['enable'] = false
puma['enable'] = false
sidekiq['enable'] = false
postgresql['enable'] = false
redis['enable'] = false
gitlab_kas['enable'] = false
gitaly['enable'] = false
nginx['enable'] = false
# Configure registry settings
registry['enable'] = true
registry['registry_http_addr'] = '0.0.0.0:5000'
registry['token_realm'] = 'https://<gitlab.example.com>'
registry['http_secret'] = '<6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b>'
# Configure GitLab Rails settings
gitlab_rails['registry_issuer'] = 'omnibus-gitlab-issuer'
gitlab_rails['registry_key_path'] = '/etc/gitlab/gitlab-registry.key'
- GitLab 노드에서
/etc/gitlab/gitlab.rb를 다음 설정으로 편집하세요:
# GitLab server details
# - IP address: 10.30.227.149
# - Domain: gitlab.example.com
# Configure GitLab URL
external_url 'https://<gitlab.example.com>'
# Configure registry settings
gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_api_url'] = '<http://10.30.227.194:5000>'
gitlab_rails['registry_host'] = '<registry.example.com>'
gitlab_rails['registry_port'] = 5000
gitlab_rails['registry_issuer'] = 'omnibus-gitlab-issuer'
gitlab_rails['registry_key_path'] = '/etc/gitlab/gitlab-registry.key'
- 두 노드 간에
/etc/gitlab/gitlab-secrets.json파일을 동기화하세요:
GitLab 노드에서 레지스트리 노드로 파일을 복사하세요.
-
파일 권한이 올바른지 확인하세요.
-
두 노드 모두에서
sudo gitlab-ctl reconfigure를 실행하세요.
컨테이너 레지스트리 아키텍처#
사용자는 컨테이너 레지스트리에 자체 Docker 이미지를 저장할 수 있습니다. 레지스트리는 클라이언트를 대상으로 하므로, 웹 서버 또는 로드 밸런서(LB)에 직접 노출됩니다.
%%{init: { "fontFamily": "GitLab Sans" }}%% flowchart LR accTitle: Container registry authentication flow accDescr: Shows how users authenticate with the container registry with GitLab API to push and pull Docker images
A[User] --->|1: Docker loginon port 443| C{Frontend loadbalancer}
C --->|2: connection attemptwithout token fails| D[Container registry]
C --->|5: connect with token succeeds| D[Container registry]
C --->|3: Dockerrequests token| E[API frontend]
E --->|4:API returnssigned token| C
linkStyle 1 stroke-width:4px,stroke:red
linkStyle 2 stroke-width:4px,stroke:green
인증 흐름에는 다음 단계가 포함됩니다:
-
사용자가 클라이언트에서
docker login registry.gitlab.example을 실행합니다. 이 요청은 포트 443의 웹 서버(또는 LB)에 도달합니다. -
웹 서버가 레지스트리 백엔드 풀(기본적으로 포트 5000)에 연결됩니다. 사용자에게 유효한 토큰이 없으므로 레지스트리는
401 UnauthorizedHTTP 코드와 토큰을 얻을 수 있는 URL을 반환합니다. URL은 레지스트리 구성의token_realm설정으로 정의되며 GitLab API를 가리킵니다. -
Docker 클라이언트가 GitLab API에 연결하여 토큰을 얻습니다.
-
API가 레지스트리 키로 토큰에 서명하고 Docker 클라이언트에 전송합니다.
-
Docker 클라이언트가 API에서 받은 토큰으로 다시 로그인합니다. 인증된 클라이언트는 이제 Docker 이미지를 푸시하고 풀할 수 있습니다.
참조: https://distribution.github.io/distribution/spec/auth/token/
GitLab과 컨테이너 레지스트리 간의 통신#
컨테이너 레지스트리는 내부적으로 사용자를 인증할 수 없으므로, GitLab을 통해 자격 증명을 검증합니다. 레지스트리와 GitLab 간의 연결은 TLS로 암호화됩니다.
GitLab은 개인 키를 사용하여 토큰에 서명하고, 레지스트리는 인증서에서 제공한 공개 키를 사용하여 서명을 검증합니다.
기본적으로 모든 설치에 대해 자체 서명 인증서 키 쌍이 생성됩니다. 레지스트리 구성의 internal_key 설정을 사용하여 이 동작을 재정의할 수 있습니다.
다음 단계는 통신 흐름을 설명합니다:
-
GitLab은 레지스트리의 개인 키를 사용하여 레지스트리와 상호 작용합니다. 레지스트리 요청이 전송될 때, 단기(10분), 네임스페이스 제한 토큰이 생성되고 개인 키로 서명됩니다.
-
레지스트리는 서명이 구성에 지정된 레지스트리 인증서와 일치하는지 확인하고 작업을 허용합니다.
-
GitLab은 Sidekiq를 통해 백그라운드 job을 처리하며, 이 job도 레지스트리와 상호 작용합니다. 이러한 job은 이미지 삭제를 처리하기 위해 레지스트리와 직접 통신합니다.
타사 레지스트리에서 마이그레이션#
GitLab에서 외부 컨테이너 레지스트리 사용은 GitLab 15.8에서 더 이상 사용되지 않게 되었으며 GitLab 16.0에서 지원이 종료되었습니다. 자세한 내용은 지원 중단 공지를 참고하세요.
통합은 GitLab 16.0에서 비활성화되지 않았지만, 더 이상 문제 디버그 및 수정에 대한 지원을 제공하지 않습니다. 또한 통합은 더 이상 개발되거나 새 기능으로 향상되지 않습니다. 타사 레지스트리 기능은 GitLab Self-Managed에서 새 GitLab 컨테이너 레지스트리 버전이 사용 가능해진 후 완전히 제거될 수 있습니다(에픽 5521 참조). GitLab 컨테이너 레지스트리만 지원될 예정입니다.
이 섹션에서는 타사 레지스트리에서 GitLab 컨테이너 레지스트리로 마이그레이션하는 관리자를 위한 지침을 제공합니다. 여기에 나열되지 않은 타사 컨테이너 레지스트리를 사용하는 경우, 피드백 이슈에서 사용 사례를 설명할 수 있습니다.
아래 제공된 모든 지침은 먼저 테스트 환경에서 시도해야 합니다. 프로덕션에서 복제하기 전에 모든 것이 예상대로 계속 작동하는지 확인하세요.
Docker Distribution Registry#
Docker Distribution Registry는 CNCF에 기증되었으며 이제 Distribution Registry로 알려져 있습니다. 이 레지스트리는 GitLab 컨테이너 레지스트리의 기반이 되는 오픈 소스 구현입니다. GitLab 컨테이너 레지스트리는 지원되는 모든 스토리지 백엔드를 포함하여 Distribution Registry에서 제공하는 기본 기능과 호환됩니다. GitLab 컨테이너 레지스트리로 마이그레이션하려면 이 페이지의 지침을 따르고 Distribution Registry와 동일한 스토리지 백엔드를 사용할 수 있습니다. GitLab 컨테이너 레지스트리는 Distribution Registry에 사용하는 것과 동일한 구성을 수락해야 합니다.
컨테이너 이미지 삭제 최대 재시도 횟수#
- GitLab 17.6에서 일반적으로 사용 가능해짐. 기능 플래그
set_delete_failed_container_repository제거됨.
컨테이너 이미지를 삭제할 때 오류가 발생할 수 있으므로, 오류가 일시적인 문제인지 확인하기 위해 삭제를 재시도합니다. 삭제는 최대 10회 재시도되며, 재시도 간에 백오프 지연이 있습니다. 이 지연은 재시도 간에 일시적인 오류가 해결될 시간을 더 많이 줍니다.
최대 재시도 횟수를 설정하면 재시도 사이에 해결되지 않은 영구적인 오류가 있는지 감지하는 데도 도움이 됩니다. 최대 재시도 횟수만큼 삭제에 실패하면 컨테이너 리포지터리 status가 delete_failed로 설정됩니다. 이 상태에서는 리포지터리가 더 이상 삭제를 재시도하지 않습니다.
delete_failed 상태의 컨테이너 리포지터리를 조사하고 문제를 해결해야 합니다. 문제가 해결된 후, 이미지 삭제를 다시 시작할 수 있도록 리포지터리 상태를 delete_scheduled로 다시 설정할 수 있습니다. Rails 콘솔에서 리포지터리 상태를 업데이트하려면:
container_repository = ContainerRepository.find(<id>)
container_repository.update(status: 'delete_scheduled')