View a markdown version of this page

AWS 계정 및 간에 Amazon ECR 컨테이너 이미지 복사 AWS 리전 - 권장 가이드

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

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 도구

  • Amazon CloudWatch를 사용하면 AWS 리소스 및에서 실행되는 애플리케이션의 지표를 실시간으로 모니터링할 AWS 수 있습니다.

  • Amazon DynamoDB는 빠르고 예측 가능하고 확장 가능한 성능을 제공하는 완전 관리형 NoSQL 데이터베이스 서비스입니다.

  • Amazon Simple Notification Service(Amazon SNS)를 사용하면 웹 서버 및 이메일 주소를 포함하여 게시자와 클라이언트 간의 메시지 교환을 조정하고 관리할 수 있습니다.

  • AWS Identity and Access Management (IAM)는 AWS 리소스에 대한 액세스를 인증하고 사용할 수 있는 권한을 부여받은 사용자를 제어하여 리소스에 대한 액세스를 안전하게 관리하는 데 도움이 됩니다.

  • AWS Lambda는 서버를 프로비저닝하거나 관리할 필요 없이 코드를 실행하는 데 도움이 되는 컴퓨팅 서비스입니다. 필요할 때만 코드를 실행하며 자동으로 확장이 가능하므로 사용한 컴퓨팅 시간만큼만 비용을 지불합니다.

  • AWS Step Functions는 Lambda 함수 및 기타를 결합하여 비즈니스 크리티컬 애플리케이션을 구축하는 AWS 서비스 데 도움이 되는 서버리스 오케스트레이션 서비스입니다.

기타 도구

  • Crane은 Docker 오케스트레이션 도구입니다. Docker Compose와 비슷하지만 추가 기능이 있습니다.

  • Docker는 운영 체제 수준의 가상화를 사용하여 컨테이너에 소프트웨어를 제공하는 서비스형 플랫폼(PaaS) 제품 세트입니다.

코드 리포지토리

  • 이 패턴의 코드는 GitHub aws-config-rules 리포지토리에서 사용할 수 있습니다. 리포지토리의 CloudFormation 템플릿을 사용하여 기본 리소스를 생성할 수 있습니다.

모범 사례

최소 권한 원칙을 따르고 작업을 수행하는 데 필요한 최소 권한을 부여하세요. 자세한 내용은 IAM 설명서의 최소 권한 부여보안 모범 사례를 참조하세요.

에픽

작업설명필요한 기술

AWS CLI 프로필을 구성합니다.

  1. 소스 계정 구성

    aws configure --profile source-account # Enter: Access Key ID, Secret Access Key, Default region, Output format (json)
  2. 대상 계정 구성

    aws configure --profile destination-account # Enter: Access Key ID, Secret Access Key, Default region, Output format (json)
  3. 구성 확인

    aws sts get-caller-identity --profile source-account aws sts get-caller-identity --profile destination-account
DevOps 엔지니어, 데이터 엔지니어, ML 엔지니어

필수 정보 수집

  1. 소스 계정 ID를 가져옵니다.

    export SOURCE_ACCOUNT_ID=$(aws sts get-caller-identity --profile source-account --query Account --output text) echo "Source Account ID: $SOURCE_ACCOUNT_ID"
  2. 대상 계정 ID를 가져옵니다.

    export DEST_ACCOUNT_ID=$(aws sts get-caller-identity --profile destination-account --query Account --output text) echo "Destination Account ID: $DEST_ACCOUNT_ID"
  3. 를 설정합니다 AWS 리전. 리전에 대해이 명령을 수정합니다.

    export SOURCE_REGION="us-east-1" export DEST_REGION="us-east-2"
  4. 소스 계정의 기존 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 엔지니어, 데이터 엔지니어

대상 인프라를 배포합니다.

  1. 대상 계정 스택을 배포합니다.

    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
  2. 스택 삭제가 완료될 때까지 기다립니다.

    aws cloudformation wait stack-create-complete \ --stack-name ecr-copy-destination \ --profile destination-account \ --region $DEST_REGION
데이터 엔지니어, DevOps 엔지니어

배포를 확인합니다.

  1. 스택 출력 가져오기

    aws cloudformation describe-stacks \ --stack-name ecr-copy-destination \ --profile destination-account \ --region $DEST_REGION \ --query 'Stacks[0].Outputs' \ --output table
  2. 교차 계정 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 엔지니어, 데이터 엔지니어
작업설명필요한 기술

컨테이너 빌드를 준비합니다.

  1. Karpenter가 실행 중인지 확인:

    docker --version docker info
  2. crane-app.pyDockerfile가 현재 디렉터리에 있는지 확인합니다.

    ls -la crane-app.py Dockerfile
데이터 엔지니어, DevOps 엔지니어

를 사용하여 컨테이너 이미지를 빌드합니다.

  1. Lambda 컨테이너 이미지를 빌드합니다.

    docker build -t ecr-copy-lambda . --no-cache
  2. 이미지가 올바르게 생성되었는지 확인합니다.

    docker images ecr-copy-lambda
  3. (선택 사항) 로컬에서 컨테이너를 실행합니다.

    docker run --rm --entrypoint python ecr-copy-lambda -c "import boto3; print('Container working')"
데이터 엔지니어, DevOps 엔지니어

리포지토리 생성 및 이미지 업로드

  1. 소스 계정에서 Amazon ECR 리포지토리를 생성합니다.

    aws ecr create-repository \ --repository-name ecr-copy-lambda \ --profile source-account \ --region $SOURCE_REGION
  2. 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
  3. Amazon ECR 이미지에 태그를 지정합니다.

    docker tag ecr-copy-lambda:latest \ $SOURCE_ACCOUNT_ID.dkr.ecr.$SOURCE_REGION.amazonaws.com/ecr-copy-lambda:latest
  4. Amazon ECR로 이미지 업로드:

    docker push $SOURCE_ACCOUNT_ID.dkr.ecr.$SOURCE_REGION.amazonaws.com/ecr-copy-lambda:latest
  5. 나중에 사용할 수 있도록 이미지 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 엔지니어

이미지를 확인하세요.

  1. 리포지토리의 이미지를 나열하려면

    aws ecr list-images \ --repository-name ecr-copy-lambda \ --profile source-account \ --region $SOURCE_REGION
  2. 이미지 세부 정보를 가져옵니다.

    aws ecr describe-images \ --repository-name ecr-copy-lambda \ --profile source-account \ --region $SOURCE_REGION
데이터 엔지니어, DevOps 엔지니어
작업설명필요한 기술

배포 파라미터

  1. 알림 이메일을 설정합니다.

    export NOTIFICATION_EMAIL="your-email@company.com"
  2. 복사할 리포지토리를 정의합니다(쉼표로 구분).

    export REPOSITORY_LIST="app-frontend,app-backend,database-migrations"
  3. 환경 설정

    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 엔지니어

인프라를 배포합니다.

  1. 소스 계정 스택을 배포합니다.

    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
  2. 스택이 완료될 때까지 기다립니다(최대 10분이 걸릴 수 있음).

    aws cloudformation wait stack-create-complete \ --stack-name ecr-copy-source \ --profile source-account \ --region $SOURCE_REGION
데이터 엔지니어, DevOps 엔지니어

배포를 확인하고 출력을 수집합니다.

  1. 스택 출력 가져오기

    aws cloudformation describe-stacks \ --stack-name ecr-copy-source \ --profile source-account \ --region $SOURCE_REGION \ --query 'Stacks[0].Outputs' \ --output table
  2. 상태 시스템 및 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 엔지니어, 데이터 엔지니어

이메일 구독을 확인합니다.

  1. 이메일에서 SNS 구독 확인을 확인합니다.

  2. 각 수신자는 이메일에서 확인 링크를 선택해야 합니다.

  3. 구독 상태를 확인합니다.

    aws sns list-subscriptions-by-topic \ --topic-arn $SNS_TOPIC_ARN \ --profile source-account \ --region $SOURCE_REGION
데이터 엔지니어, DevOps 엔지니어
작업설명필요한 기술

복사 프로세스를 실행하고 모니터링합니다.

  1. 에 로그인 AWS Management Console하고 Step Functions 콘솔을 엽니다.

  2. 상태 시스템 만들기

  3. 실행 시작을 선택합니다.

    완료되면 실행 입력 및 출력 탭에 결과가 표시됩니다.

  4. (선택 사항)를 사용하여 Step Functions를 계속 실행하려면이 에픽의 나머지 단계를 AWS CLI따릅니다.

DevOps 엔지니어, ML 엔지니어, 데이터 엔지니어

단계 함수를 실행합니다.

  1. 고유한 이름을 생성합니다.

    export EXECUTION_NAME="ecr-copy-$(date +%Y%m%d-%H%M%S)"
  2. 단계 함수를 실행합니다.

    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 엔지니어, 데이터 엔지니어

진행률 모니터링

  1. 상태를 확인합니다.

    aws stepfunctions describe-execution \ --execution-arn $EXECUTION_ARN \ --profile source-account \ --region $SOURCE_REGION \ --query '{Status:status,StartDate:startDate,StopDate:stopDate}' \ --output table
  2. 기록을 가져옵니다.

    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 엔지니어, 데이터 엔지니어

이미지를 확인하세요.

  1. 대상 계정의 리포지토리를 나열합니다.

    aws ecr describe-repositories \ --profile destination-account \ --region $DEST_REGION \ --query 'repositories[].repositoryName' \ --output table
  2. 리포지토리 이미지를 확인합니다.

    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

단계 함수가 실행되지 않습니다.

  1. 기록에서 자세한 실패 이벤트를 검색하려면 다음 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
  2. 실패한 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