繁体   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