跨帳戶或區域複寫篩選過的 Amazon ECR 容器映像 - AWS 方案指引

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

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

創建者:阿卜達爾·加魯巴 (AWS)

環境:生產

技術:容器和微服務; DevOps

AWS 服務:Amazon EC2 容器註冊表;Amazon CloudWatch;AWS CodeBuild;AWS Identity and Access Management;AWS CLI

Summary

Amazon Elastic Container Registry (Amazon ECR) 可以使用跨區域和跨帳戶複寫功能,以原生方式跨 Amazon Web Services (AWS) 區域和 AWS 帳戶複寫映像儲存庫中的所有容器映像檔。如需詳細資訊,請參閱 AWS 部落格文章 Amazon ECR 中的跨區域複寫已登陸。) 但是,無法根據任何條件篩選跨 AWS 區域或帳戶複製的映像。 

此模式說明如何根據映像標籤模式,跨 AWS 帳戶和區域複寫存放在 Amazon ECR 中的容器映像。該模式使用 Amazon E CloudWatch vents 偵聽具有預先定義自訂標籤的映像的推送事件。推送事件會啟動 AWS CodeBuild 專案,並將映像詳細資料傳遞給該專案。 CodeBuild 專案會根據提供的詳細資訊,將來源 Amazon ECR 登錄中的映像複製到目的地登錄。

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

先決條件和限制

先決條件

限制

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

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

架構

目標架構

用於跨 AWS 帳戶和 AWS 區域複寫篩選過的 Amazon ECR 容器映像的架構

自動化和規模

此模式可透過基礎架構即程式碼 (IaC) 指令碼自動化,並大規模部署。若要使用 AWS CloudFormation 範本部署此模式,請下載附件並遵循其他資訊一節中的指示進行操作。

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

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

工具

Amazon 服務

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

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

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

  • CloudWatch 活動 — Amazon CloudWatch 活動提供一系統事件串流,描述 AWS 資源中的變更。此模式使用規則將 Amazon ECR 推送動作與特定影像標籤模式相符。

工具

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

Code

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

  • 自動化設定:部署附件中提供的兩個 AWS CloudFormation 範本。如需指示,請參閱其他資訊一節。

  • 手動設定:依照 Epics 區段中的步驟操作。 

建置規格範例

如果您使用此 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}

史诗

任務描述所需技能

建立「 CloudWatch 事件」角色。

在來源 AWS 帳戶中,為要假設的 Amazon CloudWatch 事件建立 IAM 角色。該角色應具有啟動 AWS CodeBuild 專案的許可。

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

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

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

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

{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "codebuild:StartBuild", "Resource": "<CodeBuild Project ARN>" } }
AWS 管理員、AWS DevOps、AWS 系統管理員、雲端管理員、雲端架構師、 DevOps 工程師

建立 CodeBuild 角色。

按照 IAM 文件中的說明, CodeBuild 為 AWS 建立要假設的 IAM 角色。角色應具有下列權限:

  • 承擔目標跨帳戶角色的權限

  • 建立記錄群組和記錄資料流,以及放置記錄事件的權限

  • 透過將 AmazonEC2 ContainerRegistryReadOnly 受管政策新增至該角色,即可獲得所有 Amazon ECR 儲存庫的唯讀許可

  • 停止權限 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 DevOps、AWS 系統管理員、雲端管理員、雲端架構師、 DevOps 工程師

建立跨帳戶角色。

在目的地 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 DevOps、雲端管理員、雲端架構師、 DevOps 工程師、AWS 系統管理員
任務描述所需技能

創建一個 CodeBuild 項目。

按照 AWS 文 CodeBuild 件中的指示,在來源帳戶中建立 CodeBuild AWS 專案。專案應與來源登錄位於相同的區域。 

設定專案的方式如下:

  • 環境類型:LINUX CONTAINER

  • 服務角色:CodeBuild Role

  • 特權模式:true

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

  • 環境變數:

    • CROSS_ACCOUNT_ROLE_ARN:跨帳戶角色的 Amazon 資源名稱 (ARN)

    • DESTINATION_REGION:跨帳戶區域的名稱

    • DESTINATION_ACCOUNT:目標帳戶的編號

  • 構建規格:使用「工具」部分中列出的buildspec.yaml文件。

AWS 管理員、AWS DevOps、AWS 系統管理員、雲端管理員、雲端架構師、 DevOps 工程師
任務描述所需技能

建立事件規則。

由於該模式使用內容過濾功能,因此您需要使用 Amazon 創建事件 EventBridge。依照文件中的指示建立事 EventBridge 件和目標,並進行一些修改:

  • 在「定義模式」中,選擇「事件模式」,然後選擇「自訂模式」。

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

    {   "source": ["aws.ecr"],   "detail-type": ["ECR Image Action"],   "detail": {     "action-type": ["PUSH"],     "result": ["SUCCESS"],     "image-tag": [{ "prefix": "release-"}]   } }
  • 對於選取目標,請選擇 AWS CodeBuild 專案,然後貼上您在上一個史詩中建立的 AWS CodeBuild 專案的 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 角色史詩中建立的 CloudWatch 事件角色名稱。

AWS 管理員、AWS DevOps、AWS 系統管理員、雲端管理員、雲端架構師、 DevOps 工程師
任務描述所需技能

與 Amazon ECR 進行身份驗證。

遵循 Amazon ECR 文件中的步驟,對來源和目的地登錄進行驗證。

AWS 管理員、AWS DevOps、AWS 系統管理員、雲端管理員、 DevOps 工程師、雲端架構師

測試映像複製。

在您的來源帳戶中,將容器映像推送到新的或現有的 Amazon ECR 來源儲存庫,且影像標籤前置為。release-若要推送映像檔,請依照 Amazon ECR 文件中的步驟執行。 

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

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

AWS 管理員、AWS DevOps、AWS 系統管理員、雲端管理員、雲端架構師、 DevOps 工程師

測試圖像排除。

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

確認 CodeBuild 專案未啟動,且目標登錄中沒有顯示容器映像檔。

AWS 管理員、AWS DevOps、AWS 系統管理員、雲端管理員、雲端架構師、 DevOps 工程師

相關資源

其他資訊

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

  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 活動 IAM 角色

    • AWS CodeBuild 專案 IAM 角色

    • AWS CodeBuild 專案

    • AWS CloudWatch 事件規則

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

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

  5. 驗證映像複製和排除,如 Epics 一節的最後一個步驟所述。

附件

若要存取與此文件相關聯的其他內容,請解壓縮下列檔案:attachment.zip