繁体   English   中英

如何使用特定标签版本更新 ecs 服务?

[英]How to update an ecs service with specific tag version?

我正在尝试更新一个 ecs fargate 服务,该服务具有多个与服务任务定义使用的给定 ecr 容器图像关联的标签。

ecr中的容器镜像有如下标签:2023.3.0-latest、test

如您所见,这仅包含一个版本标签,然后是一个环境标签,在本例中就是“测试”。

在任务定义中,我使用标准格式传入了 ecr url:<baseurl>/<ecrrepo>:test

我想要做的是当与任务定义关联的特定服务有更新时,使用与特定版本和环境关联的特定图像。

例如,我如何使用另一个图像的特定任务定义更新服务,该图像也用于测试但版本不同?

到目前为止,我已经运行了 Jenkins 个作业,这些作业已经完成了过滤版本和更新与特定环境关联的服务的所有工作。 我的工作如下:

  1. 创建repo,将指定版本的容器上传到ecr,打上指定版本关联的tag,将容器镜像推送到ecr。

  2. 使用指定环境重新标记图像,在本例中为“测试”

第三步是如何使用与版本和环境关联的特定容器映像更新任务。

所以说,例如,我强制更新与“测试”标签关联的任务,我如何首先过滤“测试”标签的特定版本,以便 ecs 知道要使用哪个版本的“测试”?

一些重要的事情:

  • 任务定义是唯一可以定义任务中容器应使用的图像的地方。
  • 任务定义修订是不可变的——它们在创建后无法更改。
  • 您的任务定义通常应该仅指定具有永不更改的唯一图像标签的图像 否则,您的任务将具有不确定和不一致的行为。
  • 要更新服务任务使用的图像,您必须创建新的任务定义修订并更新服务以使用新修订。
  • 您可能只想在更新服务之后而不是之前移动映像上的环境标记。

您的基本步骤应如下所示:

  1. 构建镜像并使用唯一标签将镜像推送到 ECR
  2. 创建一个新的任务定义修订,为适当的容器指定唯一标签
  3. 更新服务以使用新版本
  4. (可选)等待服务稳定
  5. 成功更新后,重新标记环境

执行所有这些操作的脚本可能如下所示:

# 1. Build the image(s) and push the image(s) to ECR with a unique tag
unique_tag="$BUILD_TAG" # or whatever you want that is unique
new_image="<ecr repo>:$unique_tag"
service_arn="<service ARN>"

env_name="test" # or whatever
cache_image="<ecr repo>:$env_name"

# leverage docker cache from the currently active image in this environment, if it exists
docker pull $cache_image || echo "no cache"
docker build --cache-from "$cache_image" -t <ECR repo>:$unique_tag .
docer push <ECR repo>:$unique-tag .

# 2. Create a new task definition revision

# here we assume you don't store the task definition JSON in the repo, which means we need to get it from API call
# by default, this gets the latest ACTIVE revision, which is usually what you want.
existing_taskdef="$(aws ecs describe-task-definition --task-definition=<your-taskdef-family-name>)"

# create new taskdef using jq to replace the image key in the first container (we assume only one container `.containerDefinitions[0]` is defined in this example)
# describe-task-definition returns some keys that can't be used with register-task-defintiion, so we delete those, too
new_task_definition="$(jq --arg IMAGE "$new_image" '.taskDefinition | .containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities)' <<< "$existing_taskdef")"

# register the new revision
new_revision_arn="$(aws ecs register-task-definition --cli-input-json "$new_taskdefinition" --output text --query 'taskDefinition.taskDefinitionArn')"


# 3. Update the service to use the new revision

aws ecs update-service --service="$service_arn" --task-definition="$new_revision_arn"

# 4. wait for deployment stabilization (omitted for brevity)

# 5 retag the environment

# in subsequent workflows, the newly built image will be used for the cache
docker tag "$new_image" "<ecr repo>:${env_name}"
docker push "<ecr repo>:${env_name}"

找到了一个可行的解决方案。 同样的用例是,如果你在 ecr 中有多个版本的图像,你想通过 ecs fargate 部署,并且你不想为每个创建单独的任务定义,但将图像设置为“测试”,并且只是每次更新版本。

与某些观点相反,这是可以做到的。 当您使用“测试”(即 2023.1.0 或 2023.2.0)重新标记您想要的版本时,ecr 将该标记更新为指定的版本并从指定的先前版本中删除该标记。 换句话说,如果您刷新 ecr,您将看到“测试”标签或您指定的任何其他标签切换到该版本(注意:为了简单起见,我已经对下面的版本进行了硬编码)。

1. Push the tagged image to ECR

docker load < containername:2023.1.0-latest.tar.gz

SERVICE_NAME="ecsServiceName"
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
ECR_URL="$ACCOUNT_ID.dkr.ecr.<region>.amazonaws.com/SERVICE_NAME:2023.1.0-latest"
    
aws ecr create-repository --repository-name ${SERVICE_NAME:?} --region <region> || true

docker tag containername:2023.1.0-latest $ECR_URL
 
$(aws ecr get-login --region <region> --no-include-email --registry-ids $ACCOUNT_ID)
 
docker push $ECR_URL
    
2. Retag the image with env tag

MY_MANIFEST=$(aws ecr batch-get-image --repository-name $SERVICE_NAME --image-ids imageTag=2023.1.0-latest --region <region> --query images[].imageManifest --output text)

aws ecr put-image --repository-name $SERVICE_NAME --image-tag test --image-manifest "$MY_MANIFEST" --region <region>

3. Update the service with the task definition

aws ecs update-service --cluster ecsClusterName --service $SERVICE_NAME --task-definition ecsTaskDefinitionName --force-new-deployment --region <region>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM