最近不断收到 Let’s Encrypt 的提醒邮件,提示某个域名的证书将在 10 天内过期。这个证书由 Kubernetes 集群里的 cert-manager 管理,按理说应该在到期前自动续签。

我先查看了对应的 Certificate。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ kc get certificates -n my-namespace subdomain -o yaml
apiVersion: cert-manager.io/v1
kind: Certificate
[...]
spec:
...
status:
conditions:
- lastTransitionTime: ...
message: Certificate is up to date and has not expired
observedGeneration: 1
reason: Ready
status: "True"
type: Ready
...

从状态看,证书仍然是 Ready,提示也写着证书尚未过期。这个结果容易让人以为 cert-manager 一切正常,但它只能说明当前证书仍然可用,不能据此排除续签异常。

先排除早期版本问题

cert-manager 的早期版本确实出现过自动续签问题。相关问题影响了 v1.4.0,修复版本为 v1.4.4、v1.5.4 和 v1.6.0。如果仍在使用这些早期版本,升级到对应的修复版本即可。

我的 cert-manager 已经是 v1.15.1,不属于这次旧问题的影响范围。原来的安装命令如下。

1
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.1/cert-manager.yaml

继续沿着版本检查,问题才逐渐清楚。

核对 Kubernetes 兼容范围

当前集群已经升级到 Kubernetes 1.35。我对照了 cert-manager 官方的版本支持表,v1.15 的兼容范围不包含 Kubernetes 1.35。

官方表中,cert-manager 1.19 支持 Kubernetes 1.31 到 1.35。因此,这个环境至少需要把 cert-manager 升级到 1.19。我选择了 1.19 分支的补丁版本 v1.19.6。

升级命令如下。

1
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.19.6/cert-manager.yaml

升级完成后,cert-manager 自动发起了新的签发流程,证书也成功更新。Let’s Encrypt 的到期提醒终于有了明确的处理结果。

这次排查最容易被 Ready=True 误导。证书当前可用,并不等于运行中的 cert-manager 版本仍受当前 Kubernetes 版本支持。遇到证书停止自动续签时,除了检查 Certificate、CertificateRequest、Order 和 Challenge,也应该核对 cert-manager 与 Kubernetes 的版本兼容关系。

参考资料