InfoGrab DocsInfoGrab Docs

컨테이너 레지스트리 스토리지 줄이기

요약

레지스트리 사용량을 관리하지 않으면 컨테이너 레지스트리는 시간이 지나면서 크기가 커질 수 있습니다. 불필요한 이미지와 태그를 삭제하고 컨테이너 레지스트리 정리 정책을 설정해 컨테이너 레지스트리 사용량을 자동으로 관리해야 합니다.

레지스트리 사용량을 관리하지 않으면 컨테이너 레지스트리는 시간이 지나면서 크기가 커질 수 있습니다. 예를 들어 이미지나 태그를 많이 추가하면 다음과 같은 일이 발생합니다.

  • 사용 가능한 태그나 이미지 목록을 가져오는 속도가 느려집니다.
  • 서버에서 많은 스토리지 공간을 차지합니다.

불필요한 이미지와 태그를 삭제하고 컨테이너 레지스트리 정리 정책을 설정해 컨테이너 레지스트리 사용량을 자동으로 관리해야 합니다.

컨테이너 레지스트리 사용량 보기#

컨테이너 레지스트리 리포지터리의 스토리지 사용량 데이터를 봅니다.

프로젝트의 경우#

사전 요구 사항:

프로젝트의 스토리지 사용량을 보려면 다음 단계를 수행합니다.

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. 다음 중 하나를 수행합니다.
    • 전체 스토리지 사용량을 보려면 Settings > Usage quotas를 선택합니다. Namespace entities에서 Container Registry를 선택해 개별 리포지터리를 봅니다.
    • 리포지터리별 스토리지 사용량을 바로 보려면 Deploy > Container Registry를 선택합니다.

다음 방법도 사용할 수 있습니다.

그룹의 경우#

사전 요구 사항:

그룹의 스토리지 사용량을 보려면 다음 단계를 수행합니다.

  1. 상단 바에서 Search or go to를 선택하고 그룹을 찾습니다.
  2. 왼쪽 사이드바에서 Settings > Usage quotas를 선택합니다.
  3. Storage 탭을 선택합니다.

Groups API로 그룹에 속한 모든 프로젝트의 전체 컨테이너 레지스트리 스토리지를 가져올 수도 있습니다.

스토리지 데이터 업데이트#

메타데이터 데이터베이스를 활성화한 뒤에는 다음과 같이 동작합니다.

  • 새 컨테이너 이미지의 경우 푸시한 직후에 크기 데이터를 사용할 수 있습니다.
  • 기존 컨테이너 이미지의 경우 크기 데이터를 백그라운드에서 계산하며, 최대 24시간이 걸릴 수 있습니다.

스토리지 데이터는 다음 시점에 업데이트됩니다.

  • 컨테이너 이미지를 푸시하거나 삭제하면 즉시 업데이트됩니다.
  • 다음 작업을 수행하면 실시간으로 업데이트됩니다.
  • 프로젝트의 컨테이너 리포지터리에서 태그를 푸시하거나 삭제할 때 업데이트됩니다.
  • 그룹의 경우 5분마다 업데이트됩니다.
Note

GitLab Self-Managed 인스턴스에서는 관리자가 메타데이터 데이터베이스를 활성화한 뒤에 스토리지 데이터를 사용할 수 있습니다. GitLab.com에서는 메타데이터 데이터베이스가 기본적으로 활성화되어 있습니다.

컨테이너 레지스트리 사용량 계산 방법#

컨테이너 레지스트리에 저장된 이미지 레이어는 루트 네임스페이스 수준에서 중복이 제거됩니다.

다음의 경우 이미지는 한 번만 계산됩니다.

  • 같은 리포지터리에서 같은 이미지에 태그를 두 번 이상 지정합니다.
  • 같은 루트 네임스페이스 아래의 서로 다른 리포지터리에서 같은 이미지에 태그를 지정합니다.

다음의 경우 이미지 레이어는 한 번만 계산됩니다.

  • 같은 컨테이너 리포지터리, 프로젝트, 그룹에 속한 여러 이미지에서 이미지 레이어를 공유합니다.
  • 서로 다른 리포지터리에서 이미지 레이어를 공유합니다.

태그가 지정된 이미지가 참조하는 레이어만 집계됩니다. 태그가 없는 이미지와 그 이미지만 참조하는 레이어는 온라인 가비지 컬렉션 대상입니다. 태그가 없는 이미지 레이어는 24시간 동안 참조되지 않은 상태로 남으면 자동으로 삭제됩니다.

이미지 레이어는 원래 형식(보통 압축된 형식)으로 스토리지 백엔드에 저장됩니다. 따라서 특정 이미지 레이어의 측정된 크기는 해당하는 이미지 매니페스트에 표시된 크기와 일치해야 합니다.

네임스페이스에 속한 컨테이너 리포지터리에서 태그를 푸시하거나 삭제하면 몇 분 후에 네임스페이스 사용량이 갱신됩니다.

지연된 새로 고침#

극도로 큰 네임스페이스(전체 네임스페이스의 약 1%)에서는 컨테이너 레지스트리 사용량을 실시간으로 최대 정밀도로 계산할 수 없습니다. 이러한 네임스페이스의 Maintainer가 사용량을 확인할 수 있도록 지연된 폴백 메커니즘이 있습니다. 자세한 내용은 에픽 9413을 참고합니다.

네임스페이스의 사용량을 정밀하게 계산할 수 없으면 GitLab은 지연 방식으로 폴백합니다. 지연 방식에서 표시되는 사용량 크기는 네임스페이스에 있는 모든 고유 이미지 레이어의 합계입니다. 태그가 없는 이미지 레이어도 무시되지 않습니다. 그 결과 태그를 삭제한 뒤에도 표시되는 사용량 크기가 크게 바뀌지 않을 수 있습니다. 대신 크기 값은 다음의 경우에만 바뀝니다.

  • 자동 가비지 컬렉션 프로세스가 실행되어 태그가 없는 이미지 레이어를 삭제합니다. 사용자가 태그를 삭제하면 24시간 후에 시작되도록 가비지 컬렉션 실행이 예약됩니다. 그 실행 중에 이전에 태그가 지정되어 있던 이미지를 분석하고, 다른 태그 지정 이미지가 참조하지 않는 레이어를 삭제합니다. 레이어가 삭제되면 네임스페이스 사용량이 업데이트됩니다.
  • 네임스페이스의 레지스트리 사용량이 충분히 줄어들어 GitLab이 최대 정밀도로 측정할 수 있게 됩니다. 네임스페이스의 사용량이 줄어들면 측정 방식이 지연 측정에서 정밀 측정으로 자동 전환됩니다. UI에서는 어느 측정 방식을 사용하는지 확인할 수 있는 곳이 없지만, 이슈 386468에서 이를 개선하자고 제안합니다.

정리 정책#

정리 정책은 컨테이너 레지스트리에서 태그를 제거하는 데 사용할 수 있는 예약된 job입니다. 정책이 정의된 프로젝트에서는 정규식 패턴과 일치하는 태그가 제거됩니다. 하위 레이어와 이미지는 그대로 남습니다.

태그와 연결되지 않은 하위 레이어와 이미지를 삭제하려면 관리자가 가비지 컬렉션을 -m 스위치와 함께 사용할 수 있습니다.

정리 정책 활성화#

Warning

성능상의 이유로, 컨테이너 이미지가 없는 프로젝트에서는 활성화된 정리 정책이 자동으로 비활성화됩니다.

정리 정책 작동 방식#

정리 정책은 컨테이너 레지스트리의 모든 태그를 수집한 뒤, 삭제할 태그만 남을 때까지 태그를 제외해 나갑니다.

정리 정책은 태그 이름을 기준으로 이미지를 검색합니다. 전체 경로 일치 지원은 이슈 281071에서 추적합니다.

정리 정책은 다음 순서로 동작합니다.

  1. 지정된 리포지터리의 모든 태그를 목록으로 수집합니다.
  2. latest라는 이름의 태그를 제외합니다.
  3. name_regex(만료할 태그)를 평가해 일치하지 않는 이름을 제외합니다.
  4. name_regex_keep 값(보존할 태그)과 일치하는 태그를 제외합니다.
  5. 매니페스트가 없는 태그를 제외합니다(UI의 옵션에는 포함되지 않습니다).
  6. 남은 태그를 created_date 기준으로 정렬합니다.
  7. keep_n 값(유지할 태그 수)을 기준으로 N개의 태그를 제외합니다.
  8. older_than 값(만료 간격)보다 최근인 태그를 제외합니다.
  9. 보호된 태그를 제외합니다.
  10. 불변 태그를 제외합니다.
  11. 목록에 남은 태그를 컨테이너 레지스트리에서 삭제합니다.
Warning

GitLab.com에서는 정리 정책의 실행 시간이 제한됩니다. 정책이 실행된 뒤에도 일부 태그가 컨테이너 레지스트리에 남을 수 있습니다. 정책이 다음에 실행될 때 남은 태그가 포함됩니다. 모든 태그를 삭제하는 데 여러 번의 실행이 필요할 수 있습니다.

GitLab Self-Managed 인스턴스는 Docker Registry HTTP API V2 규격을 준수하는 서드파티 컨테이너 레지스트리를 지원합니다. 그러나 이 규격에는 태그 삭제 작업이 없습니다. 따라서 GitLab은 서드파티 컨테이너 레지스트리와 상호작용할 때 태그를 삭제하기 위해 우회 방법을 사용합니다. 자세한 내용은 이슈 15737을 참고합니다. 구현 방식이 다를 수 있으므로 이 우회 방법이 모든 서드파티 레지스트리에서 같은 방식으로 예측 가능하게 동작한다고 보장할 수 없습니다. GitLab Container Registry를 사용하는 경우에는 GitLab이 전용 태그 삭제 작업을 구현했기 때문에 이 우회 방법이 필요하지 않습니다. 이 경우 정리 정책이 일관되고 예측 가능하게 동작한다고 기대할 수 있습니다.

정리 정책 워크플로 예시#

정리 정책의 유지 규칙과 제거 규칙 사이의 상호작용은 복잡할 수 있습니다. 예를 들어 다음과 같은 정리 정책 구성을 가진 프로젝트가 있습니다.

  • Keep the most recent: 이미지 이름당 태그 1개.
  • Keep tags matching: production-.*
  • Remove tags older than: 7일.
  • Remove tags matching: .*.

그리고 다음 태그가 있는 컨테이너 리포지터리가 있습니다.

  • latest, 2시간 전에 게시되었습니다.
  • production-v44, 3일 전에 게시되었습니다.
  • production-v43, 6일 전에 게시되었습니다.
  • production-v42, 11일 전에 게시되었습니다.
  • dev-v44, 2일 전에 게시되었습니다.
  • dev-v43, 5일 전에 게시되었습니다.
  • dev-v42, 10일 전에 게시되었습니다.
  • v44, 어제 게시되었습니다.
  • v43, 12일 전에 게시되었습니다.
  • v42, 20일 전에 게시되었습니다.

이 예시에서 다음 정리 실행 때 삭제될 태그는 dev-v42, v43, v42입니다. 규칙은 다음 우선순위로 적용된다고 이해할 수 있습니다.

  1. 유지 규칙이 가장 높은 우선순위를 가집니다. 어느 규칙이든 일치하면 태그를 유지해야 합니다.
    • latest 태그는 항상 유지되므로 유지해야 합니다.
    • production-v44, production-v43, production-v42 태그는 Keep tags matching 규칙에 일치하므로 유지해야 합니다.
    • v44 태그는 가장 최근 태그이므로 Keep the most recent 규칙에 따라 유지해야 합니다.
  2. 제거 규칙은 우선순위가 더 낮으며, 모든 규칙이 일치할 때만 태그가 삭제됩니다. 유지 규칙에 일치하지 않는 태그(dev-v44, dev-v43, dev-v42, v43, v42)의 경우는 다음과 같습니다.
    • dev-v44와 dev-v43은 Remove tags older than에 일치하지 않으므로 유지됩니다.
    • dev-v42, v43, v42는 Remove tags older than과 Remove tags matching 규칙에 모두 일치하므로 이 세 태그는 삭제될 수 있습니다.

정리 정책 만들기#

API 또는 UI에서 정리 정책을 만들 수 있습니다.

UI에서 정리 정책을 만들려면 다음 단계를 수행합니다.

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.

  2. 왼쪽 사이드바에서 Settings > Packages and registries를 선택합니다.

  3. Container registry를 확장합니다.

  4. Container registry cleanup policies에서 Set cleanup rules를 선택합니다.

  5. 다음 필드를 입력합니다.

    필드 설명
    Toggle 정책을 켜거나 끕니다.
    Run cleanup 정책을 실행할 빈도입니다.
    Keep the most recent 각 이미지에서 항상 유지할 태그 수입니다.
    Keep tags matching 보존할 태그를 결정하는 정규식 패턴입니다. latest 태그는 항상 보존됩니다. 모든 태그를 대상으로 하려면 .*를 사용합니다. 다른 정규식 패턴 예시도 참고합니다.
    Remove tags older than X일보다 오래된 태그만 제거합니다. 첫 정리에서 가장 오래된 이미지만 삭제되도록 큰 숫자로 시작해야 합니다. 정리 백그라운드 워커가 사용하는 리소스를 모니터링한 뒤 일수를 점차 줄일 수 있습니다.
    Remove tags matching 제거할 태그를 결정하는 정규식 패턴입니다. 이 값은 비워 둘 수 없습니다. 첫 정리에서 소수의 이미지만 삭제되도록 비교적 구체적인 정규식으로 시작해야 합니다. 정리 백그라운드 워커가 사용하는 리소스를 모니터링한 뒤, 모든 태그와 일치하는 .*까지 정규식을 더 일반적으로 조정합니다. 자세한 내용은 정규식 패턴 예시를 참고합니다.

    [!note] 유지 정규식 패턴과 제거 정규식 패턴 모두 자동으로 \A와 \Z 앵커로 감싸지므로 직접 넣지 않아도 됩니다. 다만 정규식 패턴을 선택하고 테스트할 때 이 점을 고려합니다.

  6. Save를 선택합니다.

정책은 선택한 예약 간격에 따라 실행됩니다.

Note

정책을 편집하고 Save를 다시 선택하면 간격이 초기화됩니다.

정규식 패턴 예시#

정리 정책은 UI와 API 모두에서 정규식 패턴으로 보존할 태그와 제거할 태그를 결정합니다.

GitLab은 정리 정책의 정규식에 RE2 구문을 사용합니다.

사용할 수 있는 정규식 패턴 예시는 다음과 같습니다.

  • 모든 태그와 일치:

    .*
    

    이 패턴은 만료 정규식의 기본값입니다.

  • v로 시작하는 태그와 일치:

    v.+
    
  • main이라는 이름의 태그만 일치:

    main
    
  • 이름이 release이거나 release로 시작하는 태그와 일치:

    release.*
    
  • v로 시작하거나, 이름이 main이거나, release로 시작하는 태그와 일치:

    (?:v.+|main|release.*)
    

리소스 절약을 위한 정리 제한 설정#

정리 정책은 백그라운드 프로세스로 실행됩니다. 삭제할 태그 수에 따라 프로세스가 완료되는 데 시간이 걸릴 수 있습니다.

서버 리소스 고갈을 막기 위해 다음 애플리케이션 설정을 사용할 수 있습니다.

애플리케이션 설정 유형 설명
container_registry_expiration_policies_worker_capacity integer 동시에 실행되는 최대 정리 워커 수입니다. 기본값은 4입니다. 이 값을 0으로 설정하면 모든 워커를 제거하고 정리 정책 실행을 중지합니다. 낮은 숫자로 시작한 뒤 백그라운드 워커가 사용하는 리소스를 모니터링하고 늘립니다.
container_registry_delete_tags_service_timeout integer 정리 프로세스가 태그 배치를 삭제하는 데 걸릴 수 있는 최대 시간(초)입니다. 기본값은 250입니다.
container_registry_cleanup_tags_service_max_list_size integer 한 번의 실행에서 삭제할 수 있는 최대 태그 수입니다. 기본값은 200입니다. 추가 태그는 다른 실행에서 삭제해야 합니다. 낮은 숫자로 시작한 뒤 컨테이너 이미지가 올바르게 삭제되는지 확인하고 늘립니다.
container_registry_expiration_policies_caching boolean 정책 실행 중 태그 생성 타임스탬프 캐싱 여부입니다. 기본값은 true입니다. 캐시된 타임스탬프는 Redis에 저장됩니다.

사전 요구 사항:

  • 관리자 액세스 권한이 필요합니다.

이러한 설정은 Rails 콘솔에서 변경할 수 있습니다. 예를 들면 다음과 같습니다.

ApplicationSetting.last.update(container_registry_expiration_policies_worker_capacity: 3)

Admin 영역에서 이러한 설정을 변경하려면 다음 단계를 수행합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > CI/CD를 선택합니다.
  3. Container Registry를 확장합니다.

정리 정책 API 사용#

GitLab API로 정리 정책을 설정, 업데이트, 비활성화할 수 있습니다.

예시는 다음과 같습니다.

  • 모든 태그를 선택하고, 이미지당 최소 1개의 태그를 유지하고, 14일보다 오래된 태그를 정리하고, 한 달에 한 번 실행하고, 이름이 main인 이미지는 보존하며, 정책은 활성화된 상태입니다.

    curl --fail-with-body --request PUT --header 'Content-Type: application/json;charset=UTF-8'
         --header "PRIVATE-TOKEN: <your_access_token>" \
         --data-binary '{"container_expiration_policy_attributes":{"cadence":"1month","enabled":true,"keep_n":1,"older_than":"14d","name_regex":".*","name_regex_keep":".*-main"}}' \
         "https://gitlab.example.com/api/v4/projects/2"
    

API를 사용할 때 cadence에 유효한 값은 다음과 같습니다.

  • 1d(매일)
  • 7d(매주)
  • 14d(2주마다)
  • 1month(매월)
  • 3month(분기마다)

API를 사용할 때 keep_n(이미지 이름당 유지하는 태그 수)에 유효한 값은 다음과 같습니다.

  • 1
  • 5
  • 10
  • 25
  • 50
  • 100

API를 사용할 때 older_than(태그가 자동으로 제거되기까지의 일수)에 유효한 값은 다음과 같습니다.

  • 1d
  • 3d
  • 7d
  • 14d
  • 30d
  • 60d
  • 90d
  • 180d
  • 365d
  • 730d
  • 1095d

자세한 내용은 API 문서 프로젝트 편집 API를 참고합니다.

외부 컨테이너 레지스트리와 함께 사용#

외부 컨테이너 레지스트리를 사용할 때 프로젝트에서 정리 정책을 실행하면 성능 위험이 있을 수 있습니다. 프로젝트가 수천 개의 태그를 제거하는 정책을 실행하면 GitLab 백그라운드 job이 밀리거나 완전히 실패할 수 있습니다.

컨테이너 레지스트리 스토리지 추가 감소 옵션#

프로젝트가 사용하는 컨테이너 레지스트리 스토리지를 줄이는 데 사용할 수 있는 다른 옵션은 다음과 같습니다.

문제 해결#

스토리지 크기를 사용할 수 없음#

컨테이너 레지스트리 스토리지 크기 정보를 볼 수 없는 경우 다음 단계를 수행합니다.

  1. 관리자에게 메타데이터 데이터베이스가 올바르게 구성되었는지 확인해 달라고 요청합니다.

  2. 레지스트리 스토리지 백엔드가 올바르게 구성되어 접근할 수 있는지 확인합니다.

  3. 레지스트리 로그에서 스토리지 관련 오류를 확인합니다.

    sudo gitlab-ctl tail registry
    

Something went wrong while updating the cleanup policy.#

이 오류 메시지가 보이면 정규식 패턴이 유효한지 확인합니다.

regex101 정규식 테스터에서 Golang 플레이버로 테스트할 수 있습니다. 일반적인 정규식 패턴 예시를 확인합니다.

정리 정책이 태그를 삭제하지 않음#

여기에는 여러 가지 원인이 있을 수 있습니다.

  • GitLab Self-Managed를 사용하고 컨테이너 리포지터리에 태그가 1,000개 이상 있으면 Container Registry 토큰 만료 문제가 발생해 로그에 error authorizing context: invalid token이 나타날 수 있습니다.

    이를 해결하는 우회 방법은 두 가지입니다.

또는 삭제할 태그 목록을 만들고 그 목록으로 태그를 삭제할 수 있습니다. 목록을 만들고 태그를 삭제하려면 다음 단계를 수행합니다.

  1. 다음 셸 스크립트를 실행합니다. for 루프 바로 앞의 명령은 루프를 시작할 때 list_o_tags.out이 항상 다시 초기화되도록 합니다. 이 명령을 실행하면 모든 태그 이름이 list_o_tags.out 파일에 기록됩니다.

    # Get a list of all tags in a certain container repository while considering [pagination](../../../api/rest/_index.md#pagination)
    echo -n "" > list_o_tags.out; for i in {1..N}; do curl --fail-with-body --header 'PRIVATE-TOKEN: ' "https://gitlab.example.com/api/v4/projects//registry/repositories/<container_repo_id>/tags?per_page=100&page=${i}" | jq '.[].name' | sed 's:^.\(.*\).$:\1:' >> list_o_tags.out; done
    

    Rails 콘솔에 액세스할 수 있으면 다음 명령을 입력해 날짜로 제한된 태그 목록을 가져올 수 있습니다.

    output = File.open( "/tmp/list_o_tags.out","w" )
    Project.find().container_repositories.find(<container_repo_id>).tags.each do |tag|
      output << tag.name + "\n" if tag.created_at < 1.month.ago
    end;nil
    output.close
    

    이 명령 모음은 created_at 날짜가 한 달보다 오래된 모든 태그를 나열하는 /tmp/list_o_tags.out 파일을 만듭니다.

  2. 유지하려는 태그는 list_o_tags.out 파일에서 제거합니다. 예를 들어 sed로 파일을 파싱해 태그를 제거할 수 있습니다.

   # Remove the `latest` tag from the file
   sed -i '/latest/d' list_o_tags.out

   # Remove the first N tags from the file
   sed -i '1,Nd' list_o_tags.out

   # Remove the tags starting with `Av` from the file
   sed -i '/^Av/d' list_o_tags.out

   # Remove the tags ending with `_v3` from the file
   sed -i '/_v3$/d' list_o_tags.out
   # Remove the `latest` tag from the file
   sed -i .bak '/latest/d' list_o_tags.out

   # Remove the first N tags from the file
   sed -i .bak '1,Nd' list_o_tags.out

   # Remove the tags starting with `Av` from the file
   sed -i .bak '/^Av/d' list_o_tags.out

   # Remove the tags ending with `_v3` from the file
   sed -i .bak '/_v3$/d' list_o_tags.out
  1. list_o_tags.out 파일을 다시 확인해 삭제하려는 태그만 들어 있는지 확인합니다.

  2. 다음 셸 스크립트를 실행해 list_o_tags.out 파일에 있는 태그를 삭제합니다.

    # loop over list_o_tags.out to delete a single tag at a time
    while read -r LINE || [[ -n $LINE ]]; do echo ${LINE}; curl --fail-with-body --request DELETE --header 'PRIVATE-TOKEN: ' "https://gitlab.example.com/api/v4/projects//registry/repositories/<container_repo_id>/tags/${LINE}"; sleep 0.1; echo; done < list_o_tags.out > delete.logs
    

컨테이너 레지스트리 스토리지 줄이기

GitLab v19.5
Tier: Free, Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기

요약

레지스트리 사용량을 관리하지 않으면 컨테이너 레지스트리는 시간이 지나면서 크기가 커질 수 있습니다. 불필요한 이미지와 태그를 삭제하고 컨테이너 레지스트리 정리 정책을 설정해 컨테이너 레지스트리 사용량을 자동으로 관리해야 합니다.

레지스트리 사용량을 관리하지 않으면 컨테이너 레지스트리는 시간이 지나면서 크기가 커질 수 있습니다. 예를 들어 이미지나 태그를 많이 추가하면 다음과 같은 일이 발생합니다.

  • 사용 가능한 태그나 이미지 목록을 가져오는 속도가 느려집니다.
  • 서버에서 많은 스토리지 공간을 차지합니다.

불필요한 이미지와 태그를 삭제하고 컨테이너 레지스트리 정리 정책을 설정해 컨테이너 레지스트리 사용량을 자동으로 관리해야 합니다.

컨테이너 레지스트리 사용량 보기#

컨테이너 레지스트리 리포지터리의 스토리지 사용량 데이터를 봅니다.

프로젝트의 경우#

사전 요구 사항:

프로젝트의 스토리지 사용량을 보려면 다음 단계를 수행합니다.

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. 다음 중 하나를 수행합니다.
    • 전체 스토리지 사용량을 보려면 Settings > Usage quotas를 선택합니다. Namespace entities에서 Container Registry를 선택해 개별 리포지터리를 봅니다.
    • 리포지터리별 스토리지 사용량을 바로 보려면 Deploy > Container Registry를 선택합니다.

다음 방법도 사용할 수 있습니다.

그룹의 경우#

사전 요구 사항:

그룹의 스토리지 사용량을 보려면 다음 단계를 수행합니다.

  1. 상단 바에서 Search or go to를 선택하고 그룹을 찾습니다.
  2. 왼쪽 사이드바에서 Settings > Usage quotas를 선택합니다.
  3. Storage 탭을 선택합니다.

Groups API로 그룹에 속한 모든 프로젝트의 전체 컨테이너 레지스트리 스토리지를 가져올 수도 있습니다.

스토리지 데이터 업데이트#

메타데이터 데이터베이스를 활성화한 뒤에는 다음과 같이 동작합니다.

  • 새 컨테이너 이미지의 경우 푸시한 직후에 크기 데이터를 사용할 수 있습니다.
  • 기존 컨테이너 이미지의 경우 크기 데이터를 백그라운드에서 계산하며, 최대 24시간이 걸릴 수 있습니다.

스토리지 데이터는 다음 시점에 업데이트됩니다.

  • 컨테이너 이미지를 푸시하거나 삭제하면 즉시 업데이트됩니다.
  • 다음 작업을 수행하면 실시간으로 업데이트됩니다.
  • 프로젝트의 컨테이너 리포지터리에서 태그를 푸시하거나 삭제할 때 업데이트됩니다.
  • 그룹의 경우 5분마다 업데이트됩니다.
Note

GitLab Self-Managed 인스턴스에서는 관리자가 메타데이터 데이터베이스를 활성화한 뒤에 스토리지 데이터를 사용할 수 있습니다. GitLab.com에서는 메타데이터 데이터베이스가 기본적으로 활성화되어 있습니다.

컨테이너 레지스트리 사용량 계산 방법#

컨테이너 레지스트리에 저장된 이미지 레이어는 루트 네임스페이스 수준에서 중복이 제거됩니다.

다음의 경우 이미지는 한 번만 계산됩니다.

  • 같은 리포지터리에서 같은 이미지에 태그를 두 번 이상 지정합니다.
  • 같은 루트 네임스페이스 아래의 서로 다른 리포지터리에서 같은 이미지에 태그를 지정합니다.

다음의 경우 이미지 레이어는 한 번만 계산됩니다.

  • 같은 컨테이너 리포지터리, 프로젝트, 그룹에 속한 여러 이미지에서 이미지 레이어를 공유합니다.
  • 서로 다른 리포지터리에서 이미지 레이어를 공유합니다.

태그가 지정된 이미지가 참조하는 레이어만 집계됩니다. 태그가 없는 이미지와 그 이미지만 참조하는 레이어는 온라인 가비지 컬렉션 대상입니다. 태그가 없는 이미지 레이어는 24시간 동안 참조되지 않은 상태로 남으면 자동으로 삭제됩니다.

이미지 레이어는 원래 형식(보통 압축된 형식)으로 스토리지 백엔드에 저장됩니다. 따라서 특정 이미지 레이어의 측정된 크기는 해당하는 이미지 매니페스트에 표시된 크기와 일치해야 합니다.

네임스페이스에 속한 컨테이너 리포지터리에서 태그를 푸시하거나 삭제하면 몇 분 후에 네임스페이스 사용량이 갱신됩니다.

지연된 새로 고침#

극도로 큰 네임스페이스(전체 네임스페이스의 약 1%)에서는 컨테이너 레지스트리 사용량을 실시간으로 최대 정밀도로 계산할 수 없습니다. 이러한 네임스페이스의 Maintainer가 사용량을 확인할 수 있도록 지연된 폴백 메커니즘이 있습니다. 자세한 내용은 에픽 9413을 참고합니다.

네임스페이스의 사용량을 정밀하게 계산할 수 없으면 GitLab은 지연 방식으로 폴백합니다. 지연 방식에서 표시되는 사용량 크기는 네임스페이스에 있는 모든 고유 이미지 레이어의 합계입니다. 태그가 없는 이미지 레이어도 무시되지 않습니다. 그 결과 태그를 삭제한 뒤에도 표시되는 사용량 크기가 크게 바뀌지 않을 수 있습니다. 대신 크기 값은 다음의 경우에만 바뀝니다.

  • 자동 가비지 컬렉션 프로세스가 실행되어 태그가 없는 이미지 레이어를 삭제합니다. 사용자가 태그를 삭제하면 24시간 후에 시작되도록 가비지 컬렉션 실행이 예약됩니다. 그 실행 중에 이전에 태그가 지정되어 있던 이미지를 분석하고, 다른 태그 지정 이미지가 참조하지 않는 레이어를 삭제합니다. 레이어가 삭제되면 네임스페이스 사용량이 업데이트됩니다.
  • 네임스페이스의 레지스트리 사용량이 충분히 줄어들어 GitLab이 최대 정밀도로 측정할 수 있게 됩니다. 네임스페이스의 사용량이 줄어들면 측정 방식이 지연 측정에서 정밀 측정으로 자동 전환됩니다. UI에서는 어느 측정 방식을 사용하는지 확인할 수 있는 곳이 없지만, 이슈 386468에서 이를 개선하자고 제안합니다.

정리 정책#

정리 정책은 컨테이너 레지스트리에서 태그를 제거하는 데 사용할 수 있는 예약된 job입니다. 정책이 정의된 프로젝트에서는 정규식 패턴과 일치하는 태그가 제거됩니다. 하위 레이어와 이미지는 그대로 남습니다.

태그와 연결되지 않은 하위 레이어와 이미지를 삭제하려면 관리자가 가비지 컬렉션을 -m 스위치와 함께 사용할 수 있습니다.

정리 정책 활성화#

Warning

성능상의 이유로, 컨테이너 이미지가 없는 프로젝트에서는 활성화된 정리 정책이 자동으로 비활성화됩니다.

정리 정책 작동 방식#

정리 정책은 컨테이너 레지스트리의 모든 태그를 수집한 뒤, 삭제할 태그만 남을 때까지 태그를 제외해 나갑니다.

정리 정책은 태그 이름을 기준으로 이미지를 검색합니다. 전체 경로 일치 지원은 이슈 281071에서 추적합니다.

정리 정책은 다음 순서로 동작합니다.

  1. 지정된 리포지터리의 모든 태그를 목록으로 수집합니다.
  2. latest라는 이름의 태그를 제외합니다.
  3. name_regex(만료할 태그)를 평가해 일치하지 않는 이름을 제외합니다.
  4. name_regex_keep 값(보존할 태그)과 일치하는 태그를 제외합니다.
  5. 매니페스트가 없는 태그를 제외합니다(UI의 옵션에는 포함되지 않습니다).
  6. 남은 태그를 created_date 기준으로 정렬합니다.
  7. keep_n 값(유지할 태그 수)을 기준으로 N개의 태그를 제외합니다.
  8. older_than 값(만료 간격)보다 최근인 태그를 제외합니다.
  9. 보호된 태그를 제외합니다.
  10. 불변 태그를 제외합니다.
  11. 목록에 남은 태그를 컨테이너 레지스트리에서 삭제합니다.
Warning

GitLab.com에서는 정리 정책의 실행 시간이 제한됩니다. 정책이 실행된 뒤에도 일부 태그가 컨테이너 레지스트리에 남을 수 있습니다. 정책이 다음에 실행될 때 남은 태그가 포함됩니다. 모든 태그를 삭제하는 데 여러 번의 실행이 필요할 수 있습니다.

GitLab Self-Managed 인스턴스는 Docker Registry HTTP API V2 규격을 준수하는 서드파티 컨테이너 레지스트리를 지원합니다. 그러나 이 규격에는 태그 삭제 작업이 없습니다. 따라서 GitLab은 서드파티 컨테이너 레지스트리와 상호작용할 때 태그를 삭제하기 위해 우회 방법을 사용합니다. 자세한 내용은 이슈 15737을 참고합니다. 구현 방식이 다를 수 있으므로 이 우회 방법이 모든 서드파티 레지스트리에서 같은 방식으로 예측 가능하게 동작한다고 보장할 수 없습니다. GitLab Container Registry를 사용하는 경우에는 GitLab이 전용 태그 삭제 작업을 구현했기 때문에 이 우회 방법이 필요하지 않습니다. 이 경우 정리 정책이 일관되고 예측 가능하게 동작한다고 기대할 수 있습니다.

정리 정책 워크플로 예시#

정리 정책의 유지 규칙과 제거 규칙 사이의 상호작용은 복잡할 수 있습니다. 예를 들어 다음과 같은 정리 정책 구성을 가진 프로젝트가 있습니다.

  • Keep the most recent: 이미지 이름당 태그 1개.
  • Keep tags matching: production-.*
  • Remove tags older than: 7일.
  • Remove tags matching: .*.

그리고 다음 태그가 있는 컨테이너 리포지터리가 있습니다.

  • latest, 2시간 전에 게시되었습니다.
  • production-v44, 3일 전에 게시되었습니다.
  • production-v43, 6일 전에 게시되었습니다.
  • production-v42, 11일 전에 게시되었습니다.
  • dev-v44, 2일 전에 게시되었습니다.
  • dev-v43, 5일 전에 게시되었습니다.
  • dev-v42, 10일 전에 게시되었습니다.
  • v44, 어제 게시되었습니다.
  • v43, 12일 전에 게시되었습니다.
  • v42, 20일 전에 게시되었습니다.

이 예시에서 다음 정리 실행 때 삭제될 태그는 dev-v42, v43, v42입니다. 규칙은 다음 우선순위로 적용된다고 이해할 수 있습니다.

  1. 유지 규칙이 가장 높은 우선순위를 가집니다. 어느 규칙이든 일치하면 태그를 유지해야 합니다.
    • latest 태그는 항상 유지되므로 유지해야 합니다.
    • production-v44, production-v43, production-v42 태그는 Keep tags matching 규칙에 일치하므로 유지해야 합니다.
    • v44 태그는 가장 최근 태그이므로 Keep the most recent 규칙에 따라 유지해야 합니다.
  2. 제거 규칙은 우선순위가 더 낮으며, 모든 규칙이 일치할 때만 태그가 삭제됩니다. 유지 규칙에 일치하지 않는 태그(dev-v44, dev-v43, dev-v42, v43, v42)의 경우는 다음과 같습니다.
    • dev-v44와 dev-v43은 Remove tags older than에 일치하지 않으므로 유지됩니다.
    • dev-v42, v43, v42는 Remove tags older than과 Remove tags matching 규칙에 모두 일치하므로 이 세 태그는 삭제될 수 있습니다.

정리 정책 만들기#

API 또는 UI에서 정리 정책을 만들 수 있습니다.

UI에서 정리 정책을 만들려면 다음 단계를 수행합니다.

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.

  2. 왼쪽 사이드바에서 Settings > Packages and registries를 선택합니다.

  3. Container registry를 확장합니다.

  4. Container registry cleanup policies에서 Set cleanup rules를 선택합니다.

  5. 다음 필드를 입력합니다.

    필드 설명
    Toggle 정책을 켜거나 끕니다.
    Run cleanup 정책을 실행할 빈도입니다.
    Keep the most recent 각 이미지에서 항상 유지할 태그 수입니다.
    Keep tags matching 보존할 태그를 결정하는 정규식 패턴입니다. latest 태그는 항상 보존됩니다. 모든 태그를 대상으로 하려면 .*를 사용합니다. 다른 정규식 패턴 예시도 참고합니다.
    Remove tags older than X일보다 오래된 태그만 제거합니다. 첫 정리에서 가장 오래된 이미지만 삭제되도록 큰 숫자로 시작해야 합니다. 정리 백그라운드 워커가 사용하는 리소스를 모니터링한 뒤 일수를 점차 줄일 수 있습니다.
    Remove tags matching 제거할 태그를 결정하는 정규식 패턴입니다. 이 값은 비워 둘 수 없습니다. 첫 정리에서 소수의 이미지만 삭제되도록 비교적 구체적인 정규식으로 시작해야 합니다. 정리 백그라운드 워커가 사용하는 리소스를 모니터링한 뒤, 모든 태그와 일치하는 .*까지 정규식을 더 일반적으로 조정합니다. 자세한 내용은 정규식 패턴 예시를 참고합니다.

    [!note] 유지 정규식 패턴과 제거 정규식 패턴 모두 자동으로 \A와 \Z 앵커로 감싸지므로 직접 넣지 않아도 됩니다. 다만 정규식 패턴을 선택하고 테스트할 때 이 점을 고려합니다.

  6. Save를 선택합니다.

정책은 선택한 예약 간격에 따라 실행됩니다.

Note

정책을 편집하고 Save를 다시 선택하면 간격이 초기화됩니다.

정규식 패턴 예시#

정리 정책은 UI와 API 모두에서 정규식 패턴으로 보존할 태그와 제거할 태그를 결정합니다.

GitLab은 정리 정책의 정규식에 RE2 구문을 사용합니다.

사용할 수 있는 정규식 패턴 예시는 다음과 같습니다.

  • 모든 태그와 일치:

    .*
    

    이 패턴은 만료 정규식의 기본값입니다.

  • v로 시작하는 태그와 일치:

    v.+
    
  • main이라는 이름의 태그만 일치:

    main
    
  • 이름이 release이거나 release로 시작하는 태그와 일치:

    release.*
    
  • v로 시작하거나, 이름이 main이거나, release로 시작하는 태그와 일치:

    (?:v.+|main|release.*)
    

리소스 절약을 위한 정리 제한 설정#

정리 정책은 백그라운드 프로세스로 실행됩니다. 삭제할 태그 수에 따라 프로세스가 완료되는 데 시간이 걸릴 수 있습니다.

서버 리소스 고갈을 막기 위해 다음 애플리케이션 설정을 사용할 수 있습니다.

애플리케이션 설정 유형 설명
container_registry_expiration_policies_worker_capacity integer 동시에 실행되는 최대 정리 워커 수입니다. 기본값은 4입니다. 이 값을 0으로 설정하면 모든 워커를 제거하고 정리 정책 실행을 중지합니다. 낮은 숫자로 시작한 뒤 백그라운드 워커가 사용하는 리소스를 모니터링하고 늘립니다.
container_registry_delete_tags_service_timeout integer 정리 프로세스가 태그 배치를 삭제하는 데 걸릴 수 있는 최대 시간(초)입니다. 기본값은 250입니다.
container_registry_cleanup_tags_service_max_list_size integer 한 번의 실행에서 삭제할 수 있는 최대 태그 수입니다. 기본값은 200입니다. 추가 태그는 다른 실행에서 삭제해야 합니다. 낮은 숫자로 시작한 뒤 컨테이너 이미지가 올바르게 삭제되는지 확인하고 늘립니다.
container_registry_expiration_policies_caching boolean 정책 실행 중 태그 생성 타임스탬프 캐싱 여부입니다. 기본값은 true입니다. 캐시된 타임스탬프는 Redis에 저장됩니다.

사전 요구 사항:

  • 관리자 액세스 권한이 필요합니다.

이러한 설정은 Rails 콘솔에서 변경할 수 있습니다. 예를 들면 다음과 같습니다.

ApplicationSetting.last.update(container_registry_expiration_policies_worker_capacity: 3)

Admin 영역에서 이러한 설정을 변경하려면 다음 단계를 수행합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > CI/CD를 선택합니다.
  3. Container Registry를 확장합니다.

정리 정책 API 사용#

GitLab API로 정리 정책을 설정, 업데이트, 비활성화할 수 있습니다.

예시는 다음과 같습니다.

  • 모든 태그를 선택하고, 이미지당 최소 1개의 태그를 유지하고, 14일보다 오래된 태그를 정리하고, 한 달에 한 번 실행하고, 이름이 main인 이미지는 보존하며, 정책은 활성화된 상태입니다.

    curl --fail-with-body --request PUT --header 'Content-Type: application/json;charset=UTF-8'
         --header "PRIVATE-TOKEN: <your_access_token>" \
         --data-binary '{"container_expiration_policy_attributes":{"cadence":"1month","enabled":true,"keep_n":1,"older_than":"14d","name_regex":".*","name_regex_keep":".*-main"}}' \
         "https://gitlab.example.com/api/v4/projects/2"
    

API를 사용할 때 cadence에 유효한 값은 다음과 같습니다.

  • 1d(매일)
  • 7d(매주)
  • 14d(2주마다)
  • 1month(매월)
  • 3month(분기마다)

API를 사용할 때 keep_n(이미지 이름당 유지하는 태그 수)에 유효한 값은 다음과 같습니다.

  • 1
  • 5
  • 10
  • 25
  • 50
  • 100

API를 사용할 때 older_than(태그가 자동으로 제거되기까지의 일수)에 유효한 값은 다음과 같습니다.

  • 1d
  • 3d
  • 7d
  • 14d
  • 30d
  • 60d
  • 90d
  • 180d
  • 365d
  • 730d
  • 1095d

자세한 내용은 API 문서 프로젝트 편집 API를 참고합니다.

외부 컨테이너 레지스트리와 함께 사용#

외부 컨테이너 레지스트리를 사용할 때 프로젝트에서 정리 정책을 실행하면 성능 위험이 있을 수 있습니다. 프로젝트가 수천 개의 태그를 제거하는 정책을 실행하면 GitLab 백그라운드 job이 밀리거나 완전히 실패할 수 있습니다.

컨테이너 레지스트리 스토리지 추가 감소 옵션#

프로젝트가 사용하는 컨테이너 레지스트리 스토리지를 줄이는 데 사용할 수 있는 다른 옵션은 다음과 같습니다.

문제 해결#

스토리지 크기를 사용할 수 없음#

컨테이너 레지스트리 스토리지 크기 정보를 볼 수 없는 경우 다음 단계를 수행합니다.

  1. 관리자에게 메타데이터 데이터베이스가 올바르게 구성되었는지 확인해 달라고 요청합니다.

  2. 레지스트리 스토리지 백엔드가 올바르게 구성되어 접근할 수 있는지 확인합니다.

  3. 레지스트리 로그에서 스토리지 관련 오류를 확인합니다.

    sudo gitlab-ctl tail registry
    

Something went wrong while updating the cleanup policy.#

이 오류 메시지가 보이면 정규식 패턴이 유효한지 확인합니다.

regex101 정규식 테스터에서 Golang 플레이버로 테스트할 수 있습니다. 일반적인 정규식 패턴 예시를 확인합니다.

정리 정책이 태그를 삭제하지 않음#

여기에는 여러 가지 원인이 있을 수 있습니다.

  • GitLab Self-Managed를 사용하고 컨테이너 리포지터리에 태그가 1,000개 이상 있으면 Container Registry 토큰 만료 문제가 발생해 로그에 error authorizing context: invalid token이 나타날 수 있습니다.

    이를 해결하는 우회 방법은 두 가지입니다.

또는 삭제할 태그 목록을 만들고 그 목록으로 태그를 삭제할 수 있습니다. 목록을 만들고 태그를 삭제하려면 다음 단계를 수행합니다.

  1. 다음 셸 스크립트를 실행합니다. for 루프 바로 앞의 명령은 루프를 시작할 때 list_o_tags.out이 항상 다시 초기화되도록 합니다. 이 명령을 실행하면 모든 태그 이름이 list_o_tags.out 파일에 기록됩니다.

    # Get a list of all tags in a certain container repository while considering [pagination](../../../api/rest/_index.md#pagination)
    echo -n "" > list_o_tags.out; for i in {1..N}; do curl --fail-with-body --header 'PRIVATE-TOKEN: ' "https://gitlab.example.com/api/v4/projects//registry/repositories/<container_repo_id>/tags?per_page=100&page=${i}" | jq '.[].name' | sed 's:^.\(.*\).$:\1:' >> list_o_tags.out; done
    

    Rails 콘솔에 액세스할 수 있으면 다음 명령을 입력해 날짜로 제한된 태그 목록을 가져올 수 있습니다.

    output = File.open( "/tmp/list_o_tags.out","w" )
    Project.find().container_repositories.find(<container_repo_id>).tags.each do |tag|
      output << tag.name + "\n" if tag.created_at < 1.month.ago
    end;nil
    output.close
    

    이 명령 모음은 created_at 날짜가 한 달보다 오래된 모든 태그를 나열하는 /tmp/list_o_tags.out 파일을 만듭니다.

  2. 유지하려는 태그는 list_o_tags.out 파일에서 제거합니다. 예를 들어 sed로 파일을 파싱해 태그를 제거할 수 있습니다.

   # Remove the `latest` tag from the file
   sed -i '/latest/d' list_o_tags.out

   # Remove the first N tags from the file
   sed -i '1,Nd' list_o_tags.out

   # Remove the tags starting with `Av` from the file
   sed -i '/^Av/d' list_o_tags.out

   # Remove the tags ending with `_v3` from the file
   sed -i '/_v3$/d' list_o_tags.out
   # Remove the `latest` tag from the file
   sed -i .bak '/latest/d' list_o_tags.out

   # Remove the first N tags from the file
   sed -i .bak '1,Nd' list_o_tags.out

   # Remove the tags starting with `Av` from the file
   sed -i .bak '/^Av/d' list_o_tags.out

   # Remove the tags ending with `_v3` from the file
   sed -i .bak '/_v3$/d' list_o_tags.out
  1. list_o_tags.out 파일을 다시 확인해 삭제하려는 태그만 들어 있는지 확인합니다.

  2. 다음 셸 스크립트를 실행해 list_o_tags.out 파일에 있는 태그를 삭제합니다.

    # loop over list_o_tags.out to delete a single tag at a time
    while read -r LINE || [[ -n $LINE ]]; do echo ${LINE}; curl --fail-with-body --request DELETE --header 'PRIVATE-TOKEN: ' "https://gitlab.example.com/api/v4/projects//registry/repositories/<container_repo_id>/tags/${LINE}"; sleep 0.1; echo; done < list_o_tags.out > delete.logs