콘텐츠로 이동






Harbor 이미지 GC, Immutable Tag 및 Helm Chart 저장소 운영 가이드

대상: Harbor 운영 관리자 및 CI/CD 파이프라인 운영자
범위: Tag Retention, 이미지 Garbage Collection, Immutable Tag, Helm OCI Chart 저장소
기준: Harbor v2.x

1. 이미지 저장소 운영 개요

Harbor 이미지 저장소 운영은 단순히 이미지를 Push/Pull하는 작업만으로 끝나지 않는다. 장기 운영 시 이미지와 Helm Chart가 누적되므로 다음 정책을 함께 구성해야 한다.

기능 목적 권장 적용 대상
Tag Retention 불필요한 이미지 Tag 및 Artifact 정리 개발, CI, 테스트 프로젝트
Garbage Collection 삭제된 Artifact가 참조하지 않는 Blob 물리 삭제 Harbor 시스템 전체
Immutable Tag 특정 Tag 덮어쓰기 방지 운영, 배포, 릴리스 프로젝트
Project Quota 프로젝트별 저장 용량 제한 모든 프로젝트
Robot Account CI/CD 전용 인증 계정 Jenkins, GitLab CI, Argo CD 등
Helm OCI Registry Helm Chart 버전 관리 및 배포 플랫폼, 애플리케이션 배포 프로젝트

이미지 Tag를 삭제하거나 Tag Retention Policy를 실행해도 스토리지 사용량이 즉시 줄어들지는 않는다. Registry Blob은 Garbage Collection을 수행해야 실제 저장소에서 제거된다.

1.1 권장 프로젝트 분리

프로젝트 용도 Public 여부 Immutable Retention
platform 공용 플랫폼 이미지 및 Helm Chart Private Release Tag만 적용 최근 20개 유지
dev 개발 이미지 Private 미적용 또는 Release만 적용 최근 10개 유지
staging 스테이징 이미지 Private 배포 Tag 적용 최근 20개 유지
production 운영 배포 이미지 Private 모든 Release Tag 적용 장기 보관
proxy-cache Proxy Cache 프로젝트 Private 미적용 정책 별도 적용

2. Tag Retention 및 Garbage Collection

2.1 Tag Retention과 GC 차이점

구분 Tag Retention Garbage Collection
실행 범위 프로젝트 단위 Harbor 시스템 전체
처리 대상 Tag 및 Artifact 참조되지 않는 Blob
목적 보관할 Artifact 결정 실제 스토리지 공간 회수
실행 권한 Project Admin 이상 Harbor System Admin
실행 순서 먼저 실행 Retention 후 실행
데이터 삭제 보관 규칙에 없는 Tag/Artifact 삭제 삭제된 Artifact의 미참조 데이터 삭제

권장 운영 순서는 다음과 같다.

1. Tag Retention Policy Dry Run
2. Tag Retention Policy 실행
3. 결과 및 영향도 확인
4. Garbage Collection Dry Run
5. Garbage Collection 실행
6. 스토리지 사용량 및 Harbor 로그 확인

Tag Retention Policy는 삭제할 Tag를 직접 지정하는 방식이 아니라, 보존할 Tag를 정의하는 방식이다. 보존 규칙에 해당하지 않는 Tag와 Artifact가 삭제 대상이 된다.

2.2 Tag Retention Policy 생성

  1. Harbor Portal에 Project Admin 또는 System Admin 계정으로 로그인한다.
  2. Projects 메뉴에서 대상 프로젝트를 선택한다.
  3. Policy 탭으로 이동한다.
  4. Tag Retention을 선택한다.
  5. Add Rule을 선택한다.
  6. Repository, Quantity, Tag 조건을 설정한다.
  7. Dry Run으로 결과를 확인한다.
  8. 문제가 없으면 Run Now 또는 정기 실행 일정을 설정한다.

Harbor Tag Retention Rule은 최대 15개까지 생성할 수 있다.

2.3 Tag Retention Rule 구성 요소

Tag Retention Rule은 다음 순서로 조건을 평가한다.

순서 항목 설명
1 Repository 적용할 Repository 선택
2 Quantity 최근 N개 또는 특정 기간 기준 보존
3 Tags Tag 이름 또는 Wildcard 기준 보존

Repository와 Tag에는 Wildcard를 사용할 수 있다.

패턴 설명
** 전체
api-* api-로 시작하는 이름
*-prod -prod로 끝나는 이름
release-* Release Tag만 선택
v* Semantic Version 계열 Tag 선택

2.4 개발 프로젝트 Retention 예시

개발 프로젝트에서 모든 Repository의 최근 10개 Tag만 유지하는 정책 예시다.

항목 설정 값
Repository Matching
Repository 이름 **
Quantity Retain the most recently pushed 10 artifacts
Tags Matching
Tag 이름 **
Untagged Artifact 포함

이 정책은 CI/CD가 반복적으로 생성하는 오래된 개발 이미지를 정리하는 데 적합하다.

2.5 운영 프로젝트 Retention 예시

운영 프로젝트에서 Release Tag와 최근 배포 이미지를 보존하는 예시다.

Rule 1: Release Tag 전체 보존

항목 설정 값
Repository Matching
Repository 이름 **
Quantity Retain always
Tags Matching
Tag 이름 release-*, v*
Untagged Artifact 제외

Rule 2: 최근 Build Tag 20개 보존

항목 설정 값
Repository Matching
Repository 이름 **
Quantity Retain the most recently pushed 20 artifacts
Tags Matching
Tag 이름 build-*, main-*
Untagged Artifact 포함

여러 Retention Rule은 OR 조건으로 처리된다. 하나라도 보존 규칙에 포함되면 Artifact는 유지된다.

2.6 Retention Policy 실행 일정

Retention Policy는 다음 일정으로 설정할 수 있다.

일정 사용 예시
Hourly 매우 빈번한 CI 이미지 생성 환경
Daily 일반 개발 환경 권장
Weekly 운영 또는 변경량이 적은 프로젝트
Custom Cron 조직 정책에 따른 세부 일정

개발 프로젝트의 권장 일정 예시:

매일 새벽 01:00: Tag Retention 실행
매일 새벽 02:00: Garbage Collection 실행

주간 운영 이미지 정책 예시:

매주 일요일 01:00: Tag Retention 실행
매주 일요일 03:00: Garbage Collection 실행

2.7 Garbage Collection 실행

Garbage Collection은 Harbor System Admin 권한이 필요하다.

  1. Harbor Portal에 System Admin으로 로그인한다.
  2. AdministrationClean Up 메뉴로 이동한다.
  3. Garbage Collection 탭을 선택한다.
  4. Workers 수를 설정한다.
  5. 필요하면 Allow garbage collection on untagged artifacts를 활성화한다.
  6. 먼저 Dry Run을 실행한다.
  7. 결과를 검토한 후 GC Now를 실행한다.

Garbage Collection은 이미지 삭제 후 실제 디스크 공간을 회수하기 위해 필요하다.

2.8 GC Workers 설정

GC Worker 수는 Registry Storage 성능과 운영 부하를 고려해 설정한다.

환경 권장 Worker 수 비고
개발/테스트 1~2 부하 최소화
일반 운영 2~4 스토리지 IOPS 고려
대규모 Object Storage 4~8 사전 성능 검증 필요
저성능 NFS 1 동시 작업 주의

GC Worker 수를 과도하게 높이면 Object Storage API, NFS, Ceph, Registry Backend에 부하가 발생할 수 있다.

2.9 GC 전 Read Only Mode 권장

중요한 운영 환경에서는 GC 수행 중 이미지 Push, Tag 삭제, Repository 삭제가 발생하지 않도록 Harbor를 Read Only Mode로 전환하는 것을 권장한다.

Read Only Mode에서는 Pull은 가능하지만 Push와 Tag/Repository 삭제는 제한된다.

  1. AdministrationConfiguration 메뉴로 이동한다.
  2. Read Only Mode를 활성화한다.
  3. 실행 중인 CI/CD Pipeline을 중지하거나 완료 여부를 확인한다.
  4. GC Dry Run 및 GC를 실행한다.
  5. 결과를 확인한다.
  6. Read Only Mode를 해제한다.

2.10 GC 운영 절차

1. CI/CD Pipeline, Replication, 이미지 Push 작업 확인
2. Harbor Read Only Mode 활성화
3. Tag Retention Dry Run 실행
4. Tag Retention 실행
5. Tag/Artifact 삭제 결과 확인
6. GC Dry Run 실행
7. GC 실행
8. GC History 및 로그 확인
9. Storage 사용량 확인
10. Harbor Read Only Mode 해제

2.11 GC 전 확인 사항

확인 항목 설명
백업 Registry Storage 및 Database 백업 확인
Replication 복제 작업 실행 여부 확인
CI/CD 이미지 Push 작업 여부 확인
Retention 결과 Dry Run 결과 검토
Immutable Rule 삭제 대상 Tag가 Immutable인지 확인
Storage 상태 NFS, Ceph, S3 등 Backend 상태 확인
Read Only Mode 운영 중인 Push를 차단할지 결정

2.12 GC 관련 주의사항

  • Tag를 삭제해도 GC 전까지 실제 스토리지 공간은 즉시 반환되지 않는다.
  • GC는 Harbor 전체에 영향을 미치므로 운영 피크 시간에는 실행하지 않는다.
  • Retention Policy를 처음 적용할 때는 반드시 Dry Run을 수행한다.
  • 운영 Release 이미지는 Immutable Rule 및 별도 Retention Rule으로 보호한다.
  • Cosign Signature, SBOM, OCI Artifact는 원본 Artifact와의 연결 관계를 고려해 삭제 정책을 검토한다.
  • Proxy Cache Project의 캐시 데이터 정책은 일반 이미지 프로젝트와 분리해서 운영한다.

3. Immutable Tag 관리

Immutable Tag는 특정 Tag에 대해 이미지 덮어쓰기와 삭제를 방지하는 기능이다.

예를 들어 v1.0.0, release-2026.08.12, prod-20260812 Tag에 Immutable Policy를 적용하면, 동일 Tag로 다시 Push할 수 없다.

3.1 Immutable Tag가 필요한 이유

상황 Immutable 미적용 Immutable 적용
동일 Tag 재배포 이미지가 덮어써질 수 있음 Push 거부
운영 장애 분석 배포 시점 이미지 추적이 어려움 배포 Artifact 보존
롤백 이전 이미지가 변경될 수 있음 동일 Digest 보장
보안 감사 Tag와 실제 이미지 불일치 가능 배포 이미지 추적 가능
GitOps Tag 기반 배포 불안정 고정 버전 배포 가능

3.2 권장 Tag 전략

운영 환경에서는 latest Tag 사용을 피하고, 불변 버전 Tag 또는 Git Commit SHA Tag를 사용한다.

Tag 유형 예시 Immutable 권장 여부
Semantic Version v1.2.3 적용
Release Tag release-2026.08.12 적용
Git SHA sha-a1b2c3d4 적용
Build Number build-1024 적용
Environment Tag prod-20260812 적용
Latest latest 일반적으로 미적용
Branch Tag main, develop 일반적으로 미적용
Temporary Tag pr-123 미적용

3.3 Immutable Tag Rule 생성

  1. Harbor Portal에서 대상 Project를 선택한다.
  2. Policy 탭으로 이동한다.
  3. Tag Immutability를 선택한다.
  4. Add Rule을 선택한다.
  5. Repository와 Tag 조건을 입력한다.
  6. Add를 선택한다.
  7. 필요하면 Rule을 활성화한다.

Immutable Rule은 Project 단위로 적용된다.

3.4 운영 프로젝트 Immutable Rule 예시

Rule 1: 모든 Semantic Version 보호

항목 설정 값
Repository Matching
Repository 이름 **
Tags Matching
Tag 이름 v*

Rule 2: Release Tag 보호

항목 설정 값
Repository Matching
Repository 이름 **
Tags Matching
Tag 이름 release-*

Rule 3: Production Tag 보호

항목 설정 값
Repository Matching
Repository 이름 **
Tags Matching
Tag 이름 prod-*

3.5 개발 프로젝트 Immutable Rule 예시

개발 환경에서는 latest, main, develop Tag가 자주 변경될 수 있다. 대신 빌드 번호나 Git SHA Tag만 불변 처리한다.

항목 설정 값
Repository Matching
Repository 이름 **
Tags Matching
Tag 이름 sha-*, build-*

3.6 Immutable Tag Push 테스트

이미지를 Push한다.

export HARBOR_FQDN="harbor.example.internal"
export PROJECT="production"
export IMAGE="api"
export TAG="v1.0.0"

docker tag nginx:1.27 \
  "${HARBOR_FQDN}/${PROJECT}/${IMAGE}:${TAG}"

docker push \
  "${HARBOR_FQDN}/${PROJECT}/${IMAGE}:${TAG}"

같은 Tag로 다른 이미지를 Push한다.

docker tag nginx:1.28 \
  "${HARBOR_FQDN}/${PROJECT}/${IMAGE}:${TAG}"

docker push \
  "${HARBOR_FQDN}/${PROJECT}/${IMAGE}:${TAG}"

Immutable Rule이 적용된 경우 Push가 거부되어야 한다.

예시 오류:

denied: the requested access to the resource is denied
immutable tag cannot be overwritten

3.7 Immutable Tag 변경 절차

이미 Immutable 상태인 Tag는 일반적으로 덮어쓸 수 없다.

잘못된 이미지가 Release Tag로 배포된 경우 다음 절차를 권장한다.

1. 기존 Immutable Tag를 삭제하거나 덮어쓰지 않는다.
2. 새 버전 Tag를 발급한다.
3. 새 이미지로 배포한다.
4. 배포 Manifest 또는 Helm Values의 Image Tag를 변경한다.
5. 배포 이력과 변경 사유를 기록한다.

예시:

잘못된 Tag: v1.2.3
수정 Tag: v1.2.4

운영 Artifact의 재현성과 감사 추적을 위해 기존 Release Tag의 Immutable Rule을 임시 해제하는 방식은 권장하지 않는다.

3.8 Immutable Tag와 Retention Policy 관계

상황 결과
Immutable Tag + Retention 보존 대상 Tag와 Artifact 유지
Immutable Tag + Retention 삭제 대상 정책 및 권한에 따라 삭제 제한 가능
Immutable Tag + GC Tag가 유지되면 Blob도 유지
Tag 삭제 후 GC 참조가 없는 Blob만 제거
Cosign Signature 연결 Artifact 원본 Artifact와 함께 정책 검토 필요

운영 프로젝트에서는 다음 순서를 권장한다.

1. Immutable Rule로 Release Tag 보호
2. Retention Policy로 오래된 Build Tag 정리
3. GC로 미참조 Blob 제거

Docker Push 출력 예시

The push refers to repository [harbor.example.internal/production/sample-api]
a1b2c3d4e5f6: Preparing
b2c3d4e5f6a7: Preparing
c3d4e5f6a7b8: Preparing
d4e5f6a7b8c9: Preparing
e5f6a7b8c9d0: Preparing

a1b2c3d4e5f6: Layer already exists
b2c3d4e5f6a7: Layer already exists
c3d4e5f6a7b8: Layer already exists
d4e5f6a7b8c9: Layer already exists
e5f6a7b8c9d0: Layer already exists

denied: tag v1.0.0 is immutable and cannot be overwritten

4. Helm OCI Chart 저장소 운영

Harbor는 Helm ChartMuseum 방식 대신 OCI Registry 방식으로 Helm Chart를 저장하고 배포할 수 있다.

Helm 3.8 이상에서는 OCI Registry 기반 Chart Push/Pull 기능을 기본적으로 사용할 수 있다.

4.1 Helm Chart 프로젝트 구성

Helm Chart 전용 프로젝트를 별도로 생성하는 것을 권장한다.

프로젝트 용도 권장 권한
helm-dev 개발용 Helm Chart Developer Push/Pull
helm-staging 스테이징 Chart Developer Push/Pull
helm-production 운영 배포 Chart Robot Account Pull 중심
platform-charts 공통 플랫폼 Chart 제한된 Maintainer Push

프로젝트 생성 절차:

  1. Harbor Portal에서 Projects 메뉴로 이동한다.
  2. + New Project를 선택한다.
  3. 프로젝트 이름을 입력한다.
  4. 운영 Chart 프로젝트는 Private으로 생성한다.
  5. OK를 선택한다.

4.2 Helm OCI Registry 로그인

export HARBOR_FQDN="harbor.example.internal"
export HARBOR_PROJECT="platform-charts"

helm registry login "${HARBOR_FQDN}"

CI/CD에서는 개인 계정보다 Robot Account를 권장한다.

helm registry login "${HARBOR_FQDN}" \
  --username "robot\$platform-charts-ci" \
  --password "<ROBOT_ACCOUNT_TOKEN>"

4.3 Helm Chart 생성 및 패키징

새 Helm Chart를 생성한다.

helm create sample-app

Chart Version을 수정한다.

vi sample-app/Chart.yaml

예시:

apiVersion: v2
name: sample-app
description: Sample Application Helm Chart
type: application

version: 1.0.0
appVersion: "1.0.0"

Chart를 패키징한다.

helm package sample-app

생성 결과:

sample-app-1.0.0.tgz

4.4 Harbor에 Helm OCI Chart Push

helm push sample-app-1.0.0.tgz \
  "oci://${HARBOR_FQDN}/${HARBOR_PROJECT}"

예시:

helm push sample-app-1.0.0.tgz \
  oci://harbor.example.internal/platform-charts

Push 후 Harbor Portal에서 다음 경로로 확인한다.

Projects
→ platform-charts
→ Repositories
→ sample-app
→ Artifacts

Helm OCI Chart는 Harbor UI에서 일반 OCI Artifact처럼 표시된다.

4.5 Helm OCI Chart Pull

특정 Chart Version을 내려받는다.

helm pull \
  "oci://${HARBOR_FQDN}/${HARBOR_PROJECT}/sample-app" \
  --version 1.0.0

결과:

Pulled: harbor.example.internal/platform-charts/sample-app:1.0.0
Digest: sha256:<DIGEST>

4.6 Helm OCI Chart Install

Harbor OCI Registry에서 직접 설치한다.

helm install sample-app \
  "oci://${HARBOR_FQDN}/${HARBOR_PROJECT}/sample-app" \
  --version 1.0.0 \
  --namespace sample-app \
  --create-namespace

별도 Values 파일을 적용한다.

helm install sample-app \
  "oci://${HARBOR_FQDN}/${HARBOR_PROJECT}/sample-app" \
  --version 1.0.0 \
  --namespace sample-app \
  --create-namespace \
  --values values-production.yaml

업그레이드 예시:

helm upgrade sample-app \
  "oci://${HARBOR_FQDN}/${HARBOR_PROJECT}/sample-app" \
  --version 1.0.1 \
  --namespace sample-app \
  --values values-production.yaml

4.7 Helm OCI Chart Immutable Policy

운영 Helm Chart는 동일 Version의 재배포를 방지해야 한다.

platform-charts 또는 helm-production 프로젝트에서 다음 Immutable Rule을 권장한다.

항목 설정 값
Repository Matching
Repository 이름 **
Tags Matching
Tag 이름 v*, *.*.*

Helm Chart의 version 값은 Harbor OCI Artifact Tag로 저장된다.

예를 들어 Chart.yaml의 Version이 다음과 같다면:

version: 1.2.3

Harbor에는 다음 OCI Artifact Tag로 저장된다.

sample-app:1.2.3

동일 Version Chart를 다시 Push하면 Immutable Rule에 의해 거부되어야 한다.

4.8 Helm OCI Chart 버전 정책

환경 Version 예시 Immutable Retention
개발 0.1.0-dev.1 선택 최근 20개
테스트 0.1.0-rc.1 적용 권장 최근 10개
운영 1.0.0 필수 장기 보관
Hotfix 1.0.1 필수 장기 보관

운영 Chart는 Semantic Versioning을 권장한다.

MAJOR.MINOR.PATCH

예시:
1.0.0
1.0.1
1.1.0
2.0.0

4.9 Helm Chart Retention Policy 예시

개발 Chart 프로젝트에서 최근 20개 Version만 유지하는 정책 예시다.

항목 설정 값
Repository Matching
Repository 이름 **
Quantity 최근 20개 유지
Tags Matching
Tag 이름 **
Untagged Artifact 포함

운영 Helm Chart 프로젝트에서는 Release Version을 장기간 유지한다.

항목 설정 값
Repository Matching
Repository 이름 **
Quantity 항상 유지
Tags Matching
Tag 이름 *.*.*
Untagged Artifact 제외

4.10 Helm OCI Chart CI/CD Push 예시

GitLab CI 예시:

stages:
  - package
  - publish

variables:
  HARBOR_REGISTRY: harbor.example.internal
  HARBOR_PROJECT: platform-charts
  CHART_NAME: sample-app
  CHART_VERSION: ${CI_COMMIT_TAG}

package:
  stage: package
  script:
    - helm package ${CHART_NAME} --version ${CHART_VERSION}
  artifacts:
    paths:
      - "${CHART_NAME}-${CHART_VERSION}.tgz"

publish:
  stage: publish
  rules:
    - if: '$CI_COMMIT_TAG'
  script:
    - echo "${HARBOR_ROBOT_TOKEN}" | helm registry login "${HARBOR_REGISTRY}" --username "${HARBOR_ROBOT_USERNAME}" --password-stdin
    - helm push "${CHART_NAME}-${CHART_VERSION}.tgz" "oci://${HARBOR_REGISTRY}/${HARBOR_PROJECT}"

Jenkins Pipeline 예시:

pipeline {
    agent any

    environment {
        HARBOR_REGISTRY = 'harbor.example.internal'
        HARBOR_PROJECT = 'platform-charts'
        CHART_NAME = 'sample-app'
        CHART_VERSION = "${BUILD_NUMBER}"
    }

    stages {
        stage('Package Helm Chart') {
            steps {
                sh """
                    helm package ${CHART_NAME} \
                      --version ${CHART_VERSION}
                """
            }
        }

        stage('Push Helm OCI Chart') {
            steps {
                withCredentials([
                    usernamePassword(
                        credentialsId: 'harbor-robot-account',
                        usernameVariable: 'HARBOR_USERNAME',
                        passwordVariable: 'HARBOR_TOKEN'
                    )
                ]) {
                    sh """
                        echo "${HARBOR_TOKEN}" | \
                          helm registry login ${HARBOR_REGISTRY} \
                          --username "${HARBOR_USERNAME}" \
                          --password-stdin

                        helm push \
                          ${CHART_NAME}-${CHART_VERSION}.tgz \
                          oci://${HARBOR_REGISTRY}/${HARBOR_PROJECT}
                    """
                }
            }
        }
    }
}

4.11 Harbor Helm OCI 운영 권장사항

  • 운영 Chart는 Private Project에 저장한다.
  • CI/CD에는 Robot Account를 사용한다.
  • 운영 Chart Version에는 Immutable Rule을 적용한다.
  • Chart Version은 Semantic Versioning을 사용한다.
  • latest와 같은 가변 Tag 기반 배포를 피한다.
  • 운영 환경은 Chart Digest 또는 고정된 Version을 기준으로 배포한다.
  • Retention Policy는 개발 Chart와 운영 Chart에 다르게 적용한다.
  • Registry GC 전에 Tag Retention 결과를 Dry Run으로 검증한다.
  • Helm Chart와 Container Image Version의 추적성을 위해 Git Tag, Image Digest, Chart Version을 배포 문서에 기록한다.

Appendix #1. 운영 정책 권장 예시

A.1 개발 프로젝트

항목 권장 설정
Public 여부 Private
Immutable Tag sha-*, build-* 적용
Retention 최근 10~20개 유지
GC 매일 새벽
Robot Account CI Push/Pull
Quota 팀별 제한 설정

A.2 운영 프로젝트

항목 권장 설정
Public 여부 Private
Immutable Tag v*, release-*, prod-* 적용
Retention Release Tag 장기 보관
GC 주간 또는 월간, Read Only Mode 검토
Robot Account CD Pull 전용
Quota 별도 용량 모니터링
Signing Cosign 또는 Notation 검토

A.3 권장 실행 일정

매일 01:00  개발 프로젝트 Tag Retention
매일 02:00  개발 프로젝트 영향 확인
매일 03:00  Harbor Garbage Collection

매주 일요일 01:00  운영 프로젝트 Tag Retention Dry Run
매주 일요일 02:00  운영 프로젝트 Retention 실행
매주 일요일 03:00  Harbor Read Only Mode 활성화
매주 일요일 03:10  Harbor Garbage Collection
매주 일요일 04:00  Storage 및 GC Log 확인
매주 일요일 04:10  Harbor Read Only Mode 해제



작성일: 2026년 8월 11일 ,  마지막 업데이트: 2026년 8월 11일