Watchtower:自动更新 Docker 镜像与容器
前言
在服务器上部署 Docker 容器有一种在手机上装 APP 的感觉,但 Docker 容器并不会像手机 APP 那样会自动更新,而如果我们需要更新容器一般需要以下三个步骤:
停止并删除容器:
docker rm -f <CONTAINER>
更新镜像:
docker pull <IMAGE>
启动容器:
docker run <ARG> ... <IMAGE>
如果部署了大量的容器需要更新使用这种传统的方式工作量是巨大的。
Watchtower 是一个可以实现自动化更新 Docker 基础镜像与容器的实用工具。它监视正在运行的容器以及相关的镜像,当检测到 registry 中的镜像与本地的镜像有差异时,它会拉取最新镜像并使用最初部署时相同的参数重新启动相应的容器,一切好像什么都没发生过,就像更新手机上的 APP 一样。
快速开始
Watchtower 本身被打包为 Docker 镜像,因此可以像运行任何其他容器一样运行它:
XML/HTML代码
- docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower
然后所有容器都会自动更新,也包括 Watchtower 本身。
自动清除旧镜像
官方给出的默认启动命令在长期使用后会堆积非常多的标签为 none 的旧镜像,如果放任不管会占用大量的磁盘空间。要避免这种情况可以加入 --cleanup 选项,这样每次更新都会把旧的镜像清理掉。
XML/HTML代码
- docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --cleanup
选择性自动更新
某些容器可能需要稳定的运行,经常更新或重启可能会造成一些问题,这时我们可以使用一些参数来选择与控制容器的更新。
假设我们需要更新容器名称为 nginx、redis 这两个容器,我们可以把容器名称追加到启动命令的最后面,就像下面这个例子:
XML/HTML代码
- docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --cleanup \ nginx redis
如果需要排除某些容器,可以将 com.centurylinklabs.watchtower.enable 设置为 false。即在 docker run 命令中加入 --label=com.centurylinklabs.watchtower.enable=false 参数。在下面这个例子中,除了容器名称为 nginx、redis 以外的容器都会自动更新:
XML/HTML代码
- docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ --label=com.centurylinklabs.watchtower.enable=false \ containrrr/watchtower \ --cleanup \ nginx redis
默认情况下 Watchtower 每5分钟会轮询一次,如果你觉得这个频率太高了可以使用如下选项来控制更新的频率:
--interval,-i:设置间隔更新时间。默认 300 秒( 5 分钟)
--schedule,-s:设置定时更新时间。格式为 Cron 表达式,比如--schedule "0 0 4 * * *"
比如每小时检查一次更新:
XML/HTML代码
- docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --cleanup \ -i 3600
XML/HTML代码
- docker run -d \ --name watchtower \ --restart unless-stopped \ -e TZ=Asia/Shanghai \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --cleanup \ -s "0 0 1 * * *"
前面的使用方式都是让 Watchtower 以 detached(后台)模式在运行并自动更新容器,而 Watchtower 也支持以foreground(前台)模式来使用,即运行一次退出并删掉容器,来实现手动更新容器。这对于偶尔更新一次那些在自动更新中被排除的容器非常有用。
对于 foreground 模式,需要加上 --run-once 这个专用的选项。下面的例子 Docker 会运行一次 Watchtower并检查容器名称为 nginx 容器的基础镜像更新,最后删掉本次运行创建的 Watchtower 容器。
XML/HTML代码
- docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --cleanup \ --run-once \ nginx
XML/HTML代码
- docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ --label=com.centurylinklabs.watchtower.enable=false \ containrrr/watchtower \ --cleanup \ --run-once \ nginx
官方文档:Watchtower Document