컨테이너 레지스트리 저장 공간 줄이기 (FREE ALL)

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-Managed, GitLab Dedicated

컨테이너 레지스트리는 레지스트리 사용량을 관리하지 않으면 시간이 지남에 따라 크기가 계속 커질 수 있습니다. 예를 들어, 많은 이미지 또는 태그를 추가하는 경우:

  • 사용 가능한 태그 또는 이미지 디렉터리 검색이 느려집니다.
  • 서버의 저장 공간을 많이 차지합니다.

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

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

Tier: Free, Premium, Ultimate Offering: GitLab.com

컨테이너 레지스트리의 저장 공간 사용량을 보려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > 사용량 할당을 선택합니다.

Self-Managed형 인스턴스의 경우 컨테이너 레지스트리 사용량을 볼 수 없지만, 이에 대한 제안이 epic 5521에서 제안되었습니다.

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

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

이미지는 다음과 같은 경우에만 하나로 계산됩니다:

  • 동일한 이미지를 동일한 리포지터리에서 여러 번 태그합니다.
  • 동일한 이미지를 동일한 루트 네임스페이스 하에 있는 다른 리포지터리에 태그합니다.

이미지 레이어는 다음과 같은 경우에만 하나로 계산됩니다:

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

태그가 지정된 이미지에만 참조되는 레이어만 계산됩니다. 태그가 지정되지 않은 이미지 및 해당 레이어는 온라인 가비지 수집의 대상입니다. 태그가 지정되지 않은 이미지 레이어는 그 기간 동안 참조되지 않는 경우 24시간 후에 자동으로 삭제됩니다.

이미지 레이어는 일반적으로 원본(일반적으로 압축된) 형식으로 저장 공간 백엔드에 저장됩니다. 따라서 특정 이미지 레이어의 메트릭된 크기는 해당 이미지 매니페스트에 표시된 크기와 일치해야 합니다.

네임스페이스 사용량은 태그가 프로젝트 또는 그룹의 모든 컨테이너 리포지터리에서 푸시되거나 삭제된 후 몇 분 후에 새로 고쳐집니다.

지연된 새로 고침

실시간으로 매우 큰 네임스페이스(네임스페이스의 약 1%)의 컨테이너 레지스트리 사용량을 최대 정밀도로 계산하는 것은 불가능합니다. 이러한 네임스페이스의 유지 관리자가 사용량을 볼 수 있도록 하기 위해 지연된 대체 메커니즘이 있습니다. 자세한 내용은 이슈 9413을 참조하십시오.

네임스페이스의 사용량을 정밀하게 계산할 수 없는 경우 GitLab은 지연된 방법으로 되돌아갑니다. 지연된 방법에서 표시된 사용량 크기는 해당 네임스페이스의 모든 고유 이미지 레이어의 합계입니다. 태그가 지정되지 않은 이미지 레이어는 무시되지 않습니다. 결과적으로 표시된 사용량 크기는 태그를 삭제한 후에 크게 변하지 않을 수 있습니다. 대신, 사용량 값은 다음과 같은 경우에만 변경됩니다:

  • 자동 가비지 수집 프로세스가 실행되어 태그가 삭제됩니다. 사용자가 태그를 삭제한 후 24시간 후에 가비지 수집 실행이 예약됩니다. 해당 실행 중에 이전에 태그되었던 이미지가 분석되고, 다른 태그된 이미지에서 참조되지 않는 경우 해당 레이어가 삭제됩니다. 레이어가 삭제되면 네임스페이스 사용량이 업데이트됩니다.
  • 네임스페이스의 레지스트리 사용량이 제한 미만으로 축소되어 정밀한 사용량 메트릭이 가능해집니다. 정밀 사용량 메트릭으로 자동 전환됩니다. 사용자 인터페이스(UI)에는 사용 중인 메트릭 방법을 확인할 수있는 곳이 없지만, 이슈 386468에서 이를 개선할 것을 제안하였습니다.

정리 정책

정리 정책은 컨테이너 레지스트리에서 태그를 제거하는 예약 작업입니다. 정책이 정의된 프로젝트에서 정규표현식 패턴과 일치하는 태그가 제거됩니다. 그러나 해당하는 레이어와 이미지는 그대로 남습니다.

태그와 관련이 없는 레이어 및 이미지를 삭제하려면 관리자가 가비지 수집-m 스위치와 함께 사용할 수 있습니다.

정리 정책 활성화

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

정리 정책 작동 방식

정리 정책은 컨테이너 레지스트리에 있는 모든 태그를 수집하고, 삭제할 태그만 남을 때까지 태그를 제외합니다.

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

정리 정책:

  1. 주어진 리포지터리에 모든 태그를 디렉터리으로 수집합니다.
  2. 최신 태그를 제외합니다.
  3. name_regex (만료될 태그)를 평가하고 일치하지 않는 이름을 제외합니다.
  4. name_regex_keep 값(보존할 태그)과 일치하는 태그를 제외합니다.
  5. 매니페스트가 없는 태그는 제외합니다(UI에서 제공되지 않는 옵션의 일부).
  6. created_date에 따라 남은 태그를 순서대로 정렬합니다.
  7. keep_n 값(유지할 태그 수)을 기준으로 N개의 태그를 제외합니다.
  8. older_than 값(만료 기간)을 기준으로 더 이상 필요하지 않은 태그를 제외합니다.
  9. 남은 태그를 레지스트리에서 삭제합니다.
caution
GitLab.com에서는 정리 정책의 실행 시간이 제한됩니다. 정책 실행 후에도 일부 태그가 컨테이너 레지스트리에 남을 수 있습니다. 정책이 다시 실행되면 남은 태그가 포함됩니다. 모든 태그를 삭제하기 위해서는 여러 번 실행해야 할 수 있습니다.
caution
GitLab Self-Managed형 설치에서는 Docker Registry HTTP API V2 사양을 준수하는 타사 컨테이너 레지스트리를 지원합니다. 그러나이 사양에는 태그 삭제 작업이 포함되어 있지 않습니다. 따라서 GitLab은 타사 컨테이너 레지스트리와 상호 작용할 때 태그 삭제를 위한 우회 방법을 사용합니다. 자세한 내용은 이슈 15737을 참조하십시오. 가능한 구현 변형으로 인해이 우회 방법은 모든 타사 레지스트리에서 동일한 예측 가능한 방식으로 작동한다는 것을 보장하지 않습니다. GitLab 컨테이너 레지스트리를 사용하는 경우 별도로 이 우회 방법이 필요하지 않습니다. 왜냐하면 우리는 특별한 태그 삭제 작업을 구현했기 때문입니다. 이 경우 정리 정책은 일관되고 예측 가능하게 작동될 것으로 예상할 수 있습니다.

정리 정책 작업 예시

정리 정책의 보관 및 제거 규칙 간의 상호 작용은 복잡할 수 있습니다. 예를 들어, 다음과 같이 정리 정책 구성이 있는 프로젝트가 있다고 가정해 봅시다:

  • 가장 최근 태그 유지: 이미지 이름당 1개의 태그.
  • 일치하는 태그 유지: production-.*에 일치하는 태그.
  • 다음 날짜 이전 태그 제거: 7일.
  • 일치하는 태그 제거: .*.

및 다음과 같은 태그를 가진 컨테이너 레지스트리가 있는 경우:

  • 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 태그는 일치하는 태그 유지 규칙과 일치하므로 유지해야합니다.
    • v44 태그는 가장 최근이므로 가장 최근 태그 유지 규칙과 일치하므로 유지해야 합니다.
  2. 제거 규칙은 낮은 우선 순위를 갖습니다. 모든 규칙이 일치하는 경우에만 태그가 삭제됩니다. 유지 규칙에 일치하지 않는 태그(dev-44, dev-v43, dev-v42, v43, v42)의 경우:
    • dev-44dev-43다음 날짜 이전 태그 제거와 일치하지 않으므로 유지됩니다.
    • dev-v42, v43, v42다음 날짜 이전 태그 제거일치하는 태그 제거 규칙 둘 다 일치하므로 이 세 개의 태그를 삭제할 수 있습니다.

정리 정책 생성

API를 사용하여 정리 정책을 만들거나 UI에서 생성할 수 있습니다.

UI에서 정리 정책을 만드려면:

  1. 프로젝트에서 설정 > 패키지 및 레지스트리로 이동합니다.
  2. 정리 정책 섹션에서 정리 규칙 설정을 선택합니다.
  3. 필드를 작성합니다:

    필드 설명
    토글 정책을 켜거나 끕니다.
    정리 실행 정책이 실행되는 빈도입니다.
    가장 최근 태그 유지 각 이미지에 대해 항상 유지할 태그의 수입니다.
    일치하는 태그 유지 보존할 태그를 결정하는 정규표현식 패턴입니다. latest 태그는 항상 보존됩니다. 모든 태그를 사용하려면 .*을 사용합니다. 다른 정규표현식 패턴 예시를 참조하십시오.
    이보다 오래된 태그 제거 X일보다 오래된 태그만 제거합니다.
    일치하는 태그 제거 제거할 태그를 결정하는 정규표현식 패턴입니다. 이 값은 비워둘 수 없습니다. 모든 태그를 사용하려면 .*을 이용합니다. 다른 정규표현식 패턴 예시를 참조하십시오.
  4. 저장을 선택합니다.

정책은 선택한 예약 간격으로 실행됩니다.

note
정책을 편집하고 다시 저장을 선택하면 간격이 재설정됩니다.

정규표현식 패턴 예시

정리 정책은 UI와 API 모두에서 태그를 보존하거나 제거하는 데 정규표현식 패턴을 사용합니다.

정규표현식 패턴은 자동으로 \A\Z 앵커로 둘러싸입니다. 따라서 정규표현식 패턴에는 어떠한 \A, \Z, ^, $ 토큰도 포함할 필요가 없습니다.

다음은 사용할 수 있는 정규표현식 패턴의 예시입니다:

  • 모든 태그와 일치:

    .*
    

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

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

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

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

    release.*
    
  • v로 시작하거나 main으로 명명되거나 release로 시작하는 태그와 일치:

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

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

  • GitLab 15.0에서 container_registry_expiration_policies_throttling 피처 플래그가 제거되었습니다.

정리 정책은 백그라운드 프로세스로 실행됩니다. 이 프로세스는 복잡하며 삭제할 태그 수에 따라 완료되기까지 시간이 소요될 수 있습니다.

서버 리소스가 부족해지는 것을 방지하려면 다음과 같은 응용 프로그램 설정을 사용할 수 있습니다:

  • container_registry_expiration_policies_worker_capacity: 동시에 실행되는 최대 정리 작업자 수입니다. 이 값은 0보다 크거나 같아야 합니다. 백그라운드 작업에서 사용하는 리소스를 모니터링한 후 이 값을 낮게 설정한 다음 증가시키는 것이 좋습니다. 모든 작업자를 제거하고 정리 정책을 실행하지 않으려면 이 값을 0으로 설정하면 됩니다. 기본값은 4입니다.
  • container_registry_delete_tags_service_timeout: 정리 프로세스가 태그 일괄 삭제에 소요할 수 있는 최대 시간(초)입니다. 기본값은 250입니다.
  • container_registry_cleanup_tags_service_max_list_size: 단일 실행에서 삭제할 수 있는 최대 태그 수입니다. 추가 태그는 다른 실행에서 삭제해야 합니다. 이 값을 낮게 설정한 후 컨테이너 이미지가 올바르게 삭제되는 것을 확인한 후 증가시키는 것이 좋습니다. 기본값은 200입니다.
  • container_registry_expiration_policies_caching: 정책 실행 중에 태그 생성 타임스탬프 캐싱을 활성화하거나 비활성화합니다. 캐시된 타임스탬프는 Redis에 저장됩니다. 기본적으로 활성화됩니다.

Self-Managed형 인스턴스의 경우 이러한 설정을 Rails 콘솔에서 업데이트할 수 있습니다:

ApplicationSetting.last.update(container_registry_expiration_policies_worker_capacity: 3)

이 설정은 관리자 영역에서도 사용할 수 있습니다:

  1. 왼쪽 사이드바에서 맨 아래에 있는 관리자 영역을 선택합니다.
  2. 설정 > CI/CD를 선택합니다.
  3. 컨테이너 레지스트리를 확장합니다.

정리 정책 API 사용

GitLab API를 사용하여 정리 정책을 설정, 업데이트 및 비활성화할 수 있습니다.

예시:

  • 모든 태그를 선택하고 각 이미지 당 적어도 1개의 태그를 유지하고, 14일 이전인 모든 태그를 정리하고, 한 달에 한 번 실행하며, main이라는 이미지를 보존하고 정책이 활성화된 상태:

    curl --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(태그가 자동으로 제거되는 일수)에 대한 유효한 값은:

  • 7d
  • 14d
  • 30d
  • 90d

더 많은 세부 정보를 찾으려면 API 문서를 참조하십시오: 프로젝트 API 편집.

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

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

컨테이너 레지스트리 리포지터리 축소 옵션 더 알아보기

프로젝트에서 사용하는 컨테이너 레지스트리 리포지터리 사용량을 줄이기 위해 사용할 수 있는 몇 가지 옵션이 있습니다:

정리 정책 문제 해결

정리 정책을 업데이트하는 중에 오류가 발생했습니다.

이 오류 메시지를 확인하려면 유효한 정규표현식 패턴을 사용했는지 확인하십시오.

정리 정책에 대해 정규표현식은 RE2 구문을 사용합니다. Golang 스타일의 테스트 도구를 사용하여 regex101 regex tester에서 정규표현식을 테스트할 수 있습니다. 일반적인 정규표현식 패턴 예시를 확인하십시오.

정리 정책이 어떤 태그도 삭제하지 않음

이에는 다양한 이유가 있을 수 있습니다:

  • GitLab Self-Managed형 인스턴스를 사용하고 컨테이너 리포지터리에 1000개 이상의 태그가 있는 경우 로그에 error authorizing context: invalid token이 표시될 수 있는 컨테이너 레지스트리 토큰 만료 문제에 빠질 수 있습니다.

    이 문제를 해결하려면 두 가지 해결 방법이 있습니다:

    • 정리 정책에 한정을 설정합니다. 시간내에 정리가 실행되고 만료된 토큰 오류를 피할 수 있습니다. 자세한 내용은 리소스를 절약하기 위해 정리 한도 설정을 참조하십시오.

    • 컨테이너 레지스트리 인증 토큰의 만료 지연 시간을 연장합니다. 기본값은 5분입니다. ApplicationSetting.last.update(container_registry_token_expire_delay: <integer>)를 실행하여 사용자 정의 값을 설정할 수 있습니다. 기본적으로 GitLab.com에서는 만료 지연 시간이 15분으로 설정됩니다. 이 값을 늘릴수록 권한을 철회하는 데 필요한 시간도 늘어납니다.

또는 삭제할 태그 디렉터리을 생성하고 해당 디렉터리을 사용하여 태그를 삭제할 수 있습니다. 디렉터리을 생성하고 태그를 삭제하려면 다음 단계를 따라하십시오:

  1. 다음 셀 스크립트를 실행하십시오. for 루프 직전의 명령어는 list_o_tags.out을 항상 다시 초기화하는 역할을 합니다. 이 명령어를 실행하면 모든 태그 이름이 list_o_tags.out 파일에 기록됩니다.

    # 페이지네이션을 고려하면 특정 컨테이너 리포지터리의 모든 태그 디렉터리을 가져옵니다
    echo -n "" > list_o_tags.out; for i in {1..N}; do curl --header 'PRIVATE-TOKEN: <PAT>' "https://gitlab.example.com/api/v4/projects/<Project_id>/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(<Project_id>).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
    

    이 명령 세트는 1개월 이전의 created_at 날짜를 가진 모든 태그를 포함하는 /tmp/list_o_tags.out 파일을 만듭니다.

  2. list_o_tags.out 파일에서 유지할 태그를 제거하십시오. 예를 들어 sed를 사용하여 파일을 파싱하고 태그를 제거할 수 있습니다.

    Linux
     # 파일에서 `latest` 태그를 제거합니다
     sed -i '/latest/d' list_o_tags.out
        
     # 파일에서 처음 N개의 태그를 제거합니다
     sed -i '1,Nd' list_o_tags.out
        
     # 파일에서 `Av`로 시작하는 태그를 제거합니다
     sed -i '/^Av/d' list_o_tags.out
        
     # 파일에서 `_v3`로 끝나는 태그를 제거합니다
     sed -i '/_v3$/d' list_o_tags.out
    
    macOS
     # 파일에서 `latest` 태그를 제거합니다
     sed -i .bak '/latest/d' list_o_tags.out
        
     # 파일에서 처음 N개의 태그를 제거합니다
     sed -i .bak '1,Nd' list_o_tags.out
        
     # 파일에서 `Av`로 시작하는 태그를 제거합니다
     sed -i .bak '/^Av/d' list_o_tags.out
        
     # 파일에서 `_v3`로 끝나는 태그를 제거합니다
     sed -i .bak '/_v3$/d' list_o_tags.out
    
  3. list_o_tags.out 파일이 제거할 태그만 포함하도록 다시 확인하십시오.

  4. list_o_tags.out 파일의 태그를 삭제하려면 다음 셀 스크립트를 실행하십시오:

    ```shell # list_o_tags.out의 각 줄을 순회하여 하나씩 태그를 삭제합니다 while read -r LINE || [[ -n $LINE ]]; do echo ${LINE}; curl –request DELETE –header ‘PRIVATE-TOKEN: ' "https://gitlab.example.com/api/v4/projects//registry/repositories//tags