背景

homelab 里不少服务钉在某个镜像 tag 上,上游发了新版本不会自动跟着走。以前靠偶尔看 GitHub Release,或者写脚本去打 releases/latest。后者对把每个版本都标成 pre-release 的项目几乎没用——接口长期停在旧版,等于没监控。

现在改成在 K8s 集群里跑 Diun(Docker Image Update Notifier):盯 registry 里的镜像 tag,出现匹配规则的新稳定版就推 Telegram。它不负责滚动升级,只负责通知。它在服务清单里的位置见 Homelab Services;硬件与集群拓扑见 Homelab 拓扑。

它盯的是 registry,不是正在跑的容器

Diun 用 file provider 读一份 watch 列表,直接问 registry「这个仓库现在有哪些 tag」,不扫描集群里的 Pod。所以:

  • 可以盯 homelab 里跑着的容器(例如 Vaultwarden)
  • 也可以盯并不在集群里跑的软件:只要上游会在打 release 时构建官方镜像,tag 与版本号一一对应,就可以把镜像当发版探针

后者用来补 GitHub releases/latest 的坑。有些项目几乎每个 release 都标 pre-release,那个接口会一直停在旧稳定版;镜像 tag 没有这层过滤。

homelab 部署

跑在独立 namespace diun,由 Argo CD 管(w10n-config 里的 infra/homelab/k8s/diun/)。要点:

项 现网
镜像 Nexus 代理后的 crazymax/diun
检查频率 每 6 小时;启动时再跑一次
通知 Telegram Bot;凭据在 notifications namespace,由 Reflector 反射进 diun
状态 Longhorn PVC 记已经见过的 tag,重启不会把历史版本再推一遍
UI 没有。纯后台 + 推送

首次检查关掉通知(DIUN_WATCH_FIRSTCHECKNOTIF=false),只建基线。之后才对真正的新 tag 发消息。

当前监控目标

多数目标只匹配 x.y.z 稳定 tag(include_tags: ^\d+\.\d+\.\d+$)。Prometheus 现网是 vX.Y.Z-distroless,所以那一条用对应的 distroless 规则。按 semver 排序,每个仓库最多看最近 15 个 tag。

镜像 实际对应什么 收到通知后
docker.io/vaultwarden/server AWS EC2 上的自建密码服务 改 Ansible 里的镜像 tag,再跑对应 playbook
docker.io/grafana/grafana 集群 Grafana(kube-prometheus-stack 默认镜像) bump Helm chart 版本,镜像随 chart 走
quay.io/prometheus/prometheus 集群 Prometheus(chart 用 distroless 变体) 同上,bump Helm chart
上游官方容器镜像(二进制部署的服务) 墙外 VPS 上用 Ansible 装的二进制,本身不跑容器;官方镜像 tag 与 GitHub release 一一对应,含 pre-release 改 inventory 里的版本号,再走既有升级流程

Vaultwarden 这一条的写法大致如下:

- name: docker.io/vaultwarden/server:latest
  watch_repo: true
  notify_on:
    - new
  sort_tags: semver
  max_tags: 15
  include_tags:
    - ^\d+\.\d+\.\d+$

改 watch 列表之后要让 Deployment 重新读 ConfigMap(kubectl -n diun rollout restart deploy/diun)。

和 Watchtower / 自动升级的区别

Watchtower、Keel 一类工具会在发现新镜像后直接改运行中的容器。Diun 只发通知,升级仍是手动、按各服务自己的流程走。homelab 里版本是钉死的(GitOps 或 Ansible inventory),自动拉 latest 不符合现有发布方式。