You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Docker Swarm服务扩容与新节点镜像拉取异常问题求助

Docker Swarm Scale 后新节点无法拉取私有镜像的解决方案

这确实是 Docker Swarm 20.10.x 版本里一个容易踩的坑,我来给你拆解问题原因和对应的解决办法:

问题根源

当你用 docker service create --with-registry-auth 创建服务时,Swarm 会将主节点的私有仓库认证信息(来自 ~/.docker/config.json)嵌入到服务的配置规格(Spec)中,并同步给当时集群内的所有节点。但当你把服务缩容到 0 后,Swarm 不会主动保留这份认证信息的全局同步状态;后续新节点加入后,执行 scale 只是单纯调度新任务,不会触发认证信息的重新分发——这就导致新节点没有拉取私有镜像的权限,报错“no such image”。而重新创建服务时,--with-registry-auth 会再次触发认证信息的全节点同步,所以新节点又能正常拉取。

解决办法

方法1:扩容前更新服务并重新传递认证信息

在执行 scale 操作前,先通过 service update 重新推送认证信息到所有节点(包括新加入的节点):

# 重新同步认证信息到集群所有节点
docker service update --with-registry-auth myserv
# 再执行扩容
docker service scale myserv=<目标副本数>

这个操作会让 Swarm 重新将主节点的仓库认证信息分发到集群内所有节点,后续调度任务时新节点就能用这份认证拉取镜像了。

方法2:给所有节点预配置私有仓库认证

如果你的集群节点增减比较频繁,可以直接在每个节点(包括后续要加入的节点)预先配置 AWS ECR 的认证:

# 在目标节点执行AWS ECR登录命令
aws ecr get-login-password --region <你的AWS区域> | docker login --username AWS --password-stdin <你的ECR仓库地址>

或者把主节点的 ~/.docker/config.json 文件复制到其他节点的相同路径,注意设置正确权限:

# 从主节点复制到新节点(假设主节点IP为192.168.1.100)
scp ~/.docker/config.json user@192.168.1.100:~/.docker/
# 在新节点设置权限
chmod 600 ~/.docker/config.json

这样所有节点都有本地的认证配置,不管服务怎么缩放,都能直接拉取私有镜像。

方法3:用Swarm Secret存储认证信息(推荐长期方案)

把 Docker 认证配置做成 Swarm Secret,让服务调度时自动挂载到节点,从根源上解决认证同步问题:

  1. 基于主节点的 config.json 创建 Secret:
docker secret create regcred ~/.docker/config.json
  1. 创建服务时挂载这个 Secret 到容器的 Docker 配置路径:
docker service create \
  --name myserv \
  --secret source=regcred,target=/root/.docker/config.json \
  <你的ECR镜像地址>

后续不管新节点什么时候加入,只要服务调度任务到该节点,都会自动挂载这份认证配置,不需要手动同步认证信息,缩放操作自然能正常工作。

验证方式

你可以执行以下命令检查服务是否包含认证信息:

docker service inspect myserv --format '{{.Spec.TaskTemplate.ContainerSpec.RegistryAuth}}'

如果输出非空字符串,说明认证信息已经正确嵌入服务配置中。

内容的提问来源于stack exchange,提问作者Lessfoe

火山引擎 最新活动