기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
AWS 계정 및 간에 Amazon ECR 컨테이너 이미지 복사 AWS 리전
Faisal Shahdad, Amazon Web Services
요약
이 패턴은 서버리스 접근 방식을 사용하여 기존 Amazon Elastic Container Registry(Amazon ECR) 리포지토리에서 태그가 지정된 이미지를 다른 AWS 계정 및 로 복제하는 방법을 보여줍니다 AWS 리전. 이 솔루션은 AWS Step Functions 를 사용하여 복제 워크플로와 AWS Lambda 함수를 관리하여 대용량 컨테이너 이미지를 복사합니다.
Amazon ECR은 리전 및 계정 간에 컨테이너 이미지를 복제하는 네이티브 리전 간 및 계정 간 복제 기능을 사용합니다. 그러나 이러한 기능은 복제가 켜져 있는 순간에만 이미지를 복제합니다. 다른 리전 및 계정의 기존 이미지를 복제하는 메커니즘은 없습니다.
이 패턴은 인공 지능(AI) 팀이 컨테이너화된 기계 학습(ML) 모델, 프레임워크(예: PyTorch, TensorFlow 및 Hugging Face) 및 종속성을 다른 계정 및 리전에 배포하는 데 도움이 됩니다. 이를 통해 서비스 제한을 극복하고 GPU 컴퓨팅 리소스를 최적화할 수 있습니다. 특정 소스 계정 및 리전에서 Amazon ECR 리포지토리를 선택적으로 복제할 수도 있습니다. (자세한 내용은 Amazon ECR의 교차 리전 복제가 도입된 AWS Blog 게시물을 참조하십시오.)
사전 조건 및 제한 사항
사전 조건
둘 이상의 활성 AWS 계정 (소스 계정 하나와 대상 계정 하나, 최소)
모든 계정의 적절한 AWS Identity and Access Management (IAM) 권한
Lambda 컨테이너 이미지를 빌드하기 위한 Docker
AWS Command Line Interface 모든 계정에 대해 구성된 (AWS CLI)
제한 사항
태그가 지정되지 않은 이미지 제외 - 솔루션은 명시적 태그가 있는 컨테이너 이미지만 복사합니다. 다이SHA256제스트와 함께 존재하는 태그가 지정되지 않은 이미지는 건너뜁니다.
Lambda 실행 제한 시간 – AWS Lambda 최대 15분의 실행 제한 시간으로 제한되며, 이는 대용량 컨테이너 이미지 또는 리포지토리를 복사하는 데 충분하지 않을 수 있습니다.
수동 컨테이너 이미지 관리 - crane-app.py Python 코드를 사용하려면 Lambda 컨테이너 이미지를 다시 빌드하고 재배포해야 합니다.
제한된 병렬 처리 용량 - MaxConcurrency 상태 설정은 동시에 복사할 수 있는 리포지토리 수를 제한합니다. 그러나 소스 계정의 AWS CloudFormation 템플릿에서이 설정을 수정할 수 있습니다. 동시성 값이 높을수록 서비스 속도 제한 및 계정 수준 Lambda 실행 할당량을 초과할 수 있습니다.
아키텍처
대상 스택
패턴에는 네 가지 주요 구성 요소가 있습니다.
소스 계정 인프라 - 오케스트레이션 구성 요소를 생성하는 CloudFormation 템플릿
대상 계정 인프라 - 교차 계정 액세스 역할을 생성하는 CloudFormation 템플릿
Lambda 함수 - 효율적인 이미지 복사를 위해 Crane을 사용하는 Python 기반 함수
컨테이너 이미지 - 필요한 도구로 Lambda 함수를 패키징하는 Docker 컨테이너
대상 아키텍처
Step Functions 워크플로우
Step Functions 상태 시스템은 다음 다이어그램과 같이 다음을 오케스트레이션합니다.
PopulateRepositoryList - Amazon ECR 리포지토리를 스캔하고 Amazon DynamoDB를 채웁니다.
GetRepositoryList - DynamoDB에서 고유한 리포지토리 목록을 검색합니다.
DeduplicateRepositories - 중복 처리가 없는지 확인합니다.
CopyRepositories - 리포지토리의 병렬 복사를 처리합니다.
NotifySuccess/NotifyFailure - 실행 결과를 기반으로 하는 Amazon Simple Notification Service(Amazon SNS) 알림
Amazon 도구
기타 도구
코드 리포지토리
모범 사례
최소 권한 원칙을 따르고 작업을 수행하는 데 필요한 최소 권한을 부여하세요. 자세한 내용은 IAM 설명서의 최소 권한 부여 및 보안 모범 사례를 참조하세요.
에픽
| 작업 | 설명 | 필요한 기술 |
|---|
AWS CLI 프로필을 구성합니다. | 소스 계정 구성 aws configure --profile source-account
# Enter: Access Key ID, Secret Access Key, Default region, Output format (json)
대상 계정 구성 aws configure --profile destination-account
# Enter: Access Key ID, Secret Access Key, Default region, Output format (json)
구성 확인 aws sts get-caller-identity --profile source-account
aws sts get-caller-identity --profile destination-account
| DevOps 엔지니어, 데이터 엔지니어, ML 엔지니어 |
필수 정보 수집 | 소스 계정 ID를 가져옵니다. export SOURCE_ACCOUNT_ID=$(aws sts get-caller-identity --profile source-account --query Account --output text)
echo "Source Account ID: $SOURCE_ACCOUNT_ID"
대상 계정 ID를 가져옵니다. export DEST_ACCOUNT_ID=$(aws sts get-caller-identity --profile destination-account --query Account --output text)
echo "Destination Account ID: $DEST_ACCOUNT_ID"
를 설정합니다 AWS 리전. 리전에 대해이 명령을 수정합니다. export SOURCE_REGION="us-east-1"
export DEST_REGION="us-east-2"
소스 계정의 기존 Amazon ECR 리포지토리를 나열합니다. aws ecr describe-repositories --profile source-account --region $SOURCE_REGION --query 'repositories[].repositoryName' --output table
| DevOps 엔지니어, 데이터 엔지니어, ML 엔지니어 |
리포지토리를 복제합니다. | 프로젝트의 리포지토리를 로컬 워크스테이션에 복제합니다. git clone https://github.com/aws-samples/sample-ecr-copy
| DevOps 엔지니어, 데이터 엔지니어, ML 엔지니어 |
| 작업 | 설명 | 필요한 기술 |
|---|
템플릿 확인 | CloudFormation 템플릿 생성 aws cloudformation validate-template \
--template-body file://"Destination Account cf_template.yml" \
--profile destination-account
| DevOps 엔지니어, ML 엔지니어, 데이터 엔지니어 |
대상 인프라를 배포합니다. | 대상 계정 스택을 배포합니다. aws cloudformation deploy \
--template-file "Destination Account cf_template.yml" \
--stack-name ecr-copy-destination \
--parameter-overrides \
SourceAccountId=$SOURCE_ACCOUNT_ID \
SourceRoleName=ECRContainerLambdaRole \
--capabilities CAPABILITY_NAMED_IAM \
--profile destination-account \
--region $DEST_REGION
스택 삭제가 완료될 때까지 기다립니다. aws cloudformation wait stack-create-complete \
--stack-name ecr-copy-destination \
--profile destination-account \
--region $DEST_REGION
| 데이터 엔지니어, DevOps 엔지니어 |
배포를 확인합니다. | 스택 출력 가져오기 aws cloudformation describe-stacks \
--stack-name ecr-copy-destination \
--profile destination-account \
--region $DEST_REGION \
--query 'Stacks[0].Outputs' \
--output table
교차 계정 IAM 역할을 저장합니다. export CROSS_ACCOUNT_ROLE_ARN=$(aws cloudformation describe-stacks \
--stack-name ecr-copy-destination \
--profile destination-account \
--region $DEST_REGION \
--query 'Stacks[0].Outputs[?OutputKey==`CrossAccountRoleArn`].OutputValue' \
--output text)
echo "Cross-Account Role ARN: $CROSS_ACCOUNT_ROLE_ARN"
| DevOps 엔지니어, ML 엔지니어, 데이터 엔지니어 |
| 작업 | 설명 | 필요한 기술 |
|---|
컨테이너 빌드를 준비합니다. | Karpenter가 실행 중인지 확인: docker --version
docker info
crane-app.py 및 Dockerfile가 현재 디렉터리에 있는지 확인합니다.
ls -la crane-app.py Dockerfile
| 데이터 엔지니어, DevOps 엔지니어 |
를 사용하여 컨테이너 이미지를 빌드합니다. | Lambda 컨테이너 이미지를 빌드합니다. docker build -t ecr-copy-lambda . --no-cache
이미지가 올바르게 생성되었는지 확인합니다. docker images ecr-copy-lambda
(선택 사항) 로컬에서 컨테이너를 실행합니다. docker run --rm --entrypoint python ecr-copy-lambda -c "import boto3; print('Container working')"
| 데이터 엔지니어, DevOps 엔지니어 |
리포지토리 생성 및 이미지 업로드 | 소스 계정에서 Amazon ECR 리포지토리를 생성합니다. aws ecr create-repository \
--repository-name ecr-copy-lambda \
--profile source-account \
--region $SOURCE_REGION
Amazon ECR 로그인 토큰을 가져오고 Docker를 인증합니다. aws ecr get-login-password \
--profile source-account \
--region $SOURCE_REGION | \
docker login --username AWS --password-stdin \
$SOURCE_ACCOUNT_ID.dkr.ecr.$SOURCE_REGION.amazonaws.com
Amazon ECR 이미지에 태그를 지정합니다. docker tag ecr-copy-lambda:latest \
$SOURCE_ACCOUNT_ID.dkr.ecr.$SOURCE_REGION.amazonaws.com/ecr-copy-lambda:latest
Amazon ECR로 이미지 업로드: docker push $SOURCE_ACCOUNT_ID.dkr.ecr.$SOURCE_REGION.amazonaws.com/ecr-copy-lambda:latest
나중에 사용할 수 있도록 이미지 URI를 저장합니다. export LAMBDA_IMAGE_URI="$SOURCE_ACCOUNT_ID.dkr.ecr.$SOURCE_REGION.amazonaws.com/ecr-copy-lambda:latest"
echo "Lambda Image URI: $LAMBDA_IMAGE_URI"
| 데이터 엔지니어, DevOps 엔지니어 |
이미지를 확인하세요. | 리포지토리의 이미지를 나열하려면 aws ecr list-images \
--repository-name ecr-copy-lambda \
--profile source-account \
--region $SOURCE_REGION
이미지 세부 정보를 가져옵니다. aws ecr describe-images \
--repository-name ecr-copy-lambda \
--profile source-account \
--region $SOURCE_REGION
| 데이터 엔지니어, DevOps 엔지니어 |
| 작업 | 설명 | 필요한 기술 |
|---|
배포 파라미터 | 알림 이메일을 설정합니다. export NOTIFICATION_EMAIL="your-email@company.com"
복사할 리포지토리를 정의합니다(쉼표로 구분). export REPOSITORY_LIST="app-frontend,app-backend,database-migrations"
환경 설정 export ENVIRONMENT="dev"
echo "Deployment Parameters:"
echo "Source Account: $SOURCE_ACCOUNT_ID"
echo "Destination Account: $DEST_ACCOUNT_ID"
echo "Source Region: $SOURCE_REGION"
echo "Destination Region: $DEST_REGION"
echo "Lambda Image: $LAMBDA_IMAGE_URI"
echo "Notification Email: $NOTIFICATION_EMAIL"
echo "Repositories: $REPOSITORY_LIST"
| 데이터 엔지니어, DevOps 엔지니어 |
소스 템플릿을 검증합니다. | 소스 CloudFormation 템플릿을 검증합니다. aws cloudformation validate-template \
--template-body file://"Source Account Cf template.yml" \
--profile source-account
| 데이터 엔지니어, DevOps 엔지니어 |
인프라를 배포합니다. | 소스 계정 스택을 배포합니다. aws cloudformation deploy \
--template-file "Source Account Cf template.yml" \
--stack-name ecr-copy-source \
--parameter-overrides \
SourceAccountId=$SOURCE_ACCOUNT_ID \
DestinationAccountId=$DEST_ACCOUNT_ID \
DestinationRegion=$DEST_REGION \
SourceRegion=$SOURCE_REGION \
NotificationEmail=$NOTIFICATION_EMAIL \
RepositoryList="$REPOSITORY_LIST" \
LambdaImageUri=$LAMBDA_IMAGE_URI \
Environment=$ENVIRONMENT \
--capabilities CAPABILITY_NAMED_IAM \
--profile source-account \
--region $SOURCE_REGION
스택이 완료될 때까지 기다립니다(최대 10분이 걸릴 수 있음). aws cloudformation wait stack-create-complete \
--stack-name ecr-copy-source \
--profile source-account \
--region $SOURCE_REGION
| 데이터 엔지니어, DevOps 엔지니어 |
배포를 확인하고 출력을 수집합니다. | 스택 출력 가져오기 aws cloudformation describe-stacks \
--stack-name ecr-copy-source \
--profile source-account \
--region $SOURCE_REGION \
--query 'Stacks[0].Outputs' \
--output table
상태 시스템 및 SNS 주제에 대한 Amazon 리소스 이름(ARN)을 저장합니다. export STATE_MACHINE_ARN=$(aws cloudformation describe-stacks \
--stack-name ecr-copy-source \
--profile source-account \
--region $SOURCE_REGION \
--query 'Stacks[0].Outputs[?OutputKey==`StateMachineArn`].OutputValue' \
--output text)
export SNS_TOPIC_ARN=$(aws cloudformation describe-stacks \
--stack-name ecr-copy-source \
--profile source-account \
--region $SOURCE_REGION \
--query 'Stacks[0].Outputs[?OutputKey==`SNSTopicArn`].OutputValue' \
--output text)
echo "State Machine ARN: $STATE_MACHINE_ARN"
echo "SNS Topic ARN: $SNS_TOPIC_ARN"
| DevOps 엔지니어, ML 엔지니어, 데이터 엔지니어 |
이메일 구독을 확인합니다. | 이메일에서 SNS 구독 확인을 확인합니다. 각 수신자는 이메일에서 확인 링크를 선택해야 합니다. 구독 상태를 확인합니다. aws sns list-subscriptions-by-topic \
--topic-arn $SNS_TOPIC_ARN \
--profile source-account \
--region $SOURCE_REGION
| 데이터 엔지니어, DevOps 엔지니어 |
| 작업 | 설명 | 필요한 기술 |
|---|
복사 프로세스를 실행하고 모니터링합니다. | 에 로그인 AWS Management Console하고 Step Functions 콘솔을 엽니다. 상태 시스템 만들기 실행 시작을 선택합니다. 완료되면 실행 입력 및 출력 탭에 결과가 표시됩니다. (선택 사항)를 사용하여 Step Functions를 계속 실행하려면이 에픽의 나머지 단계를 AWS CLI따릅니다.
| DevOps 엔지니어, ML 엔지니어, 데이터 엔지니어 |
단계 함수를 실행합니다. | 고유한 이름을 생성합니다. export EXECUTION_NAME="ecr-copy-$(date +%Y%m%d-%H%M%S)"
단계 함수를 실행합니다. export EXECUTION_ARN=$(aws stepfunctions start-execution \
--state-machine-arn $STATE_MACHINE_ARN \
--name $EXECUTION_NAME \
--profile source-account \
--region $SOURCE_REGION \
--query 'executionArn' \
--output text)
echo "Execution started: $EXECUTION_ARN"
echo "Execution Name: $EXECUTION_NAME"
| DevOps 엔지니어, ML 엔지니어, 데이터 엔지니어 |
진행률 모니터링 | 상태를 확인합니다.
aws stepfunctions describe-execution \
--execution-arn $EXECUTION_ARN \
--profile source-account \
--region $SOURCE_REGION \
--query '{Status:status,StartDate:startDate,StopDate:stopDate}' \
--output table
기록을 가져옵니다.
aws stepfunctions get-execution-history \
--execution-arn $EXECUTION_ARN \
--profile source-account \
--region $SOURCE_REGION \
--query 'events[?type==`TaskStateEntered` || type==`TaskSucceeded` || type==`TaskFailed`].{Type:type,Timestamp:timestamp,Details:stateEnteredEventDetails.name}' \
--output table
| DevOps 엔지니어, ML 엔지니어, 데이터 엔지니어 |
결과를 확인합니다. | 프로세스가 완료될 때까지 기다립니다(30초마다 업데이트됨). while true; do
STATUS=$(aws stepfunctions describe-execution \
--execution-arn $EXECUTION_ARN \
--profile source-account \
--region $SOURCE_REGION \
--query 'status' \
--output text)
echo "Current status: $STATUS"
if [[ "$STATUS" == "SUCCEEDED" || "$STATUS" == "FAILED" || "$STATUS" == "TIMED_OUT" || "$STATUS" == "ABORTED" ]]; then
break
fi
sleep 30
done
echo "Final execution status: $STATUS"
| DevOps 엔지니어, ML 엔지니어, 데이터 엔지니어 |
이미지를 확인하세요. | 대상 계정의 리포지토리를 나열합니다. aws ecr describe-repositories \
--profile destination-account \
--region $DEST_REGION \
--query 'repositories[].repositoryName' \
--output table
리포지토리 이미지를 확인합니다. for repo in $(echo $REPOSITORY_LIST | tr ',' ' '); do
echo "\nImages in repository: $repo"
aws ecr list-images \
--repository-name $repo \
--profile destination-account \
--region $DEST_REGION \
--query 'imageIds[].imageTag' \
--output table 2>/dev/null || echo "Repository $repo not found or no images"
done
| DevOps 엔지니어, 데이터 엔지니어, ML 엔지니어 |
문제 해결
| 문제 | Solution |
|---|
단계 함수가 실행되지 않습니다. | 기록에서 자세한 실패 이벤트를 검색하려면 다음 AWS CLI 명령을 실행합니다. if [[ "$STATUS" == "FAILED" ]]; then
echo "Getting failure details..."
aws stepfunctions get-execution-history \
--execution-arn $EXECUTION_ARN \
--profile source-account \
--region $SOURCE_REGION \
--query 'events[?type==`TaskFailed`]' \
--output json
fi
실패한 Lambda 함수에 대한 로그를 검색하려면 다음 AWS CLI 명령을 실행합니다. # Check Lambda function logs
echo "\nLambda function logs:"
aws logs describe-log-groups \
--log-group-name-prefix "/aws/lambda/ecr-copy-source" \
--profile source-account \
--region $SOURCE_REGION \
--query 'logGroups[].logGroupName' \
--output table
|
관련 리소스
추가 정보
구성 파라미터
파라미터 | 설명 | 예제 |
|---|
SourceAccountId
| 소스 AWS 계정 ID | 11111111111
|
DestinationAccountId
| 대상 AWS 계정 ID | 22222222222
|
DestinationRegion
| 대상 AWS 리전 | us-east-2
|
SourceRegion
| 소스 AWS 리전 | us-east-1
|
NotificationEmail
| 이메일 알림 | abc@xyz.com
|
RepositoryList
| 복사할 리포지토리 | repo1,repo2,repo3
|
LambdaImageUri
| Lambda 컨테이너 이미지 | ${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com/ecr-copy-lambda:latest
|