簡體   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