AWS ECS Blue/Green CodePipeline:尝试读取图像工件时出现异常
Posted
技术标签:
【中文标题】AWS ECS Blue/Green CodePipeline:尝试读取图像工件时出现异常【英文标题】:AWS ECS Blue/Green CodePipeline: Exception while trying to read the image artifact 【发布时间】:2020-09-13 07:03:42 【问题描述】:我想创建一个 CodePipeline,它从 CodeCommit 源构建容器映像,然后以蓝/绿方式将新映像部署到我的 ECS 服务(EC2 启动类型)。
源阶段为 CodeCommit,其中已包含 appspec.json 以及 taskdef.json 构建阶段正在构建新的 容器并将其成功推送到 ECR,文件 imagedefinition.json 是这一步创建的 BuildArtifact, 包含容器和最近创建的图像及其 与 CodeCommit 提交 ID 对应的标签。 部署阶段 由操作“Amazon ECS(蓝/绿)”组成,使用 SourceArtifact 和 BuildArtifact 作为 InputArtifacts,取 来自 SourceArtifact 和图像的 appspec 和 taskdef BuildArtifact 中的描述,以最终部署新的 蓝色/绿色方式的容器。问题在于 BuildArtifact 中的图像定义。管道在部署阶段失败并出现错误:
"" 无效的动作配置 尝试从工件读取图像工件文件时出现异常:BuildArtifact。 ""
如何正确配置“Amazon ECS(蓝/绿)”部署阶段,以便它可以使用最近创建的映像并部署它....通过替换 taskdef.json 中的占位符 IMAGE_NAME ?
高度赞赏的任何提示:D
【问题讨论】:
【参考方案1】:Amazon ECS 蓝/绿(或 CodeDeployToECS)CodePipeline 操作需要 TaskDefinitionTemplateArtifact 参数(请参阅 [1])。
除了上述文件注意之外,ECS 蓝/绿部署还需要 imageDetail.json(不是“imagedefinition.json”)。文件结构和详细信息可在此处获得 [2]。将此文件添加到部署工件/版本控制的根目录。如果您不想手动添加此文件,您可以使用 ECR 源操作到 CodePipeline 并使用您在 ECS 服务/taskdef.json 中使用的图像进行配置。为了清楚起见,所有这些都在 [2] 中进行了讨论。
要了解这一切是如何组合在一起的,您还可以按照此处 [3] 的 ECS 蓝/绿部署分步说明进行操作。
参考资料:
[1] https://docs.aws.amazon.com/codepipeline/latest/userguide/reference-pipeline-structure.html#action-requirements : CodePipeline 管道结构参考 - CodePipeline 中的操作结构要求 [2] https://docs.aws.amazon.com/codepipeline/latest/userguide/file-reference.html#file-reference-ecs-bluegreen:图像定义文件参考 - 用于 Amazon ECS 蓝/绿部署操作的 imageDetail.json 文件 [3] https://docs.aws.amazon.com/codepipeline/latest/userguide/tutorials-ecs-ecr-codedeploy.html:教程:使用 Amazon ECR 源和 ECS-to-CodeDeploy 部署创建管道
【讨论】:
非常感谢@shariqmaws 的提示。该教程我已经阅读了好几遍,但它没有为我提供最后的提示,因为它使用 ECR 作为源,但我想将容器构建为管道本身的一部分。其他链接非常有帮助,因此我可以解决我的问题,提供最终解决方案作为单独的答案。【参考方案2】:在这里回答我自己的问题,希望它可以帮助面临同样情况的其他人。
-
文件 imagedefinitions.json 不适合部署操作“Amazon ECS Blue/Green”。为此,您必须在构建步骤中创建文件 imageDetail.json 并将其作为工件提供给部署步骤。如何 ?这是我的 buildspec.yaml 底部的样子:
- printf '"ImageURI":"%s"' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
artifacts:
files:
- 'image*.json'
- 'appspec.yaml'
- 'taskdef.json'
secondary-artifacts:
DefinitionArtifact:
files:
- appspec.yaml
- taskdef.json
ImageArtifact:
files:
- imageDetail.json
-
在 CodePipeline 的 Deploy 阶段,使用 DefinitionArtifact 和 ImageArtifact 作为 Input Artifact,并在相应的“Amazon ECS 任务定义”和“AWS CodeDeploy AppSpec file部分进行配置”。
确保您的 appspec.yaml 包含任务定义的占位符。这是我的 appspec.yaml:
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: <TASK_DEFINITION>
LoadBalancerInfo:
ContainerName: "my-test-container"
ContainerPort: 8000
还要确保您的 taskdef.json 包含最终图像的占位符,例如
...
"image": <IMAGE1_NAME>,
...
-
在“动态更新任务定义图像 - 可选”部分的蓝/绿部署阶段的代码管道配置中使用该占位符,方法是选择输入工件为“ImageArtifact”和占位符 @987654324 @
【讨论】:
次要注意,占位符不应包含方括号。 我对占位符的使用有点困惑。我收到此错误:名为的图像 URI 容器:谢谢大家,这让我对解决问题有了一些了解。
我想补充一点,当您使用aws cli
、cloudformation
或Terraform
配置codepipeline
时,一些参数和选项在控制台中不可用,并在这些工具中设置一些变量,如空string "" 会导致异常错误。
使用这些工具进行部署时,请始终检查控制台中的codepipeline
设置。
所以当您定义 Image Artifact 但未定义占位符时会发生错误
imageDetail.json 可以使用以下方法传入codedeploy
:
CodeBuild
source - 您使用 codebuild
buildspec.yml 更新文件并将其传递给 codedeploy
阶段。
【讨论】:
【参考方案4】:我遇到了同样的问题。
tl:dr
我没有将带有 imageDetail.json 的正确输入工件传递给管道 CodeDeployToECS 操作。
总结:
我没有使用“
项目早期的任务定义非常不稳定,新变量等被传递给容器。它在管道 (Cloudformation) 中生成和注册,然后通过 Codebuild 项目读出,用“
修复它:
-
我在生成 imageDetail.json 的管道中有一个 CodeBuild 项目:
"ImageURI":"########.dkr.ecr.eu-west-1.amazonaws.com/##/#####:2739511dd87d4e4e1f65ed69c9e779b63fb72e36-master-fbe73fdc-6213-4bd6-a784-dcc3d2ae7845"
它的管道输出名为“BuildDockerOutput”
-
我有另一个 Codebuild 项目产生:
taskdef.json
"containerDefinitions": [
"name": "ronantest1",
"image": "<IMAGE1_NAME>",
]
appspec.json
"version": 0.0,
"Resources": [
"TargetService":
"Type": "AWS::ECS::Service",
"Properties":
"TaskDefinition": "<TASK_DEFINITION>",
"LoadBalancerInfo":
"ContainerName": "ronantest1",
"ContainerPort": "8080"
],
"Hooks": [
"AfterAllowTestTraffic": "arn:aws:lambda:eu-west-1:######:function:code-deploy-after-allow-test-traffic"
]
它的管道输出名为“PrepareCodeDeployOutputTesting”
我的最终 CodeDeploy 操作如下所示:
- Name: BlueGreenDeploy
InputArtifacts:
- Name: BuildDockerOutput
- Name: PrepareCodeDeployOutputTesting
Region: !Ref DeployRegion1
ActionTypeId:
Category: Deploy
Owner: AWS
Version: '1'
Provider: CodeDeployToECS
RoleArn: !Sub arn:aws:iam::$TestingAccountId:role/######/CrossAccountsDeploymentRole
Configuration:
AppSpecTemplateArtifact: PrepareCodeDeployOutputTesting
AppSpecTemplatePath: appspec.json
ApplicationName: !Ref ApplicationName
DeploymentGroupName: !Ref ApplicationName
TaskDefinitionTemplateArtifact: PrepareCodeDeployOutputTesting
TaskDefinitionTemplatePath: taskdef.json
Image1ArtifactName: BuildDockerOutput
Image1ContainerName: "IMAGE1_NAME"
RunOrder: 4
注意 CodeDeployToECS 的不同方面需要来自不同 InputArtifacts 的人工制品,特别是“Image1ArtifactName”
【讨论】:
以上是关于AWS ECS Blue/Green CodePipeline:尝试读取图像工件时出现异常的主要内容,如果未能解决你的问题,请参考以下文章
PCL进阶:点云渲染渐变赋色(Blue>Green>Yellow>Red)
如何让 CodeDeploy Blue/Green 为自定义指标创建 CloudWatch 警报?
如何在 AWS ECS 集群的服务中运行 AWS ECS 任务,而不是将服务从 Circle CI 的“aws-ecs/run-task”中排除