Artifact Registry 비용 줄이기
쌓이는 Docker 이미지를 순서대로 확인하며 정리하는 법
Cloud Run을 배포할 때마다 Artifact Registry에 이미지가 쌓여 저장 비용이 계속 나올 때, 정리 정책(Cleanup policy)을 dry run으로 먼저 확인하고 적용하는 순서와 중단 조건을 정리합니다.

배포할 때마다 이미지를 새로 빌드해 Artifact Registry에 올리는 구성에서는 컨테이너 이미지가 새 버전으로 하나씩 늘어납니다. 서비스는 최신 이미지만 쓰는데 저장소에는 지난 배포의 이미지가 남고, 그 용량에 저장 비용이 붙습니다. 정리 정책(Cleanup policy)으로 자동 정리를 걸 수 있지만, 이미지 삭제는 되돌릴 수 없어서 어떤 이미지를 지워도 되는지 먼저 가려야 합니다. 금액은 USD이고, 계산 예시는 가격표로 만든 값이지 실제 청구서가 아닙니다.
Cloud Run 자체의 실행 비용(최소 인스턴스, CPU, 메모리)은 Cloud Run 비용 최적화에서 다뤘습니다. 이 글은 그 바깥, 이미지 저장소에서 나는 비용만 다룹니다.

순서
- 저장 비용이 실제로 얼마인지 계산합니다.
- 쓰는 이미지와 지워도 되는 이미지를 가릅니다.
- 정리 정책을 쓰고 dry run으로 검증합니다.
- dry run 결과를 확인한 뒤에만 실제로 적용합니다.
- 적용 뒤 서비스와 비용을 확인합니다.
저장 비용은 얼마나 날까
저장 비용은 저장소에 보관된 아티팩트의 용량으로 계산됩니다. 가격은 프로젝트가 아니라 청구 계정 단위로 적용되어, 같은 청구 계정의 모든 프로젝트 사용량을 합쳐 무료 구간을 계산합니다. 리전 저장소와 멀티 리전 저장소의 단가는 같습니다.
| 항목 | 값(2026-10-20, USD) |
|---|---|
| 무료 구간 | 월 0.5 GiB까지 |
| 초과분 단가 | GiB·시간당 $0.000136986(월 약 $0.10/GiB) |
시간당 단가에 한 달 730시간을 곱하면 약 $0.10이 되므로, 한 달 비용은 대략 max(0, 저장량 GiB − 0.5) × $0.10입니다. 저장량이 0.5 GiB 이하면 결과가 0이 되어 무료 구간 안에서는 음수 금액이 나오지 않습니다. 예를 들어 저장소가 20 GiB라면 (20 − 0.5) × $0.10 = 약 $1.95이고, 0.3 GiB라면 max(0, 0.3 − 0.5) = 0이라 $0입니다. 전송 요금은 저장 요금과 따로 붙고 목적지에 따라 달라서 이 계산에는 넣지 않았습니다. 저장소를 Cloud Run 같은 실행 환경과 같은 리전에 두면 리전 간 전송 비용이 생기지 않습니다.
단가가 낮아서 정리로 얻는 금액이 작을 수 있습니다. 위 계산 결과가 작다면 운영 이미지를 잘못 지울 위험과 비교해서 정리할 가치가 있는지 먼저 판단합니다. 저장소가 여러 개이거나 용량이 크게 불어났을 때 의미가 커집니다.
비용이 실제로 어디서 나는지는 결제(Billing) > 보고서(Reports) 에서 서비스를 기준으로 묶어 Artifact Registry 항목을 확인합니다.

이미지는 왜 계속 쌓일까
배포 때마다 이미지를 새로 빌드해 푸시하는 구성(소스 배포나 CI)에서는 푸시할 때마다 저장소에 새 버전이 생깁니다. 같은 이미지를 다시 배포하기만 하면 늘지 않습니다. Cloud Run은 태그(latest 같은 이름표)로 배포해도 배포하는 순간 그 태그를 이미지의 digest(내용으로 정해지는 고유 식별자, sha256:으로 시작하는 문자열)로 바꿔 리비전(배포할 때마다 만들어지는 서비스의 한 버전)을 만들고, 리비전은 바뀌지 않습니다. 새 리비전을 배포해도 이전 리비전의 이미지는 저장소에 남습니다.
이 구조에서 알아 둘 점이 세 가지입니다.
- Cloud Run은 배포할 때 이미지를 가져와 자체 사본을 두고, 서빙 중인 리비전이 쓰는 동안 그 사본을 유지합니다. 새 인스턴스를 시작할 때는 저장소에서 이미지를 다시 가져오지 않습니다.
- 리비전을 지워도 그 리비전이 쓴 이미지는 자동으로 지워지지 않습니다. 이미지는 Artifact Registry에서 따로 지워야 합니다.
- 저장소에서 이미지를 지우면 되돌릴 수 없습니다. 이미지는 여러 레이어(이미지를 이루는 조각)로 되어 있는데, 이미지를 삭제해도 레이어는 바로 지워지지 않고 일정에 따라 제거됩니다.
확인하지 못한 부분도 있습니다. 트래픽을 받지 않는 이전 리비전으로 되돌릴 때 그 리비전의 이미지를 저장소에서 지웠다면 되돌려지는지, 정리 정책이 Cloud Run이나 GKE가 쓰는 이미지를 검사해 보호해 주는지는 확인하지 못했습니다. 삭제·보존 조건으로 쓸 수 있는 것은 태그 상태, 접두사, 생성 후 경과 시간, 최근 버전 수이고, 사용 중인 이미지를 자동으로 건너뛰는 조건은 찾지 못했습니다. 그래서 롤백에 쓸 이미지는 지우지 않는 것을 전제로 보존 조건(keep 정책)을 직접 정하고, 정책이 사용 중인 이미지를 지켜 준다고 가정하지 않습니다.
지워도 되는 이미지는 무엇일까
이미지가 오래됐다는 이유만으로 지워도 되는 것이 아닙니다. 태그 상태만으로도 사용 여부를 정할 수 없습니다. 먼저 이 순서로 확인합니다. 모두 읽기만 하는 명령입니다.
# 저장소 안의 이미지와 버전(digest, 태그) 목록
gcloud artifacts docker images list LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE --include-tags
# 지금 서비스가 쓰는 설정(이미지 포함)
gcloud run services describe SERVICE --region REGION --format export
# 서비스의 리비전 목록과 리비전 하나의 상세
gcloud run revisions list --service SERVICE --region REGION
gcloud run revisions describe REVISION --region REGION --format yaml--include-tags를 빼면 최상위 이미지만 나오고 버전은 보이지 않습니다. 리비전의 YAML에서 이미지 항목이 가리키는 digest를 찾아 저장소 목록의 버전과 맞춰 봅니다. digest가 출력의 어느 필드에 나오는지는 환경에서 직접 찾아야 하고, 찾지 못하면 이 단계에서 멈춥니다. 서빙 중인 이미지를 특정하지 못한 채 정리 정책을 거는 것이 가장 위험합니다.
그다음 이미지를 이렇게 나눕니다.
| 구분 | 대상 | 처리 |
|---|---|---|
| 반드시 보존 | 지금 트래픽을 받는 리비전의 이미지, 롤백에 쓸 최근 몇 개 버전 | 정책 조건에 사용 중 여부가 없으므로 keep 정책으로 보존 조건을 직접 맞춰야 함. 삭제와 보존 조건이 모두 맞으면 그 이미지는 보존됨 |
| 후보 | 어떤 리비전도 가리키지 않는 오래된 버전, 태그가 없는 이미지 | 삭제 조건으로 지정 |
| 건드리지 않음 | 다른 서비스나 다른 프로젝트가 쓰는 이미지, 멀티 아키텍처 매니페스트가 참조하는 하위 이미지 | 정책에서 제외 |
같은 저장소를 다른 서비스가 쓰는지는 이 방법으로 알 수 없습니다. 모르면 삭제 범위를 줄이거나 정리하지 않습니다.
정리 정책 dry run 먼저
정리 정책은 저장소에 거는 규칙이고 두 종류가 있습니다. 삭제 정책(delete) 은 조건에 맞는 버전을 지우고, 보존 정책(keep) 은 조건에 맞는 버전을 남깁니다. 한 버전이 삭제 정책과 보존 정책에 모두 맞으면 남습니다. 그래서 먼저 보존 정책으로 지킬 것을 정하고, 그다음 삭제 정책을 좁게 씁니다.
정책은 JSON 파일로 씁니다. 아래는 형식을 보여 주는 예시이고, 이름과 값은 본인 저장소에 맞게 바꿔야 합니다.
[
{
"name": "keep-recent-api",
"action": { "type": "Keep" },
"mostRecentVersions": {
"packageNamePrefixes": ["api"],
"keepCount": 10
}
},
{
"name": "keep-prod-tagged",
"action": { "type": "Keep" },
"condition": {
"tagState": "tagged",
"tagPrefixes": ["prod"]
}
},
{
"name": "delete-old-untagged",
"action": { "type": "Delete" },
"condition": {
"tagState": "untagged",
"olderThan": "30d"
}
}
]mostRecentVersions의keepCount는 최근 버전 N개를 남기는 보존 정책입니다. 같은 보존 정책 안에서condition과 함께 쓸 수 없어서 위처럼 정책을 나눠 씁니다.packageNamePrefixes를 지정하면 그 패키지에만 적용되므로 빠진 패키지는 이 정책으로 지켜지지 않습니다.- 조건에는
tagState(tagged, untagged, any),tagPrefixes,versionNamePrefixes,packageNamePrefixes,olderThan,newerThan이 있습니다. 기간은30d처럼 s, m, h, d 단위로 씁니다.olderThan은 저장소에 만들어진 지 최소 이 기간이 지난 버전,newerThan은 이 기간 안에 만들어진 버전입니다. - 삭제 정책에는 이름,
action, 조건이 하나 이상 필요합니다. - Docker 이미지에서는 부모 매니페스트가 참조하는 이미지는 지워지지 않고, 태그 불변 저장소에서는 태그가 붙은 이미지를 지울 수 없습니다.
예시의 보존 정책은 api 패키지의 최근 10개 버전과 prod로 시작하는 태그만 지킵니다. 서빙 중인 이미지가 최근 10개 밖이고 태그도 없다면 delete-old-untagged에 걸려 30일 뒤 삭제 대상이 됩니다. 정책에서 서빙 이미지를 지키려면 그 이미지가 보존 조건에 실제로 맞아야 하므로, 아래 dry run 로그에서 서빙 중인 digest가 삭제 대상에 없는지 반드시 봅니다.
정책을 걸려면 Artifact Registry 관리자(roles/artifactregistry.admin) 권한이 필요합니다. 먼저 --dry-run으로 적용해서 무엇이 지워질지 확인만 합니다. --dry-run은 이미지를 지우지 않지만 저장소의 정리 정책 설정은 바꿉니다. 이 명령은 저장소가 dry run 상태로 정책을 평가하도록 설정하는 것이므로 “아무것도 바꾸지 않는 명령”이 아닙니다. 이미 걸어 둔 정책이 있다면 같은 명령으로 정책 설정이 달라질 수 있으니, 먼저 list-cleanup-policies로 기존 정책을 조회해 내용을 따로 기록해 둡니다. 정책 파일을 적용할 때 기존 정책과 합쳐지는지 대체되는지는 확인하지 못했습니다. 기존 정책이 있는 저장소라면 이 점이 확인되기 전에는 정책 변경을 중단하고, 정책이 없는 저장소에서만 진행합니다. 기존 정책을 조회한 결과를 정책 파일에 모두 옮겨 담을 수 없다면 역시 중단합니다.
gcloud artifacts repositories set-cleanup-policies REPOSITORY \
--project=PROJECT_ID \
--location=LOCATION \
--policy=policy.json \
--dry-rundry run의 결과는 Cloud Logging의 Data Access 감사 로그에 남는데, 이 로그를 쓰려면 먼저 data write 유형의 Data Access 감사 로그를 켜 둬야 합니다. 정책 변경은 약 하루 안에 반영되므로 하루가 지난 뒤 로그를 봅니다. 삭제 요청의 validateOnly가 true인 항목이 dry run입니다.
gcloud logging read 'protoPayload.serviceName="artifactregistry.googleapis.com" AND protoPayload.request.parent="projects/PROJECT_ID/locations/LOCATION/repositories/REPOSITORY/packages/-" AND protoPayload.request.validateOnly=true' --resource-names="projects/PROJECT_ID" --project=PROJECT_ID로그의 요청 내용에서 삭제 대상 버전을 확인합니다. 지금 서빙 중인 리비전의 digest와 롤백용으로 남기려던 버전이 하나라도 대상에 있으면 정책을 고칩니다. 로그에 대상이 어떻게 나오는지는 직접 확인하지 못했으니, 대상을 읽을 수 없다면 적용하지 않습니다. 다음 경우에는 실제 적용으로 넘어가지 않습니다.
- 현재 배포 이미지의 digest를 확인하지 못했을 때
- 롤백용으로 남길 버전을 정하지 못했을 때
- dry run 결과를 확인하지 못했을 때
- 지워질 대상에 운영 이미지가 섞일 가능성이 있을 때
- 이 저장소의 이미지를 다른 서비스도 쓰는지 알 수 없을 때
실제로 적용하기
dry run 결과가 의도와 같으면 --no-dry-run으로 적용합니다. 이 명령은 삭제를 시작하고 삭제된 이미지는 복구할 수 없습니다.
gcloud artifacts repositories set-cleanup-policies REPOSITORY \
--project=PROJECT_ID \
--location=LOCATION \
--policy=policy.json \
--no-dry-run--no-dry-run은 저장소의 dry run 기능을 끄는 옵션입니다. 옵션을 생략했을 때 저장소가 어느 상태가 되는지는 확인하지 못했고, gcloud 도움말(Google Cloud SDK 584.0.0)에는 --dry-run만 나오지만 --no-dry-run도 명령에서 받아들여졌습니다. 그래서 명령마다 --dry-run과 --no-dry-run 중 하나를 항상 명시합니다. 적용한 뒤에는 아래 list-cleanup-policies로 정책이 등록되었는지 확인합니다.
정책을 지우고 싶다면 이렇게 조회하고 삭제합니다.
gcloud artifacts repositories list-cleanup-policies REPOSITORY --project=PROJECT_ID --location=LOCATION
gcloud artifacts repositories delete-cleanup-policies REPOSITORY --policynames=POLICY_NAMES --project=PROJECT_ID --location=LOCATION정책을 지워도 이미 삭제된 이미지는 돌아오지 않습니다. 정책 삭제도 약 하루 뒤에 반영되므로 지우면 바로 멈춘다고 보지 않는 것이 안전합니다.
적용한 뒤 확인할 것
정책이 반영된 하루 뒤에 이렇게 확인합니다.
- 위의 이미지 목록 명령으로 버전 수가 줄었는지, 보존하려던 버전이 남아 있는지 봅니다.
- 현재 서빙 중인 리비전의 digest가 저장소에 있는지 봅니다.
- 서비스를 호출해 정상 응답하는지 보고, 롤백에 쓸 이미지가 저장소에 있는지 확인합니다.
- 다음 청구 주기에 결제 > 보고서에서 Artifact Registry 항목이 줄었는지 확인합니다. 레이어는 일정에 따라 제거되어서 저장 용량이 바로 줄지 않을 수 있습니다.
비용이 줄지 않았다면 어느 저장소가 큰지부터 다시 봅니다. 이미지를 지워도 저장소가 여러 개이거나 Cloud Run 서비스 말고 다른 곳에서 쓰는 이미지가 용량을 차지할 수 있고, 위 계산처럼 원래 월 금액이 작아서 줄일 몫이 적을 수도 있습니다.
마무리 정리
- 월 저장량이 0.5 GiB 이하면 비용이 0이라 정리할 이유가 약합니다. 먼저
max(0, 저장량 − 0.5) × $0.10으로 계산합니다. - 서빙 중인 이미지의 digest와 롤백용으로 남길 버전을 정하지 못했다면 정책을 걸지 않습니다.
- 이미 정리 정책이 있는 저장소는 정책 파일이 기존 정책을 대체하는지 확인하기 전까지 변경하지 않습니다.
--dry-run을 먼저 걸고 하루 뒤 감사 로그에서 삭제 대상을 읽을 수 있을 때만--no-dry-run으로 넘어갑니다.- 적용한 뒤에는 서빙 중인 digest, 서비스 응답, 롤백용 이미지를 확인하고 다음 청구 주기의 결제 보고서에서 Artifact Registry 항목을 봅니다.
출처 및 참고자료
마지막 확인
- Google Cloud · Artifact Registry pricing
- Google Cloud · Configure cleanup policies
- Google Cloud · gcloud artifacts repositories set-cleanup-policies
출처 5개 더 보기출처 접기
- Google Cloud · Manage container images
- Google Cloud · Deploy container images to Cloud Run
- Google Cloud · Manage revisions
- Google Cloud · Rollouts, rollbacks, and traffic migration
- Google Cloud · Free Google Cloud features and trial offer


