跨帳戶或區域複製篩選過的 Amazon ECR 容器映像 - AWS Prescriptive Guidance

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

跨帳戶或區域複製篩選過的 Amazon ECR 容器映像

由阿達爾加魯巴 (AWS) 創建

環境:生產

技能:容器與微服務;DevOps

AWS 服務:AWS EC2 Container Registry;Amazon CloudWatch;AWS CodeBuild;AWS Identity and Access Management;AWS CLI

Summary

此模式描述如何根據影像標籤模式,跨 Amazon Web 服務 (AWS) 帳戶和 AWS 區域複寫儲存在 Amazon 彈性容器登錄 (Amazon ECR) 中的容器映像。此模式使用 Amazon CloudWatch Events 來偵聽具有預先定義、自訂標籤的映像的推送事件。推送事件會啟動 AWS CodeBuild 專案,並將映像詳細資料傳遞給該專案。CodeBuild 專案會根據所提供的詳細資料,將影像從來源 Amazon ECR 註冊表複製到目標註冊表。

Amazon ECR 支援映像的跨區域和跨帳戶複寫。這兩個選項都會複寫所有推送到來源登錄的新映像。如需詳細資訊,請參閱「」私人映像複製在 Amazon ECR 文檔中。) 但是,無法根據任何條件篩選跨 AWS 區域或帳戶複製的映像。 

此樣式會在帳戶間複製具有特定標籤的影像。例如,您可以使用此模式僅將生產就緒的安全映像複製到生產 AWS 帳戶。在開發帳戶中,在完整測試映像之後,您可以將預先定義的標籤新增至安全映像,並使用此模式中的步驟將標記的映像複製到生產帳戶。

先決條件和限制

先決條件

  • 來源和目標 Amazon ECR 登錄機的有效 AWS 帳戶

  • 此模式中使用之工具的系統管理權限

  • Docker安裝在本機電腦上進行測試

  • AWS 命令列界面 (AWS CLI),用於對亞馬遜 ECR 進行身份驗證

限制

  • 此模式僅監視一個 AWS 區域中來源登錄的推送事件。您可以將此模式部署到其他區域,以監視這些區域中的登錄。

  • 在此模式中,一個 Amazon CloudWatch Events 規則會偵聽單一影像標籤模式。如果您想要檢查多個模式,您可以添加事件來監聽其他圖像標籤模式。

Architecture

目標架構

自動化與擴充

這種模式可以使用基礎結構即程式碼 (iAC) 指令碼進行自動化,並以大規模的方式部署。若要使用 AWS CloudFormation 範本來部署此模式,請下載附件並遵循其他資訊區段。

您可以將多個 Amazon CloudWatch Events 件事件 (具有不同的自訂事件模式) 指向同一個 AWS CodeBuild 專案,以複寫多個影像標籤模式,但您需要更新buildspec.yaml文件(包含在附件中和工具區段),如下所示支援多種模式。

... if [[ ${IMAGE_TAG} != release-* ]]; then ...

Tools

Amazon Services

  • IAM— AWS Identity and Access Management (IAM) 可讓您安全地管理對 AWS 服務和資源的存取。在這種模式中,您需要創建 AWS CodeBuild 將在將容器映像推送到目標註冊表時承擔的跨帳戶 IAM 角色。

  • Amazon ECR— Amazon EElastic Container Registry (Amazon ECR) 是一種完全受管的容器登錄檔,可讓您輕鬆存放、管理、共用和部署容器映像和成品。影像推送動作至來源登錄會將系統事件詳細資料傳送至 Amazon CloudWatch Events 事件所拾取的事件匯流排。

  • AWS CodeBuild— AWS CodeBuild 是一項完全受管的持續整合服務,提供運算能力來執行工作,例如編譯原始程式碼、執行測試,以及產生可供部署的成品。此模式使用 AWS CodeBuild 從來源 Amazon ECR 註冊表執行複製操作到目標註冊表。

  • CloudWatch 活動— Amazon CloudWatch Events 會提供描述 AWS 資源中的變動情形的系統事件串流。此模式使用規則將 Amazon ECR 推送動作與特定影像標籤模式進行比對。

工具

  • Docker CLI— Docker 是一種可讓您更輕鬆地建立和管理容器。容器會將應用程式及其所有相依性封裝到一個單元或封裝中,這些單元或封裝可以輕鬆部署在支援容器執行階段的任何平台上。

Code

您可透過兩種方式實現此模式:

  • 自動化設定:部署附件中提供的兩個 AWS CloudFormation 格式範本。如需說明,請參閱其他資訊區段。

  • 手動設定:請遵循史詩區段。 

範例建置規格。yaml

如果您使用的是隨此模式提供的 CloudFormation 模板,buildspec.yaml文件包含在 CodeBuild 資源中。

version: 0.2   env:     shell: bash   phases:     install:       commands:         - export CURRENT_ACCOUNT=$(echo ${CODEBUILD_BUILD_ARN} | cut -d':' -f5)         - export CURRENT_ECR_REGISTRY=${CURRENT_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com         - export DESTINATION_ECR_REGISTRY=${DESTINATION_ACCOUNT}.dkr.ecr.${DESTINATION_REGION}.amazonaws.com     pre_build:       on-failure: ABORT       commands:         - echo "Validating Image Tag ${IMAGE_TAG}"         - |           if [[ ${IMAGE_TAG} != release-* ]]; then             aws codebuild stop-build --id ${CODEBUILD_BUILD_ID}             sleep 60             exit 1           fi         - aws ecr get-login-password --region ${AWS_REGION} | docker login -u AWS --password-stdin ${CURRENT_ECR_REGISTRY}         - docker pull ${CURRENT_ECR_REGISTRY}/${REPO_NAME}:${IMAGE_TAG}     build:       commands:         - echo "Assume cross-account role"         - CREDENTIALS=$(aws sts assume-role --role-arn ${CROSS_ACCOUNT_ROLE_ARN} --role-session-name Rolesession)         - export AWS_DEFAULT_REGION=${DESTINATON_REGION}         - export AWS_ACCESS_KEY_ID=$(echo ${CREDENTIALS} | jq -r '.Credentials.AccessKeyId')         - export AWS_SECRET_ACCESS_KEY=$(echo ${CREDENTIALS} | jq -r '.Credentials.SecretAccessKey')         - export AWS_SESSION_TOKEN=$(echo ${CREDENTIALS} | jq -r '.Credentials.SessionToken')         - echo "Logging into cross-account registry"         - aws ecr get-login-password --region ${DESTINATION_REGION} | docker login -u AWS --password-stdin ${DESTINATION_ECR_REGISTRY}         - echo "Check if Destination Repository exists, else create"         - |           aws ecr describe-repositories --repository-names ${REPO_NAME} --region ${DESTINATION_REGION} \           || aws ecr create-repository --repository-name ${REPO_NAME} --region ${DESTINATION_REGION}         - echo "retag image and push to destination"         - docker tag ${CURRENT_ECR_REGISTRY}/${REPO_NAME}:${IMAGE_TAG} ${DESTINATION_ECR_REGISTRY}/${REPO_NAME}:${IMAGE_TAG}         - docker push ${DESTINATION_ECR_REGISTRY}/${REPO_NAME}:${IMAGE_TAG}

Epics

任務描述所需技能
建立 CloudWatch Events 角色。

在來源 AWS 帳戶中,為要承擔的 Amazon CloudWatch Events 建立 IAM 角色。角色應該具有啟動 AWS CodeBuild 專案的許可權。

若要使用 AWS CLI 建立角色,請遵循IAM 文件中的指示

信任原則範例 (trustpolicy.json): 

{   "Version": "2012-10-17",   "Statement": {     "Effect": "Allow",     "Principal": {"Service": "ec2.amazonaws.com"},     "Action": "sts:AssumeRole"   } }

權限原則範例 (permissionpolicy.json):

{   "Version": "2012-10-17",   "Statement": {     "Effect": "Allow",     "Action": "codebuild:StartBuild",     "Resource": "<CodeBuild Project ARN>"   } }
AWS 管理員、AWS 開發作業、AWS 系統管理員、雲端管理員、雲端管理員、雲端管理員、裝置工程師
創建一個 CodeBuild 角色。

為 AWS 程式碼建立建立 IAM 角色以假設,方法是遵循IAM 文件中的指示。此角色應具有下列許可:

  • 假設目的地跨帳戶角色的權限

  • 建立日誌群組和日誌串流,並放置日誌事件的許可

  • 所有 Amazon ECR 存放庫的唯讀權限,方法是將AmazonEC2ContainerRegistryReadOnly管政策新增至角色

  • 停止 CodeBuild 的權限

信任原則範例 (trustpolicy.json):

{   "Version": "2012-10-17",   "Statement": [     {       "Effect": "Allow",       "Principal": {         "Service": "codebuild.amazonaws.com"       },       "Action": "sts:AssumeRole"     }   ] }

權限原則範例 (permissionpolicy.json):

{     "Version": "2012-10-17",     "Statement": [         {             "Action": [                 "codebuild:StartBuild",                 "codebuild:StopBuild",                 "codebuild:Get*",                 "codebuild:List*",                 "codebuild:BatchGet*"             ],             "Resource": "*",             "Effect": "Allow"         },         {             "Action": [                 "logs:CreateLogGroup",                 "logs:CreateLogStream",                 "logs:PutLogEvents"             ],             "Resource": "*",             "Effect": "Allow"         },         {             "Action": "sts:AssumeRole",             "Resource": "<ARN of destination role>",             "Effect": "Allow",             "Sid": "AssumeCrossAccountArn"         }     ] }

附加受管政策AmazonEC2ContainerRegistryReadOnly 添加到 CLI 命令,如下所示:

~$ aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly --role-name <name of CodeBuild Role>
AWS 管理員、AWS 開發作業、AWS 系統管理員、雲端管理員、雲端管理員、雲端管理員、裝置工程師
建立跨帳戶角色。

在目標 AWS 帳戶中,為要擔任的來源帳戶的 AWS CodeBuild 角色建立 IAM 角色。跨帳戶角色應允許容器映像建立新的存放庫,並將容器映像上傳到 Amazon ECR。

若要使用 AWS CLI 建立 IAM 角色,請遵循IAM 文件中的指示。 

若要允許上一個步驟中的 AWS CodeBuild 專案,請使用下列信任政策:

{   "Version": "2012-10-17",   "Statement": {     "Effect": "Allow",     "Principal": { "AWS": "<ARN of source codebuild role>" },     "Action": "sts:AssumeRole"   } }

若要允許上一個步驟中的 AWS CodeBuild 專案將映像儲存在目標登錄中,請使用下列權限政策:

{     "Version": "2012-10-17",     "Statement": [         {             "Action": [                 "ecr:GetDownloadUrlForLayer",                 "ecr:BatchCheckLayerAvailability",                 "ecr:PutImage",                 "ecr:InitiateLayerUpload",                 "ecr:UploadLayerPart",                 "ecr:CompleteLayerUpload",                 "ecr:GetRepositoryPolicy",                 "ecr:DescribeRepositories",                 "ecr:GetAuthorizationToken",                 "ecr:CreateRepository"             ],             "Resource": "*",             "Effect": "Allow"         }     ] }
AWS 管理員、AWS 開發作業、雲端管理員、雲端管理員、雲端管理員、開發作業工程師、AWS 系統管理員
任務描述所需技能
創建一個 CodeBuild 項目。

在來源帳戶中建立 AWS CodeBuild 專案,方法是遵循AWS CodeBuild 文件中的指示。該項目應與源登錄檔位於相同的區域。 

設定專案,如下所示:

  • 環境類型:LINUX CONTAINER

  • 服務角色:CodeBuild Role

  • 特殊權限模式:true

  • 環境影像:aws/codebuild/standard:x.x(使用可用的最新圖像)

  • 環境變數:

    • CROSS_ACCOUNT_ROLE_ARN:跨帳戶角色的 Amazon Resource Name (ARN)

    • DESTINATION_REGION:跨帳戶區域的名稱

    • DESTINATION_ACCOUNT:目的地帳戶的編號

  • 建置規格:使用buildspec.yaml檔案中列出工具區段。

AWS 管理員、AWS 開發作業、AWS 系統管理員、雲端管理員、雲端管理員、雲端管理員、裝置工程師
任務描述所需技能
建立 CloudWatch Events 規則。

由於模式使用內容篩選功能,因此您需要使用 Amazon EventBridge 來建立事件。建立事件和目標,請遵循事件 Bridge 文件中的說明,並進行一些修改:

  • 適用於定義陣列中,選擇事件模式,然後選擇自訂模式。

  • 將下列自訂事件模式範例程式碼複製到提供的文字方塊中:

    {   "source": ["aws.ecr"],   "detail-type": ["ECR Image Action"],   "detail": {     "action-type": ["PUSH"],     "result": ["SUCCESS"],     "image-tag": [{ "prefix": "release-"}]   } }
  • 適用於選取目標,選擇 AWS CodeBuild 項目,然後粘貼您在前一個史詩中創建的 AWS 代碼構建項目的 ARN。

  • 適用於設定輸入中,選擇輸入轉換器

    • 在 中

      輸入路徑

      文字方塊中,貼上:

      {"IMAGE_TAG":"$.detail.image-tag","REPO_NAME":"$.detail.repository-name"}
    • 在 中

      輸入範本

      文字方塊中,貼上:

      {"environmentVariablesOverride": [ {"name": "IMAGE_TAG", "value":<IMAGE_TAG>},{"name":"REPO_NAME","value":<REPO_NAME>}]}
  • 選擇使用現有角色,然後選擇您先前在建立 IAM 角色史詩般的。

AWS 管理員、AWS 開發作業、AWS 系統管理員、雲端管理員、雲端管理員、雲端管理員、裝置工程師
任務描述所需技能
使用 Amazon ECR 進行身分驗證。

驗證來源和目的地登錄,請遵循Amazon ECR 文件

AWS 管理員、AWsDevOps、AWS 系統管理員、雲端管理員、DevOps 工程師、雲端管理員
測試映像複製。

在來源帳戶中,將容器映像推送到新的或現有的 Amazon ECR 來源存放庫,其中映像標籤前綴為release-。若要推送影像,請依照Amazon ECR 文件。 

您可以監視 CodeBuild 專案中的進度CodeBuild 主控台。 

在 CodeBuild 專案成功完成後,登入目標 AWS 帳戶,開啟 Amazon ECR 主控台並確認映像存在於目標 ECR 登錄中。

AWS 管理員、AWS 開發作業、AWS 系統管理員、雲端管理員、雲端管理員、雲端管理員、裝置工程師
測試影像排除。

在您的來源帳戶中,將容器映像推送到新的或現有的 Amazon ECR 來源存放庫,其中包含沒有自訂前置詞的映像標籤。 

確認 CodeBuild 專案未啟動,而且沒有容器映像出現在目的地登錄中。

AWS 管理員、AWS 開發作業、AWS 系統管理員、雲端管理員、雲端管理員、雲端管理員、裝置工程師

相關資源

其他資訊

如果要自動部署此病毒碼的資源,請依照下列步驟執行:

  1. 下載附件並提取兩個 CloudFormation 模板:part-1-copy-tagged-images.yamlpart-2-destination-account-role.yaml

  2. 登入AWS CloudFormation 主控台及部署part-1-copy-tagged-images.yaml與來源 Amazon ECR 登錄檔相同的 AWS 帳戶和區域。視需要更新參數。此範本部署下列資源:

    • Amazon CloudWatch Events IAM 角色

    • AWS CodeBuild 專案 IAM 角色

    • AWS CodeBuild 專案

    • AWS CloudWatch Events 規則

  3. 請記得的值SourceRoleName中的輸出索引標籤。在下一個步驟中,您將需要用到此值。

  4. 部署第二個 CloudFormation 模板part-2-destination-account-role.yaml,在您要將 Amazon ECR 容器映像複製到的 AWS 帳戶中。視需要更新參數。對於SourceRoleName參數中,指定步驟 3 的值。此範本會部署跨帳戶 IAM 角色。

  5. 驗證映像複製和排除 (如史詩區段。

Attachments

attachment.zip