Amazon ECR(Elastic Container Registry)의 컨테이너 이미지 관리는 레지스트리를 깨끗하고 비용 효율적으로 유지하는 데 매우 중요하다. 시간이 지남에 따라 사용되지 않거나 더 이상 사용되지 않는 이미지가 누적되어 스토리지 비용 증가와 운영 오버헤드로 이어질 수 있다. 일반적인 시나리오 중 하나는 특정 태깅 패턴을 따르는 이미지를 제거하는 것이다. 이 경우 x가 하나 이상의 숫자를 나타내는 "9.x.x" 형식의 버전이 태그된 모든 이미지가 대상이다.

이 글에서는 ECR 이미지 정리를 자동화하도록 설계된 Bash 스크립트를 소개한다. 이 스크립트는 dry-runapply 두 가지 주요 모드를 제공하여 필요에 따라 삭제를 시뮬레이션하거나 실행할 수 있다.


스크립트 개요

이 Bash 스크립트는 AWS CLI와 jq(경량의 유연한 명령줄 JSON 프로세서)를 활용하여 다음을 수행한다:

  1. 모든 ECR 리포지토리 나열:
    계정에서 사용 가능한 모든 ECR 리포지토리를 AWS에 쿼리한다.
  2. 이미지 및 태그 가져오기:
    각 리포지토리에 대해 이미지 세부 정보(이미지 다이제스트 및 태그 포함)를 나열한다.
  3. 태그 필터링 적용:
    정규 표현식(^9\.[0-9]+\.[0-9]+$)을 사용하여 태그가 "9.x.x" 형식(예: "9.0.1" 또는 "9.12.3")과 일치하는 이미지를 찾는다.
  4. 작동 모드:
    • Dry Run (--dry-run): 스크립트는 삭제될 이미지만 나열하여 위험 없이 어떤 이미지가 삭제 대상인지 확인할 기회를 제공한다.
    • Apply (--apply): 식별된 이미지를 리포지토리에서 실제로 삭제한다.
  5. 사용법 정보:
    스크립트가 유효한 인자 없이 실행되면 사용 가능한 옵션을 설명하는 도움말 메시지를 출력한다.

주요 기능

1. 자동 리포지토리 검색

  • 기능:
    스크립트는 수동 입력이나 리포지토리 이름 하드코딩 없이 모든 사용 가능한 ECR 리포지토리를 동적으로 조회한다.
  • 이점:
    이를 통해 계정의 리포지토리 목록 변경 사항을 추가 구성 없이 처리할 수 있어 스크립트가 확장 가능하고 적응력을 갖춘다.

2. 정규식을 통한 유연한 태그 필터링

  • 기능:
    정규 표현식을 사용하여 9.로 시작하고 마침표로 구분된 두 개의 추가 숫자 그룹이 뒤따르는 버전 태그를 일치시킨다.
  • 이점:
    정규식 기반 접근 방식은 어떤 이미지를 대상으로 할지에 대한 정밀한 제어를 제공한다. 특정 오래되었거나 사용 중단된 버전 패턴에 맞는 이미지를 정리하면서 네이밍 규칙을 유지할 수 있다.

3. 듀얼 모드 작동 (Dry-Run vs. Apply)

  • 기능:
    스크립트는 명령줄 인자를 받아 삭제를 시뮬레이션(--dry-run)하거나 실제로 실행(--apply)한다.
  • 이점:
    이 듀얼 모드 접근 방식은 파괴적인 작업을 수행하기 전에 영향을 확인할 수 있도록 하여 안전성을 제공한다. 프로덕션과 유사한 환경에서 먼저 스크립트를 테스트해야 하는 관리자에게 가치 있는 기능이다.

4. 강력한 오류 처리 및 Strict 모드

  • 기능:
    스크립트는 Bash의 set -euo pipefail을 사용하여 엄격한 오류 검사를 강제한다. 이 설정은 오류 발생 시, 설정되지 않은 변수 참조 시, 또는 파이프라인의 어떤 명령이 실패할 때 스크립트 실행을 중지시킨다.
  • 이점:
    불완전한 작업이나 예측할 수 없는 스크립트 동작의 위험을 최소화하여 더 신뢰할 수 있는 실행 환경을 촉진한다.

5. 명확한 사용법 문서

  • 기능:
    잘못된 인자가 제공되거나 인자가 없으면 각 모드에 대한 명확한 사용 지침과 설명이 포함된 도움말 메시지를 출력한다.
  • 이점:
    사용자 오류를 줄이고 스크립트 작동 방법을 명확히 하여 덜 숙련된 사용자도 더 쉽게 접근할 수 있게 한다.

장단점

장점

  • 안전성 및 예측 가능성:
    dry-run 모드의 포함으로 관리자가 삭제를 확정하기 전에 변경 사항을 미리 볼 수 있어 실수로 인한 데이터 손실 위험을 줄인다.
  • 자동 검색:
    모든 리포지토리의 자동 쿼리로 관리가 간소화되고 포괄적인 정리가 보장된다.
  • 정규식 기반 필터링:
    태그 필터링을 위한 강력한 정규 표현식으로 버전 패턴에 따라 특정 이미지를 쉽게 대상으로 지정할 수 있다.
  • 단순성 및 확장성:
    Bash로 작성되어 이해하고 수정하기 간단하다. 직관적인 구조로 추가 요구사항에 맞게 더 커스터마이징하기 쉽다.
  • 강력한 오류 처리:
    스크립트의 오류 처리 메커니즘(set -euo pipefail 사용)은 예상치 못한 오류 발생 시 실행을 중단하여 신뢰성을 높인다.

단점

  • AWS CLI와 jq에 대한 의존성:
    스크립트는 AWS CLI와 jq가 모두 설치되고 올바르게 구성되어 있어야 한다. 이러한 도구가 사전 설치되지 않은 환경에서는 추가 설정이 필요하다.
  • 제한된 정규식 유연성:
    현재 정규식은 "9.x.x" 버전과 일치하도록 특별히 조정되어 있다. 버전 관리 체계가 변경되면 그에 따라 정규식을 조정해야 하므로 업데이트하지 않으면 스크립트의 유연성이 떨어진다.
  • 과도한 삭제 가능성:
    이미지가 여러 값으로 태그되어 있고 그 중 하나가 정규식과 일치하면 삭제 명령이 해당 이미지에 작동한다. 프로덕션 환경에서 삭제 모드를 사용할 때는 특별한 주의가 필요하다.
  • 롤백 메커니즘 없음:
    이미지가 삭제되면(--apply 모드에서) 복구가 간단하지 않다. 실수로 삭제된 경우를 대비해 관리자는 백업 또는 버전 관리 수단을 마련해야 한다.
  • 장황한 로깅:
    스크립트는 처리된 각 이미지에 대해 메시지를 출력하므로 이미지 수가 많은 환경에서는 부담스러울 수 있다. 더 간결한 로깅 접근 방식으로 개선될 여지가 있다.

모범 사례 및 권장사항

  1. 먼저 스테이징 환경에서 테스트:
    스크립트를 항상 --dry-run 모드로 스테이징 환경에서 먼저 실행하여 대상 이미지를 올바르게 식별하는지 확인한다.
  2. 백업 구현:
    변경 사항을 롤백해야 할 위험이 있는 경우 이미지가 적절히 백업되거나 버전 관리되도록 한다.
  3. 로그 모니터링:
    이 스크립트를 주기적으로(cron 등을 통해) 실행하려면 출력 로그를 파일로 리디렉션하고 로그 로테이션을 구현하는 것을 고려한다.
  4. 정기적인 업데이트:
    ECR 사용 또는 이미지 태깅 전략이 변경될 때마다 스크립트를 검토하고 테스트하여 유지 관리한다.
  5. 필요 시 정규식 미세 조정:
    버전 관리 시스템이 진화하거나 새로운 태깅 규칙을 도입하는 경우 정규식 패턴을 조정한다.

스크립트

#!/bin/bash
# 이 스크립트는 모든 ECR 리포지토리와 해당 이미지를 처리하고,
# "9.x.x" 패턴(x는 하나 이상의 숫자)과 일치하는 이미지 태그를 확인한 다음,
# 해당 이미지를 나열(dry run)하거나 삭제(apply)한다.
#
# 사용법:
#   ./cleanup_ecr.sh --dry-run    # 삭제하지 않고 삭제될 이미지를 나열한다.
#   ./cleanup_ecr.sh --apply      # "9.x.x"와 일치하는 태그의 이미지를 삭제한다.
#   ./cleanup_ecr.sh              # 이 도움말 메시지를 표시한다.

set -euo pipefail

function usage() { echo “Usage: $0 [–dry-run | –apply]” echo "" echo " –dry-run 태그 패턴 ‘9.x.x’와 일치하는 이미지를 삭제하지 않고 나열한다." echo " –apply 태그 패턴 ‘9.x.x’와 일치하는 이미지를 삭제한다." }

명령줄 인자 확인

if [ “$#” -ne 1 ]; then usage exit 1 fi

MODE="$1" if [[ “$MODE” != “–dry-run” && “$MODE” != “–apply” ]]; then usage exit 1 fi

태그용 정규식 패턴 정의: “9.” 뒤에 숫자들, 마침표, 그다음 숫자들

REGEX="^9.[0-9]+.[0-9]+$"

echo “Mode: $MODE” echo “ECR 리포지토리 목록 가져오는 중…”

모든 리포지토리 이름 조회.

repositories=$(aws ecr describe-repositories –query ‘repositories[].repositoryName’ –output text)

리포지토리가 반환되었는지 확인.

if [ -z “$repositories” ]; then echo “ECR 리포지토리를 찾을 수 없습니다.” exit 0 fi

각 리포지토리 처리.

for repo in $repositories; do echo “——————————” echo “리포지토리 처리 중: $repo”

# 이미지 세부 정보 조회: 다이제스트와 태그.
images_json=$(aws ecr describe-images \
    --repository-name "$repo" \
    --query 'imageDetails[*].{Digest: imageDigest, Tags: imageTags}' \
    --output json)

# 이 리포지토리의 이미지 수 확인.
image_count=$(echo "$images_json" | jq 'length')
if [ "$image_count" -eq 0 ]; then
    echo "  리포지토리 $repo에 이미지가 없습니다."
    continue
fi

# 각 이미지 순회.
for (( i=0; i<image_count; i++ )); do
    image_digest=$(echo "$images_json" | jq -r ".[$i].Digest")
    # 태그 추출; 일부 이미지는 태그가 없을 수 있음.
    tags=$(echo "$images_json" | jq -r ".[$i].Tags[]" 2>/dev/null || true)

    if [ -z "$tags" ]; then
        continue
    fi
    
    # 각 태그 순회.
    for tag in $tags; do
        if [[ $tag =~ $REGEX ]]; then
            echo "일치 발견 - Repo: '$repo', Digest: '$image_digest', Tag: '$tag'"
            if [ "$MODE" == "--apply" ]; then
                echo "  이미지 삭제 중..."
                aws ecr batch-delete-image \
                    --repository-name "$repo" \
                    --image-ids imageDigest="$image_digest",imageTag="$tag"
            fi
        else
            echo "건너뜀 - Repo: '$repo', Digest: '$image_digest', Tag: '$tag'"
        fi
    done
done

done

echo “프로세스 완료.”

결론

제공된 Bash 스크립트는 지정된 태그 패턴과 일치하는 Amazon ECR 이미지의 정리를 자동화하기 위한 견고하고 실용적인 솔루션을 제공한다. 시뮬레이션(dry-run)과 실행(apply) 모드의 명확한 분리, 자동 리포지토리 검색, 오류 처리 메커니즘을 갖춘 이 스크립트는 컨테이너 이미지 관리를 위한 강력한 도구다.

그러나 관리자는 의존성을 인지하고 특정 버전 관리 체계에 맞게 정규식 필터를 신중하게 조정해야 한다. 스테이징 환경에서의 테스트, 삭제 로그 모니터링과 같은 모범 사례를 따르면 이 스크립트는 ECR 유지 관리를 크게 간소화하고 스토리지 비대화를 줄이며 전반적인 운영 효율성을 향상시킬 수 있다.