서드파티 레지스트리에서 컨테이너 이미지 마이그레이션
서드파티 레지스트리에서 컨테이너 이미지 마이그레이션
이 가이드를 사용해 ECR 풀 스루 캐시(Pull Through Cache)가 지원되지 않는 외부 레지스트리에서 Amazon ECR 프라이빗 레지스트리로 컨테이너 이미지를 일회성 복사하세요. 소스가 지원되는 상위 레지스트리라면 일회성 복사를 수행할 필요가 없습니다. 자동 캐싱을 구성하려면 Sync an upstream registry with an Amazon ECR private registry를 참조하세요.
참고
Amazon ECR은 복사한 이미지 버전을 저장합니다. 소스 레지스트리의 최신 버전은 자동으로 pull되지 않습니다. 이미지를 업데이트하려면 새 버전을 Amazon ECR 리포지토리로 push하세요.
출처: 문서
본문
마이그레이션 개요 (Migration overview)
컨테이너 이미지 마이그레이션은 다음 여섯 단계로 이루어집니다.
- 빌드 및 배포 파일에서 외부 이미지 참조 식별
- Amazon ECR 리포지토리 구조 계획
- 이미지를 Amazon ECR로 복사
- 이미지 무결성 검증
- 배포 구성 업데이트
- 모니터링 및 검증
사전 요구 사항 (Prerequisites)
시작하기 전에 다음을 확인하세요.
- AWS CLI 버전 2를 설치하고 구성합니다. 자세한 내용은 Install or update to the latest version of the AWS CLI를 참조하세요.
- Docker Engine 또는 Docker Desktop 버전 20.10 이상을 설치합니다. 자세한 내용은 Docker 문서의 Install Docker Engine을 참조하세요.
- (선택 사항) 로컬 Docker 데몬 없이 레지스트리 간에 컨테이너 이미지를 복사하는 오픈 소스 도구인 skopeo를 설치합니다. 설치 지침은 GitHub의 Skopeo를 참조하세요.
- IAM 자격 증명이 레지스트리에 인증하고, 리포지토리를 생성하고, 이미지를 push할 수 있는 권한이 있는지 확인합니다. 이러한 명령을 실행하는 데 사용하는 IAM 사용자 또는 역할에 AmazonEC2ContainerRegistryFullAccess 관리형 정책을 연결합니다. 자세한 내용은 AWS managed policies for Amazon Elastic Container Registry를 참조하세요.
Step 1: 외부 이미지 참조 식별
컨테이너 이미지를 빌드하고 배포하는 데 사용하는 파일에서 서드파티 레지스트리에 대한 참조를 검색합니다.
다음 명령은 Linux 및 macOS 셸 구문을 사용합니다. Windows에서는 Windows Subsystem for Linux(WSL) 또는 Git Bash를 사용하세요.
배포 매니페스트에서 참조 식별
Amazon ECS 작업 정의 또는 Amazon EKS 매니페스트에서 비-ECR 이미지 참조를 검색합니다.
Kubernetes 매니페스트의 경우:
grep -rnH --include="*.yaml" --include="*.yml" "image:" . | grep -iv "dkr.ecr"
실행 중인 Amazon EKS 워크로드의 경우:
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{range .spec.initContainers[*]}{.image}{"\n"}{end}{end}' | sort -u | grep -iv "dkr.ecr"
Amazon ECS 작업 정의의 경우:
aws ecs list-task-definitions --status ACTIVE --query 'taskDefinitionArns' --output text | \
tr '\t' '\n' | \
xargs -I {} aws ecs describe-task-definition --task-definition {} \
--query 'taskDefinition.containerDefinitions[].image' --output text | \
tr '\t' '\n' | sort -u | grep -iv "dkr.ecr"
Dockerfile에서 참조 식별
빌드 디렉터리 전체에서 외부 레지스트리를 참조하는 FROM 지시문을 찾으려면:
grep -rnH --include="Dockerfile*" "FROM" . | grep -iv "dkr.ecr"
출력은 Amazon ECR 밖에 있는 이미지를 참조하는 파일과 줄 번호를 보여줍니다. 예를 들어:
./app/Dockerfile:1:FROM python:3.11-slim
./service/Dockerfile:1:FROM nginx:1.25
./worker/Dockerfile:3:FROM redis:7-alpine
pull 빈도 식별 (선택 사항)
워크로드가 서드파티 레지스트리에서 pull하는 빈도를 이해하려면 상위 레지스트리의 사용 분석을 검토하세요(예를 들어 Docker Hub는 계정 대시보드에서 pull 비율 데이터를 제공합니다). pull 빈도가 높으면 요금 제한에 걸릴 위험이 커집니다. Docker Hub 요금 제한에 대한 자세한 내용은 Docker 문서의 Docker Hub rate limiting을 참조하세요.
Step 2: 리포지토리 구조 계획
이미지를 복사하기 전에 Amazon ECR에서 이미지를 구성하는 방법을 결정하세요.
- 리포지토리 이름 지정 (Repository naming) – Amazon ECR은 슬래시가 있는 네임스페이스 접두사를 지원합니다. 네임스페이스를 사용해 관련 이미지를 팀, 환경 또는 애플리케이션별로 그룹화하세요. 네임스페이스는 또한 접두사별로 범위가 지정된 IAM 정책을 가능하게 합니다. 예를 들어:
base-images/python
base-images/nginx
team-a/web-app
team-b/api-service
- 태그 불변성 (Tag immutability) – 프로덕션 이미지의 경우 태그 불변성을 활성화해 이미지 태그가 덮어써지지 않도록 방지하세요. 자세한 내용은 Preventing image tags from being overwritten in Amazon ECR를 참조하세요.
- 암호화 (Encryption) – 리포지토리를 만들기 전에 암호화 구성을 선택하세요. 리포지토리 생성 후에는 암호화 구성을 변경할 수 없습니다. 자세한 내용은 Encryption at rest를 참조하세요.
- 스토리지 비용 (Storage costs) – Amazon ECR은 각 리포지토리 내에서 이미지 레이어를 중복 제거합니다. 여러 이미지가 같은 기본 레이어를 공유한다면 해당 레이어에 대해 리포지토리당 한 번만 청구됩니다. 마이그레이션할 이미지를 계획할 때 이 점을 비용 추정에 반영하세요.
- 리포지토리 생성 템플릿 (Repository creation templates) – 많은 이미지를 마이그레이션한다면 선호하는 설정(태그 불변성, 암호화, 수명 주기 정책)으로 push 시 생성(create-on-push) 작업을 위한 리포지토리 생성 템플릿을 구성하세요. Amazon ECR은 첫 번째 push 중에 리포지토리를 대신 생성할 때 템플릿 설정을 적용합니다. 자세한 내용은 Templates to control repositories created during a pull through cache, create on push, or replication action을 참조하세요.
- 관리형 서명 (Managed signing) – 관리형 서명으로 이미지에 서명할 계획이라면 이미지를 push하기 전에 서명 규칙을 구성하세요. 서명은 push 시에만 발생합니다. 자세한 내용은 Sign images in Amazon ECR을 참조하세요.
- 교차 리전 복제 (Cross-Region replication) – 워크로드가 여러 AWS 리전에서 실행된다면 이미지를 push하기 전에 복제 규칙을 구성하세요. 복제는 규칙이 구성된 후 push된 이미지만 복사합니다. 자세한 내용은 Private image replication in Amazon ECR을 참조하세요.
참고
다중 아키텍처 이미지(manifest list)는 매니페스트 목록 외에도 모든 플랫폼별 매니페스트를 복사해야 합니다. Docker를 사용하면 docker pull 및 docker push 명령은 로컬 아키텍처와 일치하는 플랫폼만 처리합니다. 모든 플랫폼이 유지된 다중 아키텍처 이미지를 복사하려면 skopeo copy --all을 사용하세요.
Step 3: 이미지를 Amazon ECR로 복사
이미지를 복사하기 전에 Amazon ECR 프라이빗 레지스트리에 인증하세요. 레지스트리 URL은 account-id.dkr.ecr.region.amazonaws.com 형식을 따릅니다. 아래 예에서 111122223333을 AWS 계정 ID로, us-east-1을 사용자의 리전으로 바꾸세요. aws-cn 파티션에서 레지스트리 URL 접미사는 .amazonaws.com.cn입니다. 다른 모든 파티션(aws, aws-us-gov)에서는 접미사가 .amazonaws.com입니다.
계정 ID를 찾으려면 다음을 실행하세요.
aws sts get-caller-identity --query Account --output text
인증 방법에 대한 자세한 내용은 Private registry authentication in Amazon ECR을 참조하세요.
Docker(옵션 A)를 사용한다면 다음으로 인증하세요.
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
skopeo(옵션 B)를 사용한다면 대신 skopeo login으로 인증하세요. Skopeo는 Docker와는 별개인 자체 자격 증명 저장소를 유지합니다.
aws ecr get-login-password --region us-east-1 | \
skopeo login 111122223333.dkr.ecr.us-east-1.amazonaws.com --username AWS --password-stdin
이미지를 복사하려면 다음 방법 중 하나를 선택하세요.
옵션 A: Docker CLI로 복사
매우 적은 수의 단일 플랫폼 이미지에 이 방법을 사용하세요. push 워크플로의 자세한 안내는 Moving an image through its lifecycle in Amazon ECR을 참조하세요.
대상 리포지토리 생성(리포지토리가 이미 존재한다면 이 단계를 건너뜁니다):
aws ecr create-repository \
--repository-name base-images/nginx \
--region us-east-1 \
--image-tag-mutability IMMUTABLE \
--encryption-configuration encryptionType=AES256
요금 제한을 피하기 위해 인증된 계정으로 Docker Hub에서 pull한다면 먼저 docker login docker.io를 실행하세요. 서드파티 레지스트리에서 이미지를 pull합니다.
docker pull nginx:1.25
Amazon ECR 리포지토리용으로 이미지에 태그를 지정합니다.
docker tag nginx:1.25 111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
이미지를 Amazon ECR로 push합니다.
docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
생성 후 리포지토리 URI를 검색하려면 다음을 실행합니다.
aws ecr describe-repositories --repository-names base-images/nginx --query 'repositories[0].repositoryUri' --output text
참고
Docker CLI는 로컬 머신과 일치하는 플랫폼만 복사합니다. 다중 아키텍처 이미지를 복사하려면 skopeo와 함께 옵션 B를 사용하세요.
옵션 B: skopeo로 복사 (대량 마이그레이션에 권장)
skopeo 도구는 이미지를 로컬 머신으로 pull하지 않고 레지스트리 간에 직접 복사합니다. 이 방식은 대량 작업에서 더 빠르며 다중 아키텍처 이미지를 지원합니다. Skopeo는 이미지 위치를 식별하기 위해 전송 접두사를 사용합니다. 원격 레지스트리에는 docker:// 를 사용하세요.
필요한 경우 소스 레지스트리에 인증합니다. 예를 들어 Docker Hub의 경우:
echo YOUR_TOKEN | skopeo login docker.io --username YOUR_USERNAME --password-stdin
대상 리포지토리를 생성합니다.
aws ecr create-repository \
--repository-name base-images/nginx \
--region us-east-1
이미지를 복사합니다(단일 플랫폼).
skopeo copy docker://docker.io/library/nginx:1.25 \
docker://111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
모든 플랫폼을 포함한 다중 아키텍처 이미지를 복사하려면 --all 플래그를 추가합니다.
skopeo copy --all docker://docker.io/library/nginx:1.25 \
docker://111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
참고
skopeo copy는 이미지와 연결된 OCI 리퍼러 아티팩트(서명, SBOM, 증명)를 복사하지 않습니다. 소스 이미지에 연결된 리퍼러 아티팩트가 있다면 별도로 복사하거나 마이그레이션 후 관리형 서명을 사용해 이미지에 다시 서명하세요.
스크립트로 대량 복사
여러 이미지를 마이그레이션하려면 소스와 대상 쌍을 나열하는 텍스트 파일을 만든 다음 스크립트를 사용해 복사하세요.
images-to-migrate.txt 파일을 만듭니다.
docker.io/library/nginx:1.25 base-images/nginx:1.25
docker.io/library/python:3.11-slim base-images/python:3.11-slim
docker.io/library/redis:7-alpine base-images/redis:7-alpine
ghcr.io/org/custom-app:v2.1.0 team-a/custom-app:v2.1.0
다음 스크립트를 실행합니다.
#!/usr/bin/env bash
set -euo pipefail
ACCOUNT_ID="111122223333"
REGION="us-east-1"
REGISTRY="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com"
aws ecr get-login-password --region ${REGION} | \
skopeo login ${REGISTRY} --username AWS --password-stdin
while IFS=' ' read -r SOURCE DEST; do
REPO_NAME=$(echo "${DEST}" | cut -d: -f1)
# Create repository if it does not exist
aws ecr create-repository \
--repository-name "${REPO_NAME}" \
--region "${REGION}" 2>/dev/null || true
echo "Copying ${SOURCE} to ${REGISTRY}/${DEST}"
skopeo copy --all "docker://${SOURCE}" "docker://${REGISTRY}/${DEST}"
done < images-to-migrate.txt
참고
Amazon ECR은 push 작업에 API 요금 제한을 적용합니다. 대규모 마이그레이션에서는 제한(스로틀링)이 발생하면 지수 백오프가 있는 재시도 로직을 추가하세요. 권한 부여 토큰은 12시간 후 만료됩니다. 마이그레이션 시간이 더 길다면 계속하기 전에 인증 명령을 다시 실행하세요.
Step 4: 이미지 무결성 검증
이미지를 복사한 후 Amazon ECR의 이미지 다이제스트가 소스와 일치하는지 확인하세요.
Amazon ECR에 있는 이미지의 다이제스트를 얻습니다.
aws ecr describe-images \
--repository-name base-images/nginx \
--image-ids imageTag=1.25 \
--query 'imageDetails[0].imageDigest' \
--output text
참고
단일 플랫폼 이미지의 경우 다이제스트를 직접 비교하세요. --all 로 복사한 다중 아키텍처 이미지의 경우 Amazon ECR의 imageDigest는 매니페스트 목록을 나타냅니다. 대신 아래에 보이는 skopeo inspect --raw 를 사용해 매니페스트 목록 내용을 비교하세요.
소스 레지스트리와 다이제스트를 비교합니다. skopeo를 사용해 소스를 검사합니다.
skopeo inspect docker://docker.io/library/nginx:1.25 | grep Digest
skopeo로 복사한 단일 플랫폼 이미지의 경우 다이제스트가 일치해야 합니다. 일치하지 않는다면 복사가 성공적으로 완료되지 않은 것입니다. 복사 작업을 다시 시도하세요. Docker(옵션 A)를 사용했다면 Docker가 pull과 push 중에 레이어를 다시 처리할 수 있으므로 다이제스트가 다를 수 있습니다. 정확한 다이제스트 보존을 위해서는 skopeo를 사용하세요.
다중 아키텍처 이미지의 경우 aws ecr describe-images 는 매니페스트 목록과 개별 플랫폼 매니페스트를 모두 반환합니다. 매니페스트 목록 다이제스트를 직접 비교하려면 소스와 대상 모두에서 skopeo inspect --raw 를 사용하세요.
skopeo inspect --raw docker://111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
(선택 사항) 마이그레이션된 이미지에 이미지 스캔을 실행해 취약점을 식별합니다. 자세한 내용은 Scan images for software vulnerabilities in Amazon ECR을 참조하세요.
Step 5: 배포 구성 업데이트
이미지를 검증한 후 Amazon ECR에서 pull하도록 배포 구성을 업데이트하고, 새로 빌드된 이미지를 ECR로 push하도록 CI/CD 빌드 파이프라인을 업데이트하세요. 이렇게 하면 추가 수동 복사 없이 향후 이미지 버전을 사용할 수 있습니다.
Amazon ECS 작업 정의
업데이트된 이미지 URI로 작업 정의의 새 개정을 만듭니다.
{
"containerDefinitions": [
{
"name": "web",
"image": "111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25"
}
]
}
자세한 내용은 Amazon ECS Developer Guide의 Updating a task definition을 참조하세요.
Amazon EKS 또는 Kubernetes 매니페스트
파드 사양의 image 필드를 업데이트합니다.
spec:
containers:
- name: web
image: 111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
노드가 Amazon ECR에 인증할 수 있는지 확인합니다. Amazon EKS 노드는 AmazonEC2ContainerRegistryReadOnly 관리형 정책이 노드 IAM 역할에 연결되어 있으면 기본적으로 Amazon ECR 자격 증명 헬퍼를 사용합니다.
Dockerfile
Dockerfile에서 FROM 지시문을 업데이트합니다.
FROM 111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/python:3.11-slim
Step 6: 모니터링 및 검증
워크로드를 재배포한 후 모든 이미지 pull이 Amazon ECR에서 발생하는지 확인하세요.
- 리포지토리의 CloudWatch 지표를 확인합니다. RepositoryPullCount 지표로 pull이 발생하고 있음을 확인할 수 있습니다. 자세한 내용은 Amazon ECR repository metrics를 참조하세요.
- CloudTrail에서 BatchGetImage 및 GetDownloadUrlForLayer 이벤트를 검토해 워크로드가 예상 리포지토리에서 pull하는지 확인하세요.
- (선택 사항) 수명 주기 정책을 설정해 오래된 이미지 버전의 정리를 자동화하세요.
고려 사항 (Considerations)
- 지원되지 않는 상위 레지스트리 (Unsupported upstream registries) – Pull Through Cache는 특정 상위 레지스트리 집합을 지원합니다. 해당 목록에 없는 레지스트리(예: JFrog Artifactory, Harbor, Sonatype Nexus)는 Docker CLI 또는 skopeo를 사용해 이미지를 직접 복사하세요.
- 대규모 또는 교차 파티션 전송 (Large-scale or cross-partition transfers) – AWS 파티션 간 마이그레이션(예: aws에서 aws-cn으로) 또는 수천 개의 이미지가 포함된 전송은 Guidance for Data Transfer Hub on AWS를 참조하세요.
- Lambda – Lambda는 컨테이너 이미지가 Amazon ECR에 있어야 하며 서드파티 레지스트리에서 직접 pull할 수 없습니다. Lambda 함수를 구성하기 전에 옵션 A 또는 옵션 B를 사용해 이미지를 ECR로 복사하세요.
관련 접근 방식 (Related approaches)
- 풀 스루 캐시 (Pull Through Cache) – 소스 레지스트리가 지원되는 상위 레지스트리 중 하나이고 일회성 복사 대신 Amazon ECR이 이미지를 자동으로 pull하고 캐시하길 원한다면 Sync an upstream registry with an Amazon ECR private registry를 참조하세요.
더 알아보기 (Learn more)
- Amazon ECR 프라이빗 레지스트리
- Amazon ECR 이미지 scan
- Amazon ECR 프라이빗 이미지 복제