“最新”标签在 ECS 任务定义和从 ECR 中提取的容器实例中如何工作?

Posted

技术标签:

【中文标题】“最新”标签在 ECS 任务定义和从 ECR 中提取的容器实例中如何工作?【英文标题】:How does "latest" tag work in an ECS task definition and container instances pulling from ECR? 【发布时间】:2019-09-28 13:59:00 【问题描述】:

我在 ECR 任务定义中使用 latest 标记时遇到问题,其中 image 参数的值类似于 XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/reponame/web:latest

一旦在容器实例(注册到集群的 EC2 实例)上运行新的服务实例(任务),我希望此任务定义能够从 ECR 中提取带有 latest 标记的映像。

但是在我的情况下,当我远程连接到容器实例并列出 docker 映像时,我可以看到它没有从 ECR 中提取最新版本的映像。

最新标签在当前版本之后有两个发布版本,从我更新任务定义到使用显式定义版本标签的latest标签实例,即:v1.05

我在这个集群上只有一个容器实例。

我的过程中可能有一些怪癖,但这个问题主要是关于latest 在这种情况下应该如何表现?

我的docker镜像构建和打标签、ECR推送、ECS任务定义更新、ECS服务更新流程:

# Build the image with multiple tags
docker build -t reponame/web:latest -t reponame/web:v1.05 .

# Tag the image with the ECR repo URI
docker tag $imageId XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/reponame/web

# Push both tags separately
docker push XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/reponame/web:v1.05
docker push XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/reponame/web:latest

# Run only if the definition file's contents has been updated
aws ecs register-task-definition --cli-input-json file://web-task-definition.json

# Update the service with force-new-deployment
aws ecs update-service \
  --cluster my-cluster-name \
  --service web \
  --task-definition web \
  --force-new-deployment

带有任务定义文件:


  "family": "web",
  "containerDefinitions": [
    
      "name": "web",
      "image": "XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/reponame/web:latest",
      "essential": true,
      "memory": 768,
      "memoryReservation": 512,
      "cpu": 768,
      "portMappings": [
        
          "containerPort": 5000,
          "hostPort": 80
        
      ],
      "entryPoint": [
        "yarn", "start"
      ],
      "environment": [
        
          "name": "HOST",
          "value": "0.0.0.0"
        ,
        
          "name": "NUXT_HOST",
          "value": "0.0.0.0"
        ,
        
          "name": "NUXT_PORT",
          "value": "5000"
        ,
        
          "name": "NODE_ENV",
          "value": "production"
        ,
        
          "name": "API_URL",
          "value": "/api"
        
      ]
    
  ]

【问题讨论】:

您能出示您的web-task-definition.json 文件吗?可能是您的 docker build 产生了与之前两个版本相同的图像(repo sha256)吗? latest 标记从一个图像移动到另一个图像,但如果您的代码也返回到同一点,则可以返回。 @jogold 我已经编辑了我的问题以包含任务定义文件。 @jogold 看来你是对的,sha256 摘要与这些版本相同。这很奇怪,因为我在 Dockerfile 中使用了 COPY 语句,并且文件夹的内容已经改变,至少在一个文件(package.json)中并且该文件不在 .dockerignore 好的,这至少可以验证您的部署脚本/方法。 【参考方案1】:

在构建新镜像的时候一定要标注并推送latest,否则注册中心上的标注不会更新。 还有一个选项可以在运行镜像时强制拉取,这样 docker 主机就不会假设因为昨天拉取了latest,它今天仍然应该尝试拉取latest

【讨论】:

【参考方案2】:

原来问题出在我的脚本上。正在使用一个不同的变量,该变量的旧值仍存储在我的终端会话中。

我已经验证,通过在任务定义的图像源 URL 中使用 latest 标签确实有一个新启动的服务实例可以从 ECR 中提取带有 latest 标签的图像。

无需注册任务定义的新修订版。

作为旁注,需要小心处理latest 标记。在这种情况下,它似乎可以解决,但在许多其他情况下,它很容易出错:Ref1, Ref2

【讨论】:

以上是关于“最新”标签在 ECS 任务定义和从 ECR 中提取的容器实例中如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

新 ECS 任务定义的 CI/CD

将新映像推送到 ECR 存储库时如何自动部署到 ECS Fargate

AWS ECS:在 ECR 中强制重新部署新的最新映像

ECS Fargate 计划任务无法连接到 ECR

如何在 ECR 源管道中向 CodeDeploy 提供 AppSpec 和任务定义

ECS如何使用最新镜像