컨테이너 레지스트리 메타데이터 데이터베이스
GitLab v19.5Offering: GitLab Self-Managed
요약
메타데이터 데이터베이스는 컨테이너 레지스트리에 성능을 개선하고 새 기능을 추가하는 여러 개선 사항을 제공합니다. 기본적으로 컨테이너 레지스트리는 오브젝트 스토리지 또는 로컬 파일 시스템을 사용하여 컨테이너 이미지와 관련된 메타데이터를 유지합니다.
히스토리
- GitLab 17.3에서 일반적으로 사용 가능합니다.
- 새 Linux 패키지 및 소스 컴파일 설치에 대한 prefer 모드가 GitLab 19.0에서 도입되었습니다. 기본적으로 활성화됩니다.
메타데이터 데이터베이스는 컨테이너 레지스트리에 성능을 개선하고 새 기능을 추가하는 여러 개선 사항을 제공합니다.
기본적으로 컨테이너 레지스트리는 오브젝트 스토리지 또는 로컬 파일 시스템을 사용하여 컨테이너 이미지와 관련된 메타데이터를 유지합니다. 이 메타데이터 저장 방식은 특히 태그를 나열할 때처럼 여러 이미지에 걸친 데이터를 얼마나 효율적으로 액세스할 수 있는지를 제한합니다. 데이터베이스를 사용하여 이 데이터를 저장하면 온라인 가비지 컬렉션을 포함해 제로 다운타임으로 오래된 데이터를 자동으로 제거하는 등 많은 새 기능이 가능해집니다.
이 데이터베이스는 레지스트리가 이미 사용하는 스토리지와 함께 작동하지만 오브젝트 스토리지나 파일 시스템을 대체하지는 않습니다. 메타데이터 데이터베이스로 메타데이터 가져오기를 수행한 후에도 스토리지 솔루션을 계속 유지해야 합니다.
Helm Charts 설치의 경우, Helm Charts 문서에서 컨테이너 레지스트리 메타데이터 데이터베이스 관리를 참고합니다.
개선 사항#
메타데이터 데이터베이스 아키텍처는 레거시 메타데이터 스토리지로는 사용할 수 없는 성능 개선, 버그 수정, 새 기능을 지원합니다. 이러한 개선 사항에는 다음이 포함됩니다:
- 자동 온라인 가비지 컬렉션
- 리포지터리, 프로젝트, 그룹에 대한 스토리지 사용량 가시성
- 이미지 서명
- 리포지터리 이동 및 이름 변경
- 보호된 태그
- 정리 정책에 대한 성능 개선으로 대규모 리포지터리도 정리 가능
- 리포지터리 태그 나열 성능 개선
- 태그 게시 타임스탬프 추적 및 표시(이슈 290949 참고)
- 이름 외의 추가 속성으로 리포지터리 태그 정렬
레거시 메타데이터 스토리지의 기술적 제약으로 인해 새 기능은 메타데이터 데이터베이스 버전에서만 구현됩니다. 보안과 관련이 없는 버그 수정은 메타데이터 데이터베이스 버전으로 제한될 수 있습니다.
알려진 제한 사항#
- 기존 레지스트리의 메타데이터 가져오기에는 읽기 전용 시간이 필요합니다.
- 18.3 이전에는 버전을 업그레이드할 때 레지스트리의 일반 스키마 및 배포 후 데이터베이스 마이그레이션을 수동으로 실행해야 합니다.
- 멀티 노드 Linux 패키지 환경에서는 업그레이드 중 레지스트리 제로 다운타임이 보장되지 않습니다.
- 기존 레지스트리의 메타데이터 가져오기 중에는 이미지 태그의
createdAt및publishedAt타임스탬프 값이 가져오기 날짜로 설정됩니다. 이는 일관성을 보장하기 위한 의도적인 동작으로, 레거시 레지스트리는 모든 이미지에 대한 태그 게시 날짜를 수집하지 않기 때문입니다. 일부 이미지에는 메타데이터에 빌드 날짜가 있지만 많은 이미지에는 없습니다. 자세한 내용은 이슈 1384를 참고합니다.
메타데이터 데이터베이스 기능 지원#
기존 레지스트리에서 메타데이터 데이터베이스로 메타데이터를 가져와 온라인 가비지 컬렉션을 사용할 수 있습니다.
일부 데이터베이스 활성화 기능은 GitLab.com에서만 활성화되며, 레지스트리 데이터베이스의 자동 데이터베이스 프로비저닝은 사용할 수 없습니다. 컨테이너 레지스트리 데이터베이스와 관련된 기능 상태는 피드백 이슈의 기능 지원 표를 참고합니다.
데이터베이스 요구 사항#
컨테이너 레지스트리는 메타데이터 데이터베이스에 직접 연결하여 그에 대해 읽기-쓰기 트랜잭션을 실행합니다.
기본적으로 GitLab 18.3 이상은 기본 GitLab 데이터베이스 내에 레지스트리 메타데이터용 논리 데이터베이스를 사전 프로비저닝합니다. 이 데이터베이스는 이미 아래 요구 사항을 충족하므로, 대부분의 설치에는 추가 데이터베이스 설정이 필요하지 않습니다. 레지스트리에 외부 데이터베이스를 사용하는 경우에만 다음 요구 사항을 직접 충족해야 합니다:
- 지원되는 PostgreSQL 버전을 실행합니다. 레지스트리는 시작 시 버전을 확인하며 지원되지 않는 버전에서는 시작하지 않습니다. 지원되는 버전은 PostgreSQL 요구 사항을 참고합니다.
- 레지스트리 전용 데이터베이스를 사용합니다. 데이터베이스와 사용자를 만드는 방법은 컨테이너 레지스트리 메타데이터 데이터베이스 구성을 참고합니다.
- PostgreSQL 확장은 추가하지 않습니다. 메타데이터 데이터베이스에는 확장이 필요하지 않으므로 기본 GitLab 데이터베이스의 확장 목록을 복사하지 않습니다.
- 읽기-쓰기 액세스를 허용합니다. 레지스트리는 읽기 전용 복제본에서는 시작되지 않습니다.
bytea_output은 PostgreSQL 기본값인hex로 유지합니다. 레지스트리는 일부 바이너리 칼럼을 16진수 텍스트로 읽으므로, 서버나 역할이bytea_output = escape로 설정되어 있으면 가져오기가invalid hex format오류로 실패합니다. 자세한 내용은 오류:convert field 8 failed: invalid hex format를 참고합니다.
레지스트리 사용자가 데이터베이스를 소유해야 하며, 그렇지 않으면 마이그레이션이 권한
오류로 실패합니다. 자세한 내용은
오류: permission denied for schema public를 참고합니다.
TLS로 연결을 암호화하는 것은 선택 사항입니다. 연결을 암호화하려면 예시 구성처럼 sslmode를
require로 설정합니다. 서버
인증서까지 확인하려면 sslrootcert에 CA 인증서를 지정하고 verify-full을 사용합니다.
Linux 패키지 설치에 메타데이터 데이터베이스 활성화#
사전 요구 사항:
- GitLab 17.5가 최소 요구 버전이지만, 추가 개선 사항과 더 쉬운 구성으로 인해 GitLab 18.3 이상을 권장합니다.
- 데이터베이스 요구 사항을 충족하는 PostgreSQL 데이터베이스. 레지스트리 노드에서 액세스할 수 있어야 합니다.
- 외부 데이터베이스를 사용하는 경우 먼저 외부 데이터베이스 연결을 설정해야 합니다. 자세한 내용은 외부 데이터베이스 사용을 참고합니다.
시작하기 전에#
- 데이터베이스를 활성화한 후에는 계속 사용해야 합니다. 이제 데이터베이스가 레지스트리 메타데이터의 소스이며, 이 시점 이후 비활성화하면 데이터베이스가 활성화된 동안 작성된 모든 이미지에 대한 레지스트리의 가시성이 사라집니다.
- 오프라인 가비지 컬렉션은 더 이상 필요하지 않습니다. 데이터베이스가 활성화되면 GitLab에 포함된 가비지 컬렉션 명령은 안전하게 종료되지만, 업스트림 레지스트리에서 제공하는 명령 같은 서드파티 명령은 태그가 지정된 이미지와 관련된 데이터를 삭제합니다.
- 특히 서드파티 명령으로 오프라인 가비지 컬렉션을 자동화하지 않았는지 확인합니다.
- 프로세스를 가속화하기 위해 먼저 레지스트리 스토리지를 줄일 수 있습니다.
- 가능하면 컨테이너 레지스트리 데이터를 백업 합니다.
- 컨테이너 레지스트리 알림을 구성합니다.
- Usage quotas 페이지에 컨테이너 레지스트리 사용량 통계를 표시하려면 알림을 구성해야 합니다.
새 설치에 데이터베이스 활성화#
컨테이너 레지스트리에 데이터를 작성한 적이 없는 설치라면 가져오기가 필요하지 않습니다. 레지스트리에 데이터를 작성하기 전에 데이터베이스만 활성화하면 됩니다.
자세한 내용은 새 설치 지침을 참고합니다.
기존 레지스트리에 데이터베이스 활성화#
기존 컨테이너 레지스트리 메타데이터는 1단계 가져오기 방법이나 3단계 가져오기 방법으로 가져올 수 있습니다. 가져오기 기간에 영향을 미치는 몇 가지 요소가 있습니다:
- 레지스트리의 태그가 지정된 이미지 수.
- 기존 레지스트리 데이터의 크기.
- PostgreSQL 인스턴스의 사양.
- 실행 중인 레지스트리 인스턴스 수.
- 레지스트리, PostgreSQL, 구성된 스토리지 간의 네트워크 지연.
가져오기 전에 준비 단계로 다음을 수행할 필요가 없습니다:
- 추가 오브젝트 스토리지 또는 파일 시스템 공간 할당: 가져오기는 이 스토리지에 상당한 쓰기를 하지 않습니다.
- 오프라인 가비지 컬렉션 실행: 해롭지는 않지만, 오프라인 가비지 컬렉션은 이 명령을 실행하는 데 드는 시간을 상쇄할 만큼 가져오기 시간을 충분히 단축하지는 않습니다.
메타데이터 가져오기는 태그가 지정된 이미지만 대상으로 합니다. 태그가 없고 참조되지 않은 매니페스트와, 그 매니페스트만 참조하는 레이어는 뒤에 남아 액세스할 수 없게 됩니다. 태그가 없는 이미지는 GitLab UI나 API를 통해 표시된 적이 없지만 "dangling" 상태가 되어 백엔드에 남을 수 있습니다. 새 레지스트리로 가져온 후 모든 이미지는 지속적인 온라인 가비지 컬렉션의 대상이 되며, 기본적으로 24시간 넘게 남아 있는 태그가 없고 참조되지 않은 매니페스트 및 레이어를 삭제합니다.
올바른 가져오기 방법 선택#
오프라인 가비지 컬렉션을 정기적으로 실행한다면, 1단계 가져오기 방법을 사용합니다. 이 방법은 3단계 가져오기 방법과 비슷한 시간이 걸리며 더 간단한 작업입니다.
레지스트리가 너무 커서 오프라인 가비지 컬렉션을 정기적으로 실행할 수 없다면, 3단계 가져오기 방법을 사용하여 읽기 전용 시간을 크게 최소화합니다.
외부 데이터베이스를 사용한다면 마이그레이션 경로를 진행하기 전에 외부 데이터베이스 연결을 먼저 설정합니다.
자세한 내용은 외부 데이터베이스 사용을 참고합니다.
중단된 가져오기 복원#
히스토리
- GitLab 18.5에서 도입되었습니다.
중단된 가져오기를 재개하려면 지난 72시간 이내에 사전 가져오기한 리포지터리를 건너뜁니다. 리포지터리는 다음 중 하나로 사전 가져오기됩니다:
- 3단계 가져오기 프로세스의 1단계를 완료해서
- 1단계 가져오기 프로세스를 완료해서
중단된 가져오기를 복원하려면 --pre-import-skip-recent 플래그를 구성합니다. 기본값은 72시간입니다.
예를 들면:
# Skip repositories imported within 6 hours from the start of the import command
--pre-import-skip-recent 6h
# Disable skipping behavior
--pre-import-skip-recent 0
유효한 기간 단위에 대한 자세한 내용은 Go 기간 문자열을 참고합니다.
가져오기 이후#
대규모 가져오기를 완료하면 수십만에서 수백만 개의 블롭이 가비지 컬렉션 검토 대기열에 쌓일 수 있습니다. 이는 정상입니다.
태그가 지정된 이미지가 dangling 블롭을 조사하기 전에 먼저 가져와지므로, 가비지 컬렉터는 처음에 태그가 지정된 이미지가 여전히 참조하는 블롭을 검토합니다. 가비지 컬렉션은 이 블롭들을 대기열에서 제거하지만 스토리지에서 삭제하지는 않습니다.
스토리지는 가비지 컬렉터가 dangling 블롭에 도달한 후에만 줄어듭니다. 가비지 컬렉터가 이미지 블롭과의 간섭을 피하려고 검토를 지연시키기 때문에, 가져오기 이후 레지스트리 스토리지가 줄어드는 데 48시간 이상 걸릴 수 있습니다.
가져오기 이후 가비지 컬렉션 백로그를 모니터링하고 관리하려면 다음을 확인합니다:
- 온라인 가비지 컬렉션 상태 확인으로 검토 대기열의 크기와 상태를 확인합니다.
- 가비지 컬렉터 워커 간격 조정으로 대규모 백로그 처리를 일시적으로 가속화합니다.
Prefer 모드#
Prefer 모드는 메타데이터 데이터베이스의 구성 옵션이며, 기존 레지스트리가 아직 데이터베이스로 가져오기되지 않았을 때 레지스트리가 레거시 메타데이터 스토리지로 폴백하게 합니다.
Prefer 모드 활성화#
Prefer 모드를 활성화하려면:
-
/etc/gitlab/gitlab.rb에서database.enabled를true나false가 아닌'prefer'로 설정합니다:registry['database'] = { 'enabled' => 'prefer', 'host' => '<your_database_host>', 'port' => 5432, 'user' => '<your_database_user>', 'password' => '<your_database_password>', 'dbname' => '<your_database_name>', } -
파일을 저장하고 GitLab을 재구성합니다.
GitLab을 재구성하면 레지스트리는 시작 시 어떤 메타데이터 백엔드를 사용할지 파일 시스템이나 데이터베이스에 대한 이전 쓰기를 추적하는 잠금 파일을 기준으로 평가합니다.
Prefer 모드 잠금 파일 워크플로#
레지스트리는 시작할 때 잠금 파일을 쓰고, 메타데이터 가져오기는 완료될 때 잠금 파일을 쓰지만, 푸시는 잠금 파일을 쓰지 않습니다.
레거시 메타데이터를 사용하는 레지스트리는 이미 메타데이터가 있는 스토리지에 대해 시작할 때
filesystem-in-use를 씁니다.
메타데이터 데이터베이스를 사용하는 레지스트리는 스토리지에 무엇이 있든 관계없이 시작할 때
database-in-use를 씁니다.
메타데이터 가져오기도 완료될 때 database-in-use를 씁니다.
다음 표는 enabled: false와 enabled: 'prefer'에서 잠금 파일 상태별 결과를 보여 줍니다.
스토리지에 완전한 카탈로그가 있고, 구성된 데이터베이스에 접근할 수 있으며, 레지스트리 스키마가 있고,
리포지터리 행이 없다고 가정합니다.
| 스토리지의 잠금 파일 | enabled |
레지스트리 시작 | 제공되는 카탈로그 |
|---|---|---|---|
| 없음 | false |
예, 레거시 메타데이터를 사용하고 filesystem-in-use를 씁니다 |
완전함 |
filesystem-in-use |
'prefer' |
예, 레거시 메타데이터로 폴백합니다 | 완전함 |
| 없음 | 'prefer' |
예, 데이터베이스를 채택하고 database-in-use를 씁니다 |
비어 있음, 200 OK 응답 |
database-in-use |
false |
아니요, registry metadata database in use |
없음 |
| 둘 다 | 'prefer' |
아니요, database-in-use and filesystem-in-use lockfiles present |
없음 |
filesystem-in-use |
false |
예, 레거시 메타데이터를 사용합니다 | 완전함 |
표의 마지막 행은 데이터베이스에서 푸시를 아직 제공한 적이 없는 사이트를 위한 것입니다. 제공한 적이 있는 사이트에서는 레지스트리가 시작되고, 가져오기가 실행된 이후에 푸시된 모든 항목이 빠진 카탈로그를 제공합니다. 자세한 내용은 오브젝트 스토리지 메타데이터로 되돌리기를 참고합니다.
세 번째 행만 오류를 보고하지 않고 실패합니다. 나머지는 완전한 카탈로그를 제공하거나 시작을 거부하면서 그 이유를 알려 줍니다.
잠금 파일이 없다고 해서 항상 스토리지가 비어 있는 것은 아닙니다. 스토리지가 처음 채워진 뒤 재시작하지 않은 레지스트리에는 잠금 파일이 없습니다. 여기에는 복제를 통해 레지스트리 API로 채워진 Geo 보조 사이트가 포함됩니다. 복사본에 잠금 파일이 포함되어 있지 않다면, 스냅샷에서 복원했거나 다른 사이트에서 미러링한 스토리지도 포함됩니다.
데이터베이스를 사용할 수 없으면(예: 서버가 연결은 수락하지만 구성된 자격 증명을 거부하는 경우)
레지스트리가 시작되지 않고 gitlab-ctl reconfigure도 레지스트리 데이터베이스 마이그레이션에서 실패합니다.
빈 카탈로그와 시작 실패를 모두 피하는 방법은 기존 설치를 참고합니다.
스토리지를 비우거나 다시 만들어도 잠금 파일은 지워지지 않습니다.
lockfiles 디렉터리는 v2/ 안이 아니라 v2/와 같은 수준에 있습니다.
공간을 확보하려고 v2/blobs와 v2/repositories를 삭제해도 filesystem-in-use는 그대로 남습니다.
그러면 이제 비어 있는 스토리지에 대해 다음에 시작할 때 레지스트리가 다시 레거시 메타데이터로 폴백합니다.
이 상태에서는 푸시가 성공하고 태그가 나타나지만 메타데이터 데이터베이스는 비어 있으므로,
가져오기가 끝나지 않은 것처럼 보일 수 있습니다.
메타데이터 데이터베이스로 이동하려는데 스토리지를 비운 뒤에 푸시된 것이 없다면 잠금 파일을 제거합니다.
레지스트리를 중지하고, 디스크의 잠금 파일 확인에서 설명한 디렉터리에서
filesystem-in-use를 삭제한 다음 레지스트리를 시작합니다.
스토리지를 비운 뒤에 푸시된 것이 있다면 대신
메타데이터 가져오기를 실행합니다. 잠금 파일을 제거하면 해당 이미지가
카탈로그에서 빠지기 때문입니다.
레거시 메타데이터를 계속 사용하려면 잠금 파일을 유지합니다.
폴백 결정은 시작 시 한 번만 내려지며 레지스트리가 실행되는 동안에는 바뀌지 않습니다. 폴백 후 데이터베이스에 대한 자동 재시도나 재연결은 없습니다. 폴백 후 파일 시스템에서 데이터베이스 모드로 전환하려면 표준 메타데이터 가져오기를 완료하고 레지스트리를 재시작합니다.
기본 구성#
히스토리
- GitLab 19.0에서 새 Linux 패키지 및 소스 컴파일 설치의 기본 메타데이터 데이터베이스 모드가
prefer로 변경되었습니다.
GitLab 19.0 이상에서는 새 설치에 대해 메타데이터 데이터베이스가 기본적으로 prefer 모드로 활성화됩니다:
- Linux 패키지(Omnibus) 설치:
/etc/gitlab/gitlab.rb에 설정을 지정하지 않으면registry['database']['enabled']는 기본값으로'prefer'가 됩니다. 자세한 내용은 이슈 9396을 참고합니다. - 소스 컴파일 설치: 레지스트리 구성 파일에 설정을 지정하지 않으면
database.enabled는 기본값으로'prefer'가 됩니다.
업그레이드 후 레지스트리가 어떤 백엔드를 사용하는지 확인합니다. 절차는 활성 메타데이터 백엔드 확인을 참고합니다.
새 설치#
새 GitLab 19.0 이상 설치에서는 레지스트리가 prefer 모드로 시작됩니다. 접근 가능한 메타데이터 데이터베이스가 구성되어 있으면 레지스트리는 이를 사용합니다. 접근 가능한 데이터베이스가 없으면 레지스트리는 시작에 실패합니다.
새 설치를 파일 시스템 메타데이터로 유지하려면 레지스트리를 처음 시작하기 전에 데이터베이스 모드를 false로 설정합니다:
-
Linux 패키지(Omnibus) 설치의 경우,
/etc/gitlab/gitlab.rb에서:registry['database']['enabled'] = false -
소스 컴파일 설치의 경우,
/home/git/gitlab/config/gitlab.yml에서:registry: database: enabled: false
기존 설치#
기존 설치를 GitLab 19.0 이상으로 업그레이드해도 현재 registry['database']['enabled'] 설정은 유지됩니다. 업그레이드는 메타데이터를 마이그레이션하거나 활성 백엔드를 전환하지 않습니다.
파일 시스템 메타데이터를 사용하는 기존 prefer 모드 설치는 업그레이드 후에도 파일 시스템 메타데이터를 계속 사용합니다. 데이터베이스로 전환하려면 메타데이터 가져오기를 완료합니다.
/etc/gitlab/gitlab.rb에 registry['database']['enabled']가 설정되어 있지 않으면 업그레이드는
설정을 지정되지 않은 상태로 두고, 레지스트리는 prefer 모드로 시작됩니다. 이러한 사이트를 업그레이드하기 전에
잠금 파일이 있는지 확인합니다. 절차는
디스크의 잠금 파일 확인을 참고합니다.
레지스트리가 레거시 메타데이터를 사용하는데 filesystem-in-use가 없다면
업그레이드하기 전에 레지스트리를 한 번 재시작합니다.
sudo gitlab-ctl restart registry
재시작하면 잠금 파일이 쓰이므로 prefer 모드가 레거시 메타데이터로 올바르게 폴백합니다. 재시작하지 않으면 레지스트리가 잠금 파일을 찾지 못해 Prefer 모드에서 설명한 잠금 파일 없음 경로를 따릅니다.
메타데이터 데이터베이스 백업#
레지스트리가 메타데이터 데이터베이스를 사용하는 경우, 백업에 레지스트리 데이터베이스를 포함합니다. 절차는 메타데이터 데이터베이스로 백업을 참고합니다.
기존 파일 시스템 메타데이터가 있는 prefer 모드 설치는 재시작해도 폴백 상태를 유지합니다. 폴백 중에는 레지스트리가 메타데이터 데이터베이스를 읽거나 쓰지 않습니다. 폴백이 끝나기 전까지는 메타데이터 데이터베이스를 백업할 필요가 없습니다.
폴백을 끝내려면 메타데이터 가져오기를 완료하고 레지스트리를 재시작합니다. 재시작 후에는 레지스트리가 메타데이터 데이터베이스를 사용합니다. 이를 백업 루틴에 포함합니다.
활성 메타데이터 백엔드 확인#
레지스트리가 어떤 메타데이터 백엔드를 사용하는지 확인하려면 다음 방법 중 하나를 사용합니다.
레지스트리 API 응답 헤더 확인#
레지스트리는 /v2/ 엔드포인트에서 인증을 요구합니다. 이 엔드포인트는 인증되지 않은 요청에
401 Unauthorized로 응답하며 gitlab-container-registry-* 헤더를 포함하지 않으므로,
이 확인은 답을 주는 대신 아무 출력도 내지 않습니다.
레지스트리 API 응답 헤더를 확인하려면 다음과 같이 합니다.
-
레지스트리용 토큰을 받습니다. 레지스트리는 GitLab이 발급한 JWT만 허용합니다. 레지스트리 토큰 엔드포인트에서 토큰을 요청합니다. 최소한
read_registry스코프가 있는 개인 액세스 토큰으로 인증합니다. 관리자일 필요는 없습니다./v2/는 리포지터리에 대한 액세스가 아니라 유효한 토큰을 요구하므로 이 요청에는scope매개변수가 필요하지 않습니다.token=$(curl --silent --user "<username>:<personal-access-token>" \ "https://gitlab.example.com/jwt/auth?service=container_registry" \ | grep --only-matching '"token":"[^"]*"' | cut --delimiter='"' --fields=4)개인 액세스 토큰에 레지스트리 스코프가 없으면 엔드포인트가
403 Forbidden상태 코드와 빈 토큰을 반환합니다. -
레지스트리
/v2/엔드포인트에 요청을 보냅니다:curl --silent --head --header "Authorization: Bearer ${token}" "https://registry.example.com/v2/" | grep --ignore-case gitlab-container-registry-database-enabled -
다음
gitlab-container-registry-database-enabled응답 헤더를 확인합니다:-
값이
true이면 레지스트리가 메타데이터 데이터베이스를 사용 중입니다. -
값이
false이면 레거시 파일 시스템 스토리지를 사용 중입니다. -
출력이 없으면 헤더가 없었다는 뜻이므로, 명령이
false가 아니라 아무 답도 주지 않은 것입니다. 헤더가 없다고 해서 메타데이터 데이터베이스가 비활성화된 것은 아닙니다. 결과에 따라 조치하기 전에 응답 상태를 확인합니다.curl --silent --output /dev/null --write-out '%{http_code}\n' --header "Authorization: Bearer ${token}" "https://registry.example.com/v2/"401은token이 비어 있거나 토큰이 거부되어 요청이 인증되지 않았다는 뜻입니다. 인증할 수 없다면 대신 디스크의 잠금 파일 확인 또는 레지스트리 로그 확인을 사용합니다.
-
디스크의 잠금 파일 확인#
디스크의 잠금 파일을 확인하려면 구성된 스토리지 백엔드에서 다음 경로의
<rootdirectory>/docker/registry/lockfiles/ 파일을 확인합니다:
database-in-use: 레지스트리가 메타데이터 데이터베이스를 사용 중입니다.filesystem-in-use: 레지스트리가 레거시 파일 시스템 스토리지를 사용 중입니다.
두 잠금 파일이 모두 존재하면 레지스트리는 잘못된 상태이며 시작되지 않습니다.
레지스트리 로그 확인#
레지스트리는 시작 시 선택한 메타데이터 백엔드를 로그로 남깁니다.
레지스트리 로그를 확인할 때는 다음 메시지 중 하나를 찾습니다:
-
레지스트리가 레거시 스토리지로 폴백하는 경우(prefer 모드에서만 해당):
database prefer mode enabled, but found filesystem metadata: falling back to legacy metadata -
레지스트리가 데이터베이스에 연결되는 경우:
using the metadata database
데이터베이스 마이그레이션#
컨테이너 레지스트리는 두 가지 유형의 마이그레이션을 지원합니다:
- 일반 스키마 마이그레이션: 새 애플리케이션 코드를 배포하기 전에 실행해야 하는 데이터베이스 구조 변경으로, 사전 배포 마이그레이션이라고도 합니다. 배포 지연을 방지하려면 빠르게(몇 분 이하) 실행되어야 합니다.
- 배포 후 마이그레이션: 애플리케이션이 실행 중인 동안 실행할 수 있는 데이터베이스 구조 변경입니다. 대규모 테이블에 인덱스를 생성하는 등 시간이 오래 걸리는 작업에 사용해 시작 지연과 장시간의 업그레이드 다운타임을 방지합니다.
기본적으로 레지스트리는 일반 스키마 마이그레이션과 배포 후 마이그레이션을 동시에 적용합니다. 업그레이드 중 다운타임을 줄이려면 배포 후 마이그레이션을 건너뛰고 애플리케이션이 시작된 후 수동으로 적용할 수 있습니다.
데이터베이스 마이그레이션 적용#
애플리케이션이 시작되기 전에 일반 스키마 마이그레이션과 배포 후 마이그레이션을 모두 적용하려면:
-
데이터베이스 마이그레이션을 실행합니다:
sudo gitlab-ctl registry-database migrate up
배포 후 마이그레이션을 건너뛰려면:
-
일반 스키마 마이그레이션만 실행합니다:
sudo gitlab-ctl registry-database migrate up --skip-post-deployment--skip-post-deployment플래그 대신SKIP_POST_DEPLOYMENT_MIGRATIONS환경 변수를true로 설정할 수도 있습니다:SKIP_POST_DEPLOYMENT_MIGRATIONS=true sudo gitlab-ctl registry-database migrate up -
애플리케이션을 시작한 후 대기 중인 배포 후 마이그레이션을 적용합니다:
sudo gitlab-ctl registry-database migrate up
애플리케이션이 시작되기 전에 일반 스키마 마이그레이션과 배포 후 마이그레이션을 모두 적용하려면:
-
데이터베이스 마이그레이션을 실행합니다:
sudo -u registry gitlab-ctl registry-database migrate up
배포 후 마이그레이션을 건너뛰려면:
-
일반 스키마 마이그레이션만 실행합니다:
sudo -u registry gitlab-ctl registry-database migrate up --skip-post-deployment--skip-post-deployment플래그 대신SKIP_POST_DEPLOYMENT_MIGRATIONS환경 변수를true로 설정할 수도 있습니다:SKIP_POST_DEPLOYMENT_MIGRATIONS=true sudo -u registry gitlab-ctl registry-database migrate up -
애플리케이션을 시작한 후 대기 중인 배포 후 마이그레이션을 적용합니다:
sudo -u registry gitlab-ctl registry-database migrate up
migrate up 명령은 마이그레이션 적용 방식을 제어할 수 있는 몇 가지 추가 플래그를 제공합니다.
자세한 내용은 sudo gitlab-ctl registry-database migrate up --help를 실행합니다.
온라인 가비지 컬렉션 모니터링#
가져오기 프로세스 이후 온라인 가비지 컬렉션의 초기 실행은 가져온 이미지 수에 따라 기간이 달라집니다. 이 기간에는 온라인 가비지 컬렉션의 효율성과 상태를 모니터링해야 합니다.
데이터베이스 성능 모니터링#
가져오기를 완료하면 가비지 컬렉션 대기열이 소진되는 동안 데이터베이스가 높은 부하를 겪는 기간이 예상됩니다. 이 높은 부하는 온라인 가비지 컬렉터가 대기 중인 태스크를 처리하면서 발생하는 다수의 개별 데이터베이스 호출 때문입니다.
오류나 경고가 있는지 PostgreSQL 및 레지스트리 로그를 정기적으로 확인합니다. 레지스트리 로그에서는
component=registry.gc.*로 필터링된 로그에 특히 주의를 기울입니다.
메트릭 추적#
Prometheus 및 Grafana와 같은 모니터링 도구를 사용해 가비지 컬렉션 메트릭을 시각화하고 추적하며,
registry_gc_* 프리픽스가 붙은 메트릭에 초점을 맞춥니다. 여기에는 삭제 대상으로 표시된
오브젝트 수, 성공적으로 삭제된 오브젝트 수, 실행 간격, 실행 기간이 포함됩니다.
Prometheus를 활성화하는 방법은 레지스트리 디버그 서버 활성화를
참고합니다.
태스크 대기열 모니터링#
블롭 및 매니페스트에 대한 가비지 컬렉션 태스크 대기열의 상태와 건강을 모니터링합니다.
온라인 가비지 컬렉션 상태 확인#
다음 명령은 온라인 가비지 컬렉션과 관련된 정보를 표시합니다.
sudo gitlab-ctl registry-database gc-stats
예시 출력:
=== Blob Review Queue ===
Tasks Pending Removal: 42
Tasks ready for GC review (review_after has passed).
┌───────────────────────────────────────────────────────────────────┬─────────────────────┬─────────────────┐
│ DIGEST │ REVIEW AFTER │ EVENT │
├───────────────────────────────────────────────────────────────────┼─────────────────────┼─────────────────┤
│ sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22e │ 2026-01-16 21:56:13 │ blob_upload │
│ sha256:b4f5e6d7c8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2 │ 2026-01-16 19:56:13 │ manifest_delete │
│ sha256:c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3 │ 2026-01-16 17:56:13 │ layer_delete │
└───────────────────────────────────────────────────────────────────┴─────────────────────┴─────────────────┘
Long Overdue Tasks: 5
Tasks pending longer than configured delay - may need attention.
┌───────────────────────────────────────────────────────────────────┬─────────────────────┬──────────────┬─────────┐
│ DIGEST │ REVIEW AFTER │ EVENT │ OVERDUE │
├───────────────────────────────────────────────────────────────────┼─────────────────────┼──────────────┼─────────┤
│ sha256:d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4 │ 2026-01-11 23:56:13 │ blob_upload │ 4d 0h │
│ sha256:e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5 │ 2026-01-13 23:56:13 │ layer_delete │ 2d 0h │
└───────────────────────────────────────────────────────────────────┴─────────────────────┴──────────────┴─────────┘
High Retry Tasks: 2
Tasks with >10 review attempts - may indicate persistent issues.
┌───────────────────────────────────────────────────────────────────┬─────────────────────┬─────────────────┬─────────┐
│ DIGEST │ REVIEW AFTER │ EVENT │ RETRIES │
├───────────────────────────────────────────────────────────────────┼─────────────────────┼─────────────────┼─────────┤
│ sha256:f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 │ 2026-01-17 00:56:13 │ blob_upload │ 15 │
│ sha256:a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7 │ 2026-01-17 01:56:13 │ manifest_delete │ 12 │
└───────────────────────────────────────────────────────────────────┴─────────────────────┴─────────────────┴─────────┘
=== Manifest Review Queue ===
Tasks Pending Removal: 128
Tasks ready for GC review (review_after has passed).
┌───────────────┬─────────────┬─────────────────────┬──────────────────────┐
│ REPOSITORY ID │ MANIFEST ID │ REVIEW AFTER │ EVENT │
├───────────────┼─────────────┼─────────────────────┼──────────────────────┤
│ 1001 │ 12345 │ 2026-01-16 22:56:13 │ tag_delete │
│ 1002 │ 67890 │ 2026-01-16 20:56:13 │ manifest_upload │
│ 1003 │ 11111 │ 2026-01-16 18:56:13 │ tag_switch │
│ 2001 │ 22222 │ 2026-01-16 16:56:13 │ manifest_list_delete │
└───────────────┴─────────────┴─────────────────────┴──────────────────────┘
Long Overdue Tasks: 8
Tasks pending longer than configured delay - may need attention.
┌───────────────┬─────────────┬─────────────────────┬─────────────────┬─────────┐
│ REPOSITORY ID │ MANIFEST ID │ REVIEW AFTER │ EVENT │ OVERDUE │
├───────────────┼─────────────┼─────────────────────┼─────────────────┼─────────┤
│ 3001 │ 33333 │ 2026-01-12 23:56:13 │ tag_delete │ 3d 0h │
│ 3002 │ 44444 │ 2026-01-14 23:56:13 │ manifest_delete │ 1d 0h │
└───────────────┴─────────────┴─────────────────────┴─────────────────┴─────────┘
High Retry Tasks: 3
Tasks with >10 review attempts - may indicate persistent issues.
┌───────────────┬─────────────┬─────────────────────┬─────────────────┬─────────┐
│ REPOSITORY ID │ MANIFEST ID │ REVIEW AFTER │ EVENT │ RETRIES │
├───────────────┼─────────────┼─────────────────────┼─────────────────┼─────────┤
│ 4001 │ 55555 │ 2026-01-17 00:26:13 │ tag_delete │ 18 │
│ 4002 │ 66666 │ 2026-01-17 00:41:13 │ manifest_upload │ 11 │
└───────────────┴─────────────┴─────────────────────┴─────────────────┴─────────┘
다음 명령을 사용하여 레지스트리 메타데이터 데이터베이스에 연결합니다:
gitlab-psql -d registry
다음 쿼리는 10회 넘게 재시도되었거나 24시간 넘게 검토 대상이었던 태스크를 반환합니다. 온라인 가비지 컬렉터는 실패 횟수가 적은 항목을 24시간 이내에 검토용으로 가져와야 합니다. 행이 반환되면 온라인 가비지 컬렉터의 상태를 조사합니다.
매니페스트의 경우:
SELECT
repository_id,
manifest_id,
ROUND(
EXTRACT(
EPOCH
FROM
AGE(NOW(), review_after)
) / 3600
) AS hours_eligible_for_review,
review_count as failed_review_attempts,
event
FROM
gc_manifest_review_queue
WHERE
review_after < NOW() - INTERVAL '24 hours'
OR review_count > 10
LIMIT
20;
블롭의 경우:
SELECT
substring(encode(digest, 'hex'), 3) AS digest,
ROUND(
EXTRACT(
EPOCH
FROM
AGE(NOW(), review_after)
) / 3600
) AS hours_eligible_for_review,
review_count as failed_review_attempts,
event
FROM
gc_blob_review_queue
WHERE
review_after < NOW() - INTERVAL '24 hours'
OR review_count > 10
LIMIT
20;
다음 쿼리를 실행하여 검토 대상 태스크 수를 확인합니다:
SELECT COUNT(*) FROM gc_blob_review_queue WHERE review_after < NOW();
SELECT COUNT(*) FROM gc_manifest_review_queue WHERE review_after < NOW();
일반적으로 검토 대상 항목 수는 상대적으로 적어야 하며, 종종 0에 가깝습니다. 그러나 다음의 경우 더 많을 수 있습니다:
- 24~48시간 전에 가져오기가 시작된 경우.
- 대량의 태그가 삭제되었거나 컨테이너 리포지터리가 제거된 경우.
- 온라인 가비지 컬렉션이 장기간 비활성화된 경우.
재시도된 태스크나 오래 지연된 태스크가 있다면 레지스트리 로그에서
가비지 컬렉션과 관련된 메시지를 확인합니다.
component="registry.gc.*로 항목을 필터링하고 오류 메시지를 조사합니다.
문제 해결 전 확인 사항#
GC 대기열 크기#
gc_manifest_review_queue와 gc_blob_review_queue의 필터링되지 않은 크기는
온라인 가비지 컬렉터의 상태를 나타내는 좋은 지표가 아닙니다. 이
대기열에는 계속 새 항목이 추가되므로,
활성 레지스트리에서는 완전히 비워지지 않습니다.
또한 이 대기열의 모든 항목이 스토리지에서 제거되는 것도 아닙니다. 이러한 대기열에 대한 자세한 설명은 온라인 가비지 컬렉션 명세를 참고합니다.
검토 대상 태스크가 많은 경우#
검토 대상 태스크가 대량으로 쌓인 것도 반드시 우려할 일은 아닙니다. 가비지 컬렉터가 활동 급증으로 발생한 항목을 처리 중일 수 있습니다.
오래된 태스크가 있는 경우#
마찬가지로 이러한 태스크의 created_at 날짜만으로는 좋은 상태 지표가 되지 않습니다.
이벤트가 동일한 블롭이나 매니페스트를 대기열에 추가하면 기존 태스크의
review_after가 갱신되어 검토가 지연되며, 중복 태스크는 생성되지 않습니다.
이는 여러 번 발생할 수 있으므로 몇 달 전에 생성된 태스크도 우려할 필요는 없습니다.
가비지 컬렉터 워커 간격 조정#
검토 대상 태스크 수가 계속 높게 유지되어 가비지 컬렉션 블롭 또는 매니페스트 워커 실행
사이의 빈도를 높이고 싶다면, 간격 구성을
기본값(5s)에서 1s로 업데이트합니다:
registry['gc'] = {
'blobs' => {
'interval' => '1s'
},
'manifests' => {
'interval' => '1s'
}
}
가져오기 부하가 해소된 후에는 데이터베이스 및 레지스트리 인스턴스에 불필요한 CPU 부하가 걸리지 않도록 장기적으로 이 설정을 조정해야 합니다. 성능과 리소스 사용량의 균형을 맞추는 값으로 간격을 점차 늘릴 수 있습니다.
데이터 일관성 검증#
가져오기 이후 데이터 일관성을 보장하려면 crane validate
도구를 사용합니다. 이 도구는 컨테이너 레지스트리의 모든 이미지 레이어와 매니페스트가
액세스 가능하고 올바르게 연결되어 있는지 확인합니다. crane validate를 실행하면
레지스트리의 이미지가 완전하고 액세스 가능한지 확인하여 가져오기가 성공했음을 보장할 수 있습니다.
정리 정책 검토#
이미지 대부분에 태그가 지정되어 있다면 가비지 컬렉션은 태그가 없는 이미지만 삭제하므로 스토리지 공간을 크게 줄이지 못합니다.
불필요한 태그를 제거하는 정리 정책을 적용하면 결국 이미지가 가비지 컬렉션으로 제거되어 스토리지 공간이 회수됩니다.
외부 데이터베이스 사용#
기본적으로 GitLab 18.3 이상은 컨테이너 레지스트리 메타데이터를 위해 기본 GitLab 데이터베이스 내에 논리 데이터베이스를 사전 프로비저닝합니다. 그러나 레지스트리를 확장하려는 경우 컨테이너 레지스트리 전용 외부 데이터베이스를 사용할 수 있습니다.
단계#
- 외부 데이터베이스를 만듭니다.
이후 고유한 데이터베이스 값으로 대체하여 기본 데이터베이스와 동일한 단계를 따릅니다. 안내에 따라 데이터베이스를 활성화·비활성화하도록 주의하면서 데이터베이스를 비활성화한 상태로 시작합니다:
registry['database'] = {
'enabled' => false,
'host' => '<registry_database_host_placeholder_change_me>',
'port' => 5432, # Default, but set to the port of your database instance if it differs.
'user' => '<registry_database_username_placeholder_change_me>',
'password' => '<registry_database_placeholder_change_me>',
'dbname' => '<registry_database_name_placeholder_change_me>',
'sslmode' => 'require', # See the PostgreSQL documentation for additional information https://www.postgresql.org/docs/16/libpq-ssl.html.
'sslcert' => '</path/to/cert.pem>',
'sslkey' => '</path/to/private.key>',
'sslrootcert' => '</path/to/ca.pem>'
}
메타데이터 데이터베이스로 백업#
히스토리
- GitLab 18.10에서 레지스트리 메타데이터 데이터베이스에 대한 자동 백업 지원이 도입되었습니다.
메타데이터 데이터베이스가 활성화되면 백업은 레지스트리 스토리지 백엔드와 데이터베이스를 모두 포함해야 합니다.
백업 방법은 스토리지 유형에 따라 다릅니다:
- 로컬 파일 시스템 스토리지:
gitlab-backup이 레지스트리를 자동으로 포함합니다. - 오브젝트 스토리지: 오브젝트 스토리지는 별도로 백업해야 합니다.
일관된 레지스트리 상태를 보장하려면 스토리지와 데이터베이스를 최대한 가까운 시점에 백업합니다. 레지스트리를 복원하려면 두 백업을 모두 적용해야 합니다.
자동 백업#
GitLab 18.10 이상에서는 메타데이터 데이터베이스가 구성되어 있으면 gitlab-backup create와
gitlab-backup restore가 레지스트리 메타데이터 데이터베이스를 자동으로 포함합니다. Helm 차트
(Kubernetes) 설치에서는 backup-utility가 동일하게 동작합니다.
메타데이터 데이터베이스는 gitlab.rb나 Helm values 파일에 구성되어 있어야 합니다.
추가 구성은 필요하지 않습니다. 백업 도구는 기존 구성에서 레지스트리 데이터베이스 연결 설정을 읽어옵니다.
백업 Rake 태스크를 직접 호출하는 경우, 백업을 실행하는 노드에 다음 환경 변수를 설정해야 합니다:
| 변수 | 필수 | 설명 |
|---|---|---|
REGISTRY_DATABASE_HOST |
예 | 데이터베이스 호스트입니다. |
REGISTRY_DATABASE_NAME |
예 | 데이터베이스 이름입니다. |
REGISTRY_DATABASE_USER |
예 | 데이터베이스 사용자입니다. |
REGISTRY_DATABASE_PORT |
아니요 | 데이터베이스 포트입니다. 기본값은 5432입니다. |
REGISTRY_DATABASE_PASSWORD |
아니요 | 데이터베이스 비밀번호입니다. |
REGISTRY_DATABASE_SSLMODE |
아니요 | SSL 모드를 요구할지 여부입니다. require로 설정하거나 생략합니다. |
REGISTRY_DATABASE_SSLCERT |
아니요 | 클라이언트 인증서의 경로입니다. |
REGISTRY_DATABASE_SSLKEY |
아니요 | 클라이언트 개인 키의 경로입니다. |
REGISTRY_DATABASE_SSLROOTCERT |
아니요 | CA 인증서의 경로입니다. |
REGISTRY_DATABASE_CONNECT_TIMEOUT |
아니요 | 연결 제한 시간(초)입니다. |
백업 Rake 태스크는 다음 자격 증명 중 하나라도 감지되면 레지스트리 데이터베이스 백업을 활성화합니다:
REGISTRY_DATABASE_PASSWORDREGISTRY_DATABASE_SSLCERTREGISTRY_DATABASE_SSLKEYREGISTRY_DATABASE_SSLROOTCERT
자격 증명이 없으면 레지스트리 데이터베이스는 백업에 포함되지 않습니다. 복원할 때도 동일한 환경 변수를 설정해야 합니다.
수동 백업#
GitLab 18.9 이하를 사용하거나 레지스트리 데이터베이스 백업을 별도로
관리하려는 경우, pg_dump와 pg_restore 같은 표준 PostgreSQL 도구를 사용하여
레지스트리 데이터베이스를 독립적으로 백업하고 복원합니다.
Helm 차트(Kubernetes) 백업 및 복원#
히스토리
- GitLab 18.10에서 도입되었습니다.
Helm 차트(Kubernetes) 배포에서는 백업 및 복원 작업을 위한 전용 데이터베이스 자격 증명으로 toolbox Pod를 구성합니다. 별도의 PostgreSQL 사용자 두 개가 필요합니다:
- 백업 사용자는 읽기 전용 권한을 가져야 합니다.
- 복원 사용자는 쓰기 권한을 가져야 합니다.
필요한 작업에 따라 사용자 하나 또는 둘 다를 구성합니다.
시작하기 전에 registry.database.enabled: true로 설정하여 컨테이너 레지스트리 메타데이터 데이터베이스를 활성화합니다.
Kubernetes Secret 생성#
배포하기 전에 Kubernetes Secret을 직접 만들어야 합니다. 차트는 이 Secret을 자동으로 생성하지 않습니다.
예를 들어 백업 및 복원 비밀번호를 모두 포함하는 Secret을 만들려면:
kubectl create secret generic my-registry-db-password-secret \
--from-literal=backupPassword="BACKUP_USER_PASSWORD" \
--from-literal=restorePassword="RESTORE_USER_PASSWORD"
레지스트리 데이터베이스 자격 증명 구성#
백업 및 복원 사용자를 구성하려면 Helm values.yaml에 필요한 YAML을 추가합니다. 구성 설정 정의는 다음 표를 참고합니다.
| 설정 | 기본값 | 설명 |
|---|---|---|
backupUser |
백업 작업에 사용할 PostgreSQL 사용자 이름입니다. 레지스트리 데이터베이스 백업을 활성화하려면 필요합니다. | |
restoreUser |
복원 작업에 사용할 PostgreSQL 사용자 이름입니다. 레지스트리 데이터베이스 복원을 활성화하려면 필요합니다. | |
password.secret |
<release-name>-toolbox-registry-database-password |
비밀번호가 담긴 Kubernetes Secret의 이름입니다. |
password.backupPasswordKey |
backupPassword |
백업 사용자 비밀번호에 대한 Kubernetes Secret의 키입니다. |
password.restorePasswordKey |
restorePassword |
복원 사용자 비밀번호에 대한 Kubernetes Secret의 키입니다. |
다음 예시는 백업 및 복원 사용자를 모두 구성합니다:
gitlab:
toolbox:
backups:
registry:
database:
# PostgreSQL username for backing up the registry database
backupUser: "registry_backup"
# PostgreSQL username for restoring the registry database
restoreUser: "registry_restore"
password:
# Name of the Kubernetes Secret containing the passwords
secret: "my-registry-db-password-secret"
# Key in the Secret for the backup user's password
backupPasswordKey: "backupPassword"
# Key in the Secret for the restore user's password
restorePasswordKey: "restorePassword"
backupUser나 restoreUser가 구성되어 있지 않으면 레지스트리 데이터베이스 백업은
조용히 건너뛰어지며 toolbox Pod는 정상적으로 동작합니다.
PostgreSQL 사용자 권한#
백업 사용자는 레지스트리 데이터베이스를 덤프하려면 읽기 전용 액세스가 필요합니다. 복원 사용자는 데이터베이스를 복원하려면 슈퍼유저 권한이 필요합니다.
Linux 패키지 설치에서는 database_backup_username, database_backup_password,
database_restore_username, database_restore_password가 구성되면
이러한 사용자와 권한이 자동으로 생성됩니다.
소스 컴파일 설치나 외부 데이터베이스 설치에서는 사용자를 만들고 권한을 직접 부여합니다:
-- Create the backup user with minimal privileges for pg_dump.
-- The registry database uses both the 'public' and 'partitions' schemas.
CREATE ROLE registry_backup WITH LOGIN PASSWORD 'password'
NOINHERIT NOCREATEDB NOSUPERUSER NOREPLICATION;
GRANT CONNECT ON DATABASE registry TO registry_backup;
-- Grant read-only access on both schemas
GRANT USAGE ON SCHEMA public TO registry_backup;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO registry_backup;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO registry_backup;
ALTER DEFAULT PRIVILEGES FOR ROLE registry IN SCHEMA public
GRANT SELECT ON TABLES TO registry_backup;
ALTER DEFAULT PRIVILEGES FOR ROLE registry IN SCHEMA public
GRANT SELECT ON SEQUENCES TO registry_backup;
GRANT USAGE ON SCHEMA partitions TO registry_backup;
GRANT SELECT ON ALL TABLES IN SCHEMA partitions TO registry_backup;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA partitions TO registry_backup;
ALTER DEFAULT PRIVILEGES FOR ROLE registry IN SCHEMA partitions
GRANT SELECT ON TABLES TO registry_backup;
ALTER DEFAULT PRIVILEGES FOR ROLE registry IN SCHEMA partitions
GRANT SELECT ON SEQUENCES TO registry_backup;
-- Create the restore user with superuser privileges.
-- SUPERUSER is required for database restore operations because the
-- restore process must SET ROLE to the registry owner and
-- CREATE TRIGGER on all tables.
CREATE ROLE registry_restore WITH LOGIN PASSWORD 'password' SUPERUSER;
자격 증명 볼륨 워크플로#
구성하면 차트는 toolbox Deployment와 백업 CronJob 양쪽 모두에
/etc/gitlab/registry-db/에 마운트된 볼륨을 만듭니다. 이 볼륨은 읽기 전용이며
다음을 포함합니다:
- 연결 파라미터: 데이터베이스 호스트, 포트, 이름, SSL 모드, 연결 제한 시간을 담은 레지스트리 차트가 생성한 ConfigMap입니다.
- 백업 및 복원 사용자 이름: 구성된
backupUser와restoreUser를 담은 toolbox 차트가 생성한 ConfigMap입니다. - 비밀번호: 백업 및 복원 비밀번호를 담은, 사용자가 제공한 Kubernetes Secret입니다.
toolbox Pod의 backup-utility는 이 파일들을 읽어 백업 및 복원 작업에
레지스트리 메타데이터 데이터베이스를 포함합니다.
필요한 자격 증명 파일이 없으면 backup-utility는 경고를 로그로 남기고
다른 리소스의 백업을 계속 진행합니다.
상호 TLS 제한 사항#
PostgreSQL과의 상호 TLS 인증을 위한 SSL 인증서 경로는 SSL이 전역으로
구성된 경우(global.psql.ssl)에만 포함됩니다. SSL이 레지스트리 서브차트
수준(registry.database.ssl)에서만 구성된 경우, 해당 설정은
toolbox에 전달되지 않습니다.
Geo 고려 사항#
Geo를 사용하면 각 사이트는 자체 레지스트리 데이터베이스와 오브젝트 스토리지를 유지합니다. 각 사이트에서 레지스트리 데이터베이스와 오브젝트 스토리지를 독립적으로 백업합니다. Geo는 사이트 간에 레지스트리 데이터베이스를 복제하지 않습니다.
레지스트리 다운그레이드#
가져오기를 완료한 후 레지스트리를 이전 버전으로 다운그레이드하려면 원하는 버전의 백업으로 복원해야 합니다.
Geo를 사용하는 데이터베이스 아키텍처#
컨테이너 레지스트리와 함께 GitLab Geo를 사용하는 경우, 각 사이트의 레지스트리에 대해 별도의 데이터베이스 및 오브젝트 스토리지 스택을 구성해야 합니다. 컨테이너 레지스트리에 대한 Geo 복제는 데이터베이스 복제가 아니라 레지스트리 알림에서 생성된 이벤트를 사용합니다.
사전 요구 사항#
각 Geo 사이트는 별도의 사이트별 리소스가 필요합니다.
- 컨테이너 레지스트리 데이터베이스용 PostgreSQL 인스턴스
- 컨테이너 레지스트리용 오브젝트 스토리지 인스턴스
- 이러한 사이트별 리소스를 사용하도록 구성된 컨테이너 레지스트리
다음 다이어그램은 데이터 흐름과 기본 아키텍처를 보여줍니다.
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TB
accTitle: Geo architecture for the container registry metadata database
accDescr: The primary site sends events to the secondary site through the GitLab Rails notification system for Geo replication.
subgraph "Primary site"
P_Rails[GitLab Rails]
P_Reg[Container registry]
P_RegDB[(Registry database)]
P_Obj[(Object storage)]
P_Reg --> P_RegDB
P_RegDB --> P_Obj
end
subgraph "Secondary site"
S_Rails[GitLab Rails]
S_Reg[Container registry]
S_RegDB[(Registry database)]
S_Obj[(Object storage)]
S_Reg --> S_RegDB
S_RegDB --> S_Obj
end
P_Reg -- "Notifications" --> P_Rails
P_Rails -- "Events" --> S_Rails
S_Rails --> S_Reg</code></pre></details></div>
각 사이트에서 별도의 데이터베이스 인스턴스를 사용해야 하는 이유는 다음과 같습니다.
- 기본 GitLab 데이터베이스는 읽기 전용으로 보조 사이트에 복제됩니다.
- 이 복제는 레지스트리 데이터베이스에 대해서만 선택적으로 비활성화할 수 없습니다.
- 컨테이너 레지스트리는 양쪽 사이트에서 데이터베이스에 대한 쓰기 액세스가 필요합니다.
- 동질적인 구성을 사용하면 Geo 사이트 간에 최대한의 동등성을 보장할 수 있습니다.
오브젝트 스토리지 메타데이터로 되돌리기#
메타데이터 가져오기를 완료한 후 레지스트리가 오브젝트 스토리지 메타데이터를 사용하도록 되돌릴 수 있습니다.
Warning
오브젝트 스토리지 메타데이터로 되돌리면, 가져오기 완료 시점과 이 되돌리기 작업 사이에
추가되거나 삭제된 컨테이너 이미지, 태그, 리포지터리는 사용할 수 없습니다.
오브젝트 스토리지 메타데이터로 되돌리려면 다음과 같이 합니다.
-
마이그레이션 전에 수행한 백업을 복원합니다.
-
레지스트리가 오브젝트 스토리지를 사용한다면 디스크의 잠금 파일 확인에서 설명한
위치에서 database-in-use를 삭제합니다.
백업을 복원해도 오브젝트 스토리지에서 이 잠금 파일은 제거되지 않습니다.
잠금 파일이 있는 동안에는 'enabled' => false인 레지스트리가 시작되지 않고
registry metadata database in use, please enable the database를 로그로 남깁니다.
-
/etc/gitlab/gitlab.rb 파일에 다음 구성을 추가합니다.
registry['database'] = {
'enabled' => false,
}
-
파일을 저장하고 GitLab을 재구성합니다.
문제 해결#
오류와 문제 해결 방법 및 우회 방법을 확인하려면 컨테이너 레지스트리 메타데이터 데이터베이스 문제 해결을 참고합니다.