Featured image of post Watchtower 容器自动更新:定时检测、选择性更新与远程主机

Watchtower 容器自动更新:定时检测、选择性更新与远程主机

containrrr/watchtower 容器化部署、cleanup 旧镜像、按容器名/标签选择性更新、监控频率 schedule/interval、远程 Docker Host、Harbor 私有仓库认证

容器跑起来之后,“镜像更新"是个让人纠结的事——不更新吧,安全漏洞累积;更新吧,业务容器一重启服务就断。Watchtower 解决了"无痛更新”:定时拉取镜像、检测到更新就停掉旧容器、用新镜像起一个新容器、把端口/网络/卷全部恢复。这篇文章讲清楚 Watchtower 容器化部署、清理旧镜像、选择性更新、监控频率、远程主机对接。

阅读对象:在多容器环境里希望"装完不用管"、或者要给客户做无人值守部署的运维同学
覆盖范围:Watchtower 容器化部署、cleanup 选项、容器名过滤、标签选择、interval/schedule 频率、远程 Docker Host、Harbor 私有仓库凭据

一、为什么是 Watchtower

容器自动更新工具里,Watchtower 是事实标准:

  • 零侵入:跑一个 sidecar 容器,监控 Docker daemon,不动现有 docker-compose
  • 可选择性:可以只更新部分容器(按名字/标签过滤)
  • 可灰度--run-once 手动触发、--label-enable 白名单模式
  • 可远程:能监控远程 Docker Host 上的容器
  • 开源活跃:containrrr 组织维护,GitHub 1w+ stars

When to use:业务容器是"无状态"、“镜像无破坏性变更”、“出问题可快速回滚"的场景,Watchtower 几乎是首选。如果是数据库这种"有状态升级"或"必须停机升级"的场景,Watchtower 不合适。

二、容器化部署

2.1 最简启动

1
2
3
4
5
6
docker run -d \
  --name watchtower \
  --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower \
  -c

挂载 /var/run/docker.sock:Watchtower 通过 Docker API 拉镜像、停旧容器、起新容器,没有这个挂载就什么也做不了-c (--cleanup):每次更新后清理旧镜像,否则磁盘会被旧镜像塞满。

2.2 选择性自动更新(按容器名)

1
2
3
4
5
6
7
docker run -d \
  --name watchtower \
  --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower \
  -c \
  nginx redis

nginx redis被监控的容器名(不是镜像名)。docker ps 看到的 NAMES 列填进去即可。Watchtower 会监控这俩容器,其它不管。

2.3 配置文件方式(容器多了之后)

容器列表写在文件里:

1
2
3
4
cat ~/.watchtower.list
aria2-pro
unlockmusic
mtg
1
2
3
4
5
6
7
docker run -d \
  --name watchtower \
  --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower \
  -c \
  $(cat ~/.watchtower.list)

注意空格$(cat ...) 会把换行替换成空格,正好是 Watchtower 的命令行格式。

三、排除与白名单

3.1 排除特定容器(label 模式)

给容器加 label com.centurylinklabs.watchtower.enable=false

1
2
3
4
5
6
7
8
docker run -d \
  --name openwrt-mini \
  --restart always \
  --network openwrt \
  --privileged \
  --label com.centurylinklabs.watchtower.enable=false \
  p3terx/openwrt-mini \
  /sbin/init

Watchtower 看到这个 label 就跳过

3.2 白名单模式(只更新带 label 的)

启动时加 --label-enable(简写 -e):

1
2
3
4
5
6
docker run -d \
  --name watchtower \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower -c \
  --label-enable

关键:要把 --label-enable 加在 Watchtower 自己的启动参数上,被监控容器加 label com.centurylinklabs.watchtower.enable=true,Watchtower 更新这种容器。

四、更新频率控制

4.1 默认行为

Watchtower 默认每 5 分钟轮询一次。

4.2 interval(秒)

1
2
3
4
5
6
docker run -d \
  --name watchtower \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower -c \
  --interval 3600

--interval 3600:每 3600 秒(1 小时)检查一次。

4.3 schedule(6 字段 Cron)

1
2
3
4
5
6
docker run -d \
  --name watchtower \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower -c \
  --schedule "0 0 2 * * *"

6 字段 Cron:第一位是秒(0 0 2 * * * 表示"每天 02:00:00”),与 Linux crontab 的 5 字段格式不一样推荐0 0 3 * * *(凌晨 3 点)——业务低峰期,重启容器对用户影响最小。

4.4 手动更新(–run-once)

Watchtower 默认常驻后台;--run-once 让它跑一次就退出,适合“白天手动触发更新”:

1
2
3
docker run --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower -cR aria2-pro

-R = --run-once:跑一次就退出。容器被 docker run --rm 自动清理。

五、远程 Docker Host

Watchtower 能监控远程主机上的容器(前提:远程 Docker daemon 监听 TCP 端口,且能认证):

1
2
3
4
5
6
7
8
9
docker run -d \
  --name watchtower \
  --restart always \
  -e REPO_USER=admin \
  -e REPO_PASS={{REDACTED}} \
  -e DOCKER_HOST="tcp://{{REMOTE_DOCKER_HOST}}:2375" \
  containrrr/watchtower \
  -c \
  base

远程 Docker 监听 TCP 2375(明文) 有安全风险,生产环境必须用 TLS(2376)。配置方式:DOCKER_HOST=tcp://host:2376 + -e DOCKER_TLS_VERIFY=1 + -v /path/to/certs:/certs

DOCKER_HOST 与 -v 冲突:Watchtower 用 -e DOCKER_HOST 时不需要挂载 /var/run/docker.sock,否则两个 Docker daemon 都会跑(本地和远程同时管),按需取舍。

六、私有仓库(Harbor / 自建 registry)

如果镜像在私有仓库,Watchtower 拉镜像需要凭据:

1
2
3
4
5
6
7
8
9
docker run -d \
  --name watchtower \
  --restart always \
  -e REPO_USER=admin \
  -e REPO_PASS={{REDACTED}} \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower \
  -c \
  base

base 是镜像名(不是容器名):Harbor 仓库里项目叫 base,Watchtower 就会拉 {{REGISTRY}}/base/* 下的所有镜像。

七、踩坑清单

  1. 磁盘吃光——忘了 -c/--cleanup,旧镜像累积几个 G
  2. 数据库被自动升级——Postgres / MySQL 这种"有状态"服务,Watchtower 升级可能直接破坏数据,强烈建议加 label 排除
  3. 配置/数据卷没挂出来——Watchtower 升级只会保留"挂载进容器的卷",容器内 /etc/nginx/conf.d 这种直接放容器内的文件会丢
  4. Watchtower 把自己升级挂了——--restart=always 不一定能救回,因为新版可能改了 entrypoint;建议固定 tag 不追 latest
  5. 频繁重启影响业务——--interval 设太短(如 60s),凌晨业务被意外重启。生产用 --schedule 凌晨低峰
  6. 远程 Docker Host 防火墙——DOCKER_HOST=tcp://... 远程 daemon 端口(2375/2376)没在远程主机防火墙开放

八、参考资料

  • Watchtower 官方仓库:https://github.com/containrrr/watchtower
  • 文档:https://containrrr.dev/watchtower/
  • Docker daemon TLS 配置:https://docs.docker.com/engine/remote-access/

下一步

使用 Hugo 构建
主题 StackJimmy 设计