最近在部署service到swarm集群的时候,出现了下列的报错:
[root@nccztsjb-node-01 ~]# docker service create \ > --name=nginx \ > --publish published=8080,target=80 \ > 172.20.58.152/middleware/nginx:1.21.4 image 172.20.58.152/middleware/nginx:1.21.4 could not be accessed on a registry to record its digest. Each node will access 172.20.58.152/middleware/nginx:1.21.4 independently, possibly leading to different nodes running different versions of the image. hr3vb5wdzkzhewbc62f06nenr overall progress: 0 out of 1 tasks 1/1: No such image: 172.20.58.152/middleware/nginx:1.21.4
看到报错信息,才恍然大悟,原来,这个镜像是在私有的、内部搭建的仓库中的。
也就是说,拉取镜像是需要认证的,或者,在拉取镜像之前,需要登录仓库
解决的方法,也是非常的简单的
首先,登录到这个仓库中(在manager节点操作)
[root@nccztsjb-node-01 ~]# docker login 172.20.58.152 Username: admin Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded [root@nccztsjb-node-01 ~]#
然后,部署service的时候加上认证参数 --with-registry-auth (在manager节点)
docker service create \ --name=nginx \ --with-registry-auth \ --publish published=8080,target=80 \ 172.20.58.152/middleware/nginx:1.21.4
[root@nccztsjb-node-01 ~]# docker service create \ > --name=nginx \ > --with-registry-auth \ > --publish published=8080,target=80 \ > 172.20.58.152/middleware/nginx:1.21.4 qi8fxxrdrbxlidenqxyd7ywx4 overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged [root@nccztsjb-node-01 ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS qi8fxxrdrbxl nginx replicated 1/1 172.20.58.152/middleware/nginx:1.21.4 *:8080->80/tcp hz926ckhmkd9 redis replicated 1/1 172.20.58.152/middleware/redis:3.0.6 pzcsua3xuur9 test-commd replicated 1/1 172.20.58.152/baseimage/alpine:latest [root@nccztsjb-node-01 ~]# docker service ps nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS j0ltlwxwcsnw nginx.1 172.20.58.152/middleware/nginx:1.21.4 nccztsjb-node-04 Running Running 14 seconds ago [root@nccztsjb-node-01 ~]# [root@nccztsjb-node-01 ~]#
有没有发现,是在nccztsjb-node-01上,即manager节点上做的登录,但是,现在的task实际上运行nccztsjb-node-04这个节点上的。
也就是说,所有的集群中的节点,都是可以获取这个认证的信息的!
原理:会将manager节点本地客户端的登录tokenc传送到swarm集群中service运行的节点。使用这个token信息,节点可以登录到私有仓库,然后拉取镜像
所以,关键步骤:
- manger节点登录私有仓库(使用用户名和密码)
- 部署service指定认证参数--with-registry-auth