手动申请证书、手动配置、到期前手动续期——这件事在只有一两个域名时还能忍,一旦有 beta 和 prod 两套环境就很容易忘。cert-manager 把整个流程变成了一段声明式配置。
集群里跑的是 cert-manager v1.21.2。
ClusterIssuer 与两个环境
Issuer 是命名空间级的,ClusterIssuer 是集群级的。因为 beta 和 prod 都要用,建了 ClusterIssuer。
关键是建两个:staging 和 prod。它们的区别不在安全性,而在速率限制:
- staging:Let’s Encrypt 的测试环境,签发频率限制很宽松,但证书不被浏览器信任(会报红色警告)。用来验证流程通不通。
- prod:正式环境,证书被信任,但对”同一域名在一段时间内的签发次数”有严格限制(目前是每周 50 张)。
正确顺序是:先用 staging 把流程跑通,确认 HTTP-01 校验能通过,再切到 prod。反过来做的话,很容易因为配置错误反复重试,几小时内就把一周的额度用光,然后只能干等。
HTTP-01 校验为什么失败
cert-manager 会在你的站点上临时放一个校验文件,然后让 Let’s Encrypt 从公网访问 http://<你的域名>/.well-known/acme-challenge/<token> 来确认这个域名确实归你。
失败通常就三个原因:
- 80 端口不通:云厂商安全组、服务器防火墙没放行。HTTP-01 只能用 80 端口,没有例外。
- 被强制跳转 HTTPS:如果 Ingress 配了”所有 HTTP 请求 301 到 HTTPS”,校验请求会被跳走,Let’s Encrypt 拿不到文件内容。需要给 challenge 路径单独放行。
- DNS 还没生效:域名解析没指向这台服务器,或者刚改过解析还在传播中。
排查命令固定三板斧:
kubectl get certificate -A
kubectl describe certificate <name> -n <ns>
kubectl get challenge -A # 看 challenge 的状态和原因
describe certificate 输出的 Events 基本会直接告诉你卡在哪一步。
证书复用
同一台主机下的所有 Ingress 共用一张证书。我的 WordPress、/qrcode、/tools 都在 www.mazter.cn 下,所以只有一张 wp-tls。
新增子路径应用时不需要动证书配置,这一点在 Traefik 那篇里也提过——共用域名的隐性收益。
续期
Let’s Encrypt 证书有效期 90 天。cert-manager 会在到期前自动续期,默认是到期前 30 天开始尝试。你什么都不用做。
值得做的一件事是加个监控:证书状态不是 Ready 时能收到通知。它平时不出问题,但一旦出问题(比如 DNS 改了、80 端口被封),表现是”整站突然打不开”,而且往往在你最不想处理事情的时候发生。