簡體   English   中英

Docker Swarm 服務 - 強制更新已經在運行的最新鏡像

[英]Docker Swarm Service - force update of latest image already running

環境

  • 碼頭工人 1.12
  • 集中在 Ubuntu 16.04

如果服務更新未更改任何參數但 docker hub 映像已更新,是否有辦法強制對已運行的 docker swarm 服務進行滾動更新?

示例:我部署了服務:

docker service create --replicas 1 --name servicename --publish 80:80 username/imagename:latest

我的構建過程已經更新了 docker hub 上的最新鏡像,現在我想再次拉取最新鏡像。

我試過運行:

docker service update --image username/imagename:latest servicename

當我遵循這個過程時,docker 不會拉取最新的,我想它假設因為我想要最新的並且 docker 已經拉了一個圖像:最新的那么沒有什么可做的。

我唯一的解決方法是刪除服務 servicename 並重新部署。

僅供參考:

Docker 1.13 為service update添加了一個--force標志:

--force :即使不需要更改也強制更新

像這樣使用它:

docker service update --force service_name

Docker 不會自動從 DockerHub(或私有注冊表)為您在本地已有的 image:tag 執行拉取操作。

如果您在docker service update之前執行了手動拉取,或者在本地刪除了圖像,它會。

您還可以鏈接命令:

docker pull image:tag && docker service update --image username/imagename:latest servicename

您可以通過數字標記您的圖像並使用更新的標簽來避免這種情況。 username/imagename:1.1.0

您可以使用圖像 ID 而不是username/imagename:latest像這樣:

docker service update --image \
$(docker inspect --type image --format '{{.Id}}' username/imagename:latest) \
servicename

但在這種情況下,您的所有節點都必須在服務更新之前提取此映像。 否則,容器將僅在存在具有此類 ID 的圖像的節點上更新。 幸運的是,沒有這個鏡像的節點會停止它們的容器,所以如果某些節點無法拉取新版本的鏡像,也沒什么不好。

更新:或者您可以使用圖像摘要如下:

docker service update --image \
$(docker inspect --type image --format '{{index .RepoDigests 0}}' username/imagename:latest) \
servicename

docker inspect --type image --format '{{index .RepoDigests 0}}' IMAGE返回圖像摘要,其中包括由 registry v2 生成的圖像的唯一哈希。 因此,必須從注冊表中提取圖像,否則摘要將不可用。

使用摘要允許您不在所有節點上提取圖像(具有指定摘要的圖像將自動從必要節點上的注冊表中提取)。 但是在服務更新之前,您必須在管理器節點上提取一次新版本的圖像。

順便說一句,從 Docker 1.13 開始,最后一種方式將是默認的

如果你想更新 docker 服務鏡像,你可以簡單地做docker service update --image myimage:tag servicename 例如docker service update --image traefik:1.7.5 traefik_proxy同樣通過不使用myimage:latest標簽,它確保您不會無意中更新到最新更新的主要/次要版本而不是補丁版本。

參考: https : //github.com/moby/moby/issues/30951#issuecomment-279479589

我做的是

  1. 先拉圖
  2. 使用新的時間戳標簽運行更新命令

docker service update --container-label-add last_deployed=$(date -u +%Y-%m-%dT%H:%M:%S) service_name_or_id

我是在 2020 年寫的,我希望這個腳本能幫助那些想要一種干凈的方式在堆棧上拉取和重新啟動容器而無需每次都在新標簽上發布新圖像的人!

#!/bin/bash -e
if [ $# -lt 1 ]
then
  echo "this command needs the name of the container and the branch you want to use"
  echo "Syntax: ./update.sh <microservice> <version>"
  echo "Syntax: ./update.sh mymicroservice develop"
  exit 1
fi
declare -r STACK_NAME="mystack" # this should be generated or asked to user
declare -r REPO="192.168.1.100" # this should be generated or asked to user

echo "Pull the image ${REPO}/${1}:${2}"
# Pull latest image on the swarm master
docker pull ${REPO}/${1}:${2}
# Get the ID of that image
declare -r imageSha256=`docker image inspect --format '{{ .Id }}' ${REPO}/${1}:${2}`
declare -r image="${REPO}/${1}@${imageSha256}"

# Update the server and the image used
docker service update --image ${image} ${STACK_NAME}_${1}
echo "Update succeeded !"

根據https://github.com/moby/moby/issues/34153

在更新需要憑據來拉取鏡像的服務時,您需要傳遞 --with-registry-auth。 為服務拉取的圖像采用與常規 docker pull 不同的路徑,因為實際拉取是在部署實例的 swarm 中的每個節點上執行的。 要拉取鏡像,swarm 集群需要存儲憑據(以便憑據可以傳遞給它執行拉取的節點)。

即使在這種情況下“節點”是您的本地節點,swarm 也采用相同的方法(否則它只能在本地節點上拉取圖像,而不能在任何其他節點上拉取圖像)。

設置 --with-registry-auth 選項會將您本地存儲的憑據傳遞給守護程序,並將它們存儲在 raft 存儲中。 之后,解析圖像摘要(使用這些憑據),並將圖像拉到調度任務的節點上(再次使用存儲在服務中的憑據)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM