主题
RKE2 集群证书过期巡检 + 飞书卡片通知
每天定时检查 RKE2 集群全部证书(apiserver / etcd / kubelet / CA 等)的过期时间, 按剩余天数分级(⛔ 已过期 / 🔴 ≤30 天 / 🟡 ≤60 天 / 🟢 正常),通过飞书自定义机器人 Webhook 推送交互式卡片,卡片头部颜色随最严重级别变化(红/橙/绿)。
原理
CronJob (每天 08:00, Asia/Shanghai)
└─ 调度到 control-plane 节点 (nodeSelector + tolerations)
└─ hostPath 只读挂载 /var/lib/rancher/rke2
└─ openssl 计算每张 .crt/.pem 剩余天数 → curl POST 飞书卡片- 扫描范围:
server/tls(含etcd/、kube-controller-manager/、kube-scheduler/子目录) 和agent(含kubelet/pki)下所有.crt/.pem - 发送失败或飞书返回非
code:0时脚本以非零码退出,Job 标记为 Failed 便于发现 - RKE2 证书剩余 90 天内重启
rke2-server即自动轮换,也可手动执行rke2 certificate rotate
文件清单
| 文件 | 说明 |
|---|---|
rke2-cert-expiry-check-cronjob.yaml | K8s 部署清单(ConfigMap 脚本 + CronJob),已按 sza122 集群适配 |
check-certs.sh | 宿主机单机版脚本,无需容器,可直接在 server 节点运行或加入 crontab 作备份巡检 |
export-image.sh | 离线镜像导入导出工具(跨环境离线分发时使用) |
部署(sza122 集群 / 有 Harbor 的环境)
bash
kubectl apply -f rke2-cert-expiry-check-cronjob.yaml
# 立即手动触发一次验证(无需等定时)
kubectl -n kube-system create job cert-check-test --from=cronjob/rke2-cert-expiry-check
kubectl -n kube-system logs job/cert-check-test # 查看飞书响应
kubectl -n kube-system delete job cert-check-test # 清理飞书返回 {"StatusCode":0,...} 即成功。当前集群已部署(kube-system 命名空间, CronJob rke2-cert-expiry-check),实测扫描 26 张证书,最早到期 2027-07-30。
离线部署(无 Harbor / 全新离线环境)
在已有镜像的 RKE2 节点上导出镜像(582MiB):
bash./export-image.sh export # 生成 rancher-agent-v2.14.3.tar拷贝
rancher-agent-v2.14.3.tar与rke2-cert-expiry-check-cronjob.yaml到目标环境, 在目标集群任一 server 节点导入:bash./export-image.sh import注意:镜像只需存在于 Job 实际调度到的节点;多 control-plane 节点建议每台都导入, 或将 CronJob 用
nodeSelector固定到已导入的节点(如kubernetes.io/hostname: sza122020.local)。如目标环境使用不同镜像地址,修改清单中
image:字段后kubectl apply。不依赖 K8s 的兜底方案:直接把
check-certs.sh拷到 server 节点加入 crontab (Rocky 9 自带 bash/openssl/curl/coreutils,开箱即用):cron0 8 * * * WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/xxx" /root/check-certs.sh
参数配置(CronJob env)
| 变量 | 默认值 | 说明 |
|---|---|---|
WEBHOOK_URL | 飞书机器人 webhook | 告警群机器人的完整 hook 地址 |
CLUSTER_NAME | sza122-cluster | 卡片中显示的集群名 |
WARN_DAYS | 30 | 红色告警阈值(黄色为其 2 倍) |
检查时间修改 schedule(cron 表达式)与 timeZone。
环境适配记录(重要)
- 镜像选择:目标环境无外网(docker.io 不可达),使用集群已缓存的
192.168.122.156:30000/rancher/rancher-agent:v2.14.3,其内置 openssl 3.2 / curl / GNU coreutils,无需apk/apt安装任何依赖。 - TLS 拦截:出口到
open.feishu.cn存在自签名 TLS 检查代理,curl 必须加-k, 否则报SSL certificate problem: self-signed certificate in certificate chain。 若目标环境出口无拦截,可去掉-k。 - webhook 保密:当前 webhook 明文写在 env 中,如需保密可改为 Secret 引用。
常见问题
| 现象 | 排查 |
|---|---|
Pod CreateContainerError/镜像拉取失败 | 镜像是否已缓存或已导入该节点:ctr -a /run/k3s/containerd/containerd.sock -n k8s.io images ls |
| Job Failed,日志显示未发现证书 | hostPath /var/lib/rancher/rke2 是否存在于调度节点(agent-only 节点无 server/tls) |
| 飞书响应 SSL 错误 | 出口 TLS 拦截,确认 curl 带 -k |
飞书响应 code 非 0 | webhook 地址错误/机器人被移除/触发关键词或频率限制 |
| 想换更轻的镜像 | 任意含 openssl+curl+GNU date 的镜像均可(如自行构建的 alpine 工具镜像),脚本无其他依赖 |