Docker 通过watchtower对registry私有库的容器的自动更新
小白防忘。首先得准备好两个虚拟机(我自己用的是Ubuntu镜像,并且两台虚拟机能够ping通,不能通信就不能进行镜像的拉取之类的操作了),方便实现更新registry仓库以及通过watchtower实现容器的自动更新(后面会有解释为什么使用两台虚拟机)。registry和watchtower可以在任意一个准备的虚拟机上运行。以下所有命令都是使用root账户进行操作。1.配置registry自己的私
小白防忘.
首先得准备好两个虚拟机,我自己用的是Ubuntu镜像,并且两台虚拟机能够ping通,不能通信就不能进行镜像的拉取之类的操作了,后面会有解释为什么使用两台虚拟机。registry和watchtower可以在任意一个准备的虚拟机上运行,示例使用的所有命令都是通过root账户进行操作。
1.配置registry
registry私有库为了安全考虑是需要实现登录认证的,我自己用的是一种最简单的方式——通过htpasswd实现登录认证。
registry:2.7.0以下版本
如果使用的registry镜像在2.7.0以下可以直接使用下面的命令生成htpasswd文件(registry:2版本的镜像不能用下面的方法)
docker run --entrypoint htpasswd registry:2.7.0 -Bbn username password > /root/registry/auth/passwd
以下参数均可自定义:
username:登录的用户名
password:登录的密码
/root/registry/auth/:生成文件的路径
passwd:生成的文件名
registry:2.7.0以上版本或者registry:2
因为docker考虑了进程安全问题,所以在registry:2.7.0以上版本不能使用上面的命令直接生成htpasswd。所以需要下载一个apache2用来生成登录所需要的htpasswd。
apt-get install apache2
#安装完成之后再执行下面的命令,参数和上面提供的参数使用方式相同
htpasswd -Bbn username password > /root/registry/auth/passwd
做完准备工作,就先把registry容器跑起来。
docker run -dp 5000:5000 \
--restart=always --name registry \
-v /root/registry/data:/var/lib/registry \
-v /root/registry/auth:/auth \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM=Registry_Realm \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/passwd \
registry:2
直接在浏览器上访问 运行registry容器的虚拟机的ip:5000/v2,在浏览器上能进行登录就表示配置成功了,下图为登录成功后的显示结果。
别高兴太早,在虚拟机上使用docker login ip:5000,不出意外的会报错。需要修改docker的配置文件解决问题。
vi /etc/docker/daemon.json
#在打开的文件中添加(没有就自己创建)
{
#ip为运行registry容器的服务器的ip地址
"insecure-registries": ["http://ip:5000"]
}
#保存之后重启docker即可生效
systemctl restart docker
#重启docker之后执行
docker login ip:5000 #根据提示输入之前设置的用户名和密码即可。
登录成功后会自动生成/root/.docker/config.json文件,该文件里就是registry的认证信息,等会配置watchtower的时候会用到。
2.配置watchtower
watchtower的运行机制
因为watchtower的工作机制是定时的扫描一遍所有正在运行的Docker容器的镜像是否被更改,如果watchtower检测到容器的镜像发生了变化,就会将仓库中的镜像拉倒本地,然后将与之对应的容器关闭,最后用容器最初部署时使用的配置信息重新启动容器,从而实现容器的自动更新。
至少需要两台虚拟机的原因
watchtower容器需要和自己的项目容器放在同一个虚拟机内,这样watchtower才能检测到自己部署的项目容器的镜像是否被更新了。又因为自己的项目容器会一直运行,所以是做不到在项目容器运行的虚拟机上直接用docker build;docker rmi;docker tag;docker push;命令更新私有库上的项目镜像的。因为不能删除正在运行中的容器的镜像,所以就不能用docker tag命令将新版本的镜像命名为已经存在的同名同版本号的镜像,也就无法实现对registry的更新了。所以需要一台虚拟机执行docker build;docker rmi;docker tag;docker push;命令,以实现对registry的更新;另一台虚拟机运行watchtower和自己的项目容器,至于registry容器运行在那一台虚拟机里都可以。
搞清楚上面两点,直接下来只需要docker run watchtower就行了,直接上命令吧。
docker run -d --registry=always --name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \ #监视所有在docker中运行的容器
#config.json为登录私有库的认证信息,我用的是root账户,所以使用/root/目录,根据自己的账号改变
-v /root/.docker/config.json:/config.json \
containrrr/watchtower \
-i 10 -c # -i 10 表示每隔10s扫描一次 -c 表示清除所有镜像
其他配置可以参考watchtower官网。
3.实际的更新流程
docker ps 查看正在运行中的容器
主要查看项目容器的镜像名称:ip:5000/watch:v1.0
然后在另一台虚拟机里进行更新操作
docker build -t index:v3 -f htmlfile . #构建新版本的镜像
docker rmi ip:5000/watch:v1.0 #删除之前的老版镜像
docker tag index:v3 ip:5000/watch:v1.0 #创建新版的镜像
docker push ip:5000/watch:v1.0 #对registry私有库里的镜像更新
#特别注意push到私有库的镜像名称必须和运行的项目容器的镜像名称相同,不然watchtower会判定项目容器的镜像没有更新。
最后在运行项目容器的虚拟机里执行docker logs就能看到watchtower已经完成了对容器的更新操作了。
欢迎评论区讨论其他写法,不积跬步无以至千里。
更多推荐
所有评论(0)