View a markdown version of this page

跨 AWS 帳戶 和 複製 Amazon ECR 容器映像 AWS 區域 - 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 帳戶 (一個來源帳戶和一個目的地帳戶,至少)

  • 所有帳戶中的適當 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 執行配額。

Architecture

目標堆疊

模式有四個主要元件:

  • 來源帳戶基礎設施 – 建立協同運作元件的 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) 可協助您協調和管理發佈者和用戶端之間的訊息交換,包括 Web 伺服器和電子郵件地址。

  • AWS Identity and Access Management (IAM) 透過控制已驗證並獲授權使用的人員,協助您安全地管理對 AWS 資源的存取。

  • AWS Lambda 是一項運算服務,可協助您執行程式碼,無需佈建或管理伺服器。它只會在需要時執行程式碼並自動擴展,因此您只需按使用的運算時間付費。

  • AWS Step Functions 是一種無伺服器協同運作服務,可協助您結合 Lambda 函數和其他 AWS 服務 來建置業務關鍵應用程式。

其他工具

  • Crane 是 Docker 協同運作工具。它類似於 Docker Compose,但有其他功能。

  • Docker 是一組平台即服務 (PaaS) 產品,可在作業系統層級使用虛擬化在容器中交付軟體。

程式碼儲存庫

  • 此模式的程式碼可在 GitHub sample-ecr-copy 儲存庫中使用。您可以從儲存庫使用 CloudFormation 範本來建立基礎資源。

最佳實務

遵循最低權限原則,並授予執行任務所需的最低許可。如需詳細資訊,請參閱 IAM 文件中的授予最低權限安全最佳實務

史詩

任務Description所需的技能

設定 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 工程師
任務Description所需的技能

驗證範本。

驗證 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
資料工程師、ML 工程師、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 工程師、資料工程師
任務Description所需的技能

準備容器建置。

  1. 確認 Docker 正在執行:

    docker --version docker info
  2. 確定 crane-app.pyDockerfile 位於目前的目錄中:

    ls -la crane-app.py Dockerfile
資料工程師、ML 工程師、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')"
資料工程師、ML 工程師、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"
資料工程師、ML 工程師、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
資料工程師、ML 工程師、DevOps 工程師
任務Description所需的技能

準備部署參數。

  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 工程師、ML 工程師

驗證來源範本。

驗證來源 CloudFormation 範本:

aws cloudformation validate-template \ --template-body file://"Source Account Cf template.yml" \ --profile source-account
資料工程師、ML 工程師、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
資料工程師、ML 工程師、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 Resource Name (ARNs):

    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
資料工程師、ML 工程師、DevOps 工程師
任務Description所需的技能

執行並監控複製程序。

  1. 登入 AWS 管理主控台,然後開啟 Step Functions 主控台

  2. 找到狀態機器。

  3. 選擇 Start execution (開始執行)

    完成後,結果會顯示在執行輸入和輸出索引標籤上。

  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 工程師

疑難排解

問題解決方案

步驟函數無法執行。

  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 容器映像 URI

${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com/ecr-copy-lambda:latest