K8s 证书避坑指南:如何安全地测试并申请 Let's Encrypt 泛域名证书
在 Kubernetes 集群中,使用 cert-manager 配合 Let’s Encrypt 自动签发免费的 HTTPS 泛域名证书,是目前的业界标配。
但是,无数新手在第一次配置时都会踩进一个**“死亡陷阱”**:Let’s Encrypt 对正式接口有极其严格的速率限制。如果你因为 DNS 配置填错、Token 权限不对等原因导致申请失败超过 5 次,你的域名将被拉黑封锁 1 个小时;如果反复重试,甚至会被封锁 7 天!
为了避免“坠机”,最标准、最专业的做法是:先用测试服 (Staging) 跑通流程,再切换到正式服 (Production)。
今天这篇文章,就带你完整走一遍这个“演习到转正”的标准全流程。
🚦 第一阶段:使用 Staging (测试服) 进行实战演习
Section titled “🚦 第一阶段:使用 Staging (测试服) 进行实战演习”Let’s Encrypt 提供了一个专门的 Staging 测试环境,它的请求限制极其宽松,你可以随便报错、随便重试,绝对不会封锁你的域名。
我们的第一步,就是写一份指向测试服的图纸。
1. 编写 Staging 配置文件
Section titled “1. 编写 Staging 配置文件”创建一个名为 cluster-issuer-and-cert.yaml 的文件。请注意看代码中的注释,有 3 个地方是测试服独有的:
# 1. 声明一个测试服的“发证机关” (ClusterIssuer)apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencrypt-staging # 🧪 标志 1:命名为 stagingspec: acme: # 🧪 标志 2:必须使用 Staging 的 API 地址! server: [https://acme-staging-v02.api.letsencrypt.org/directory](https://acme-staging-v02.api.letsencrypt.org/directory) email: your-email@example.com # ⚠️ 替换为你的真实邮箱,用于接收过期通知 privateKeySecretRef: # 🧪 标志 3:测试服专用的账号私钥名称,千万别和正式服重名 name: letsencrypt-staging-account-key solvers: - dns01: cloudflare: # 这里以 Cloudflare DNS 验证为例 apiTokenSecretRef: name: cloudflare-api-token key: api-token---# 2. 提交一份“证书申请单” (Certificate)apiVersion: cert-manager.io/v1kind: Certificatemetadata: name: my-website-tls namespace: default # ⚠️ 替换为你网关 (如 Traefik/Nginx) 所在的命名空间spec: secretName: my-website-tls # 最终生成的证书 Secret 名称 issuerRef: # 🧪 标志 4:指定上面那个测试服发证机关来处理这张单子 name: letsencrypt-staging kind: ClusterIssuer commonName: "*.example.com" # ⚠️ 替换为你的域名 dnsNames: - "example.com" - "*.example.com"2. 部署并验证演习成果
Section titled “2. 部署并验证演习成果”将上面的配置应用到集群中:
kubectl apply -f cluster-issuer-and-cert.yaml接下来,我们不需要去浏览器里看,直接在终端里盯着它的状态:
# 监控证书状态 (将 default 换成你自己的 namespace)kubectl get certificate my-website-tls -n default -w-
成功标志:当你看到
READY这一列从False变成了True,恭喜你,演习大获全胜!这证明你的 DNS Token 和底层网络链路已经 100% 跑通。 -
终极查验 (彻底放心):如果你想彻底确认这张申请下来的证书到底是谁发的,建议使用以下兼容性最强的“临时文件法”进行查验:
Terminal window # 1. 提取 Secret 中的证书内容,解码后存入临时文件kubectl get secret my-website-tls -n default -o jsonpath='{.data.tls\.crt}' | base64 -d > /tmp/cert_verify.crt# 2. 调用 openssl 物理查验该文件并过滤颁发者openssl x509 -in /tmp/cert_verify.crt -text -noout | grep "Issuer"# 3. 查完即焚,删除临时文件rm /tmp/cert_verify.crt预计输出结果:
- 演习环境 (Staging):输出包含
Issuer: ..., CN=(STAGING) Artificial Apricot R3。这证明 Let’s Encrypt 已经认可了你的域名所有权,并把测试用的“假证书”发给你了。
- 正式环境 (Production):输出包含
Issuer: ..., CN=R3(没有 STAGING 字样)。这说明你的正式绿锁已经下发。
- 演习环境 (Staging):输出包含
🚀 第二阶段:销毁假证,正式转正 (Production)
Section titled “🚀 第二阶段:销毁假证,正式转正 (Production)”既然流程已经跑通,我们就可以放心大胆地去正式服领真绿锁了。
1. 修改图纸,切换为正式环境
Section titled “1. 修改图纸,切换为正式环境”回到你刚才的 cluster-issuer-and-cert.yaml 文件,把那 4 个测试服的标志全部改掉:
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencrypt-prod # ✅ 1. 改为 prodspec: acme: # ✅ 2. 换成 Let's Encrypt 的正式服 API server: [https://acme-v02.api.letsencrypt.org/directory](https://acme-v02.api.letsencrypt.org/directory) email: your-email@example.com privateKeySecretRef: name: letsencrypt-prod-account-key # ✅ 3. 换个正式的工作证名称 solvers: - dns01: cloudflare: apiTokenSecretRef: name: cloudflare-api-token key: api-token---apiVersion: cert-manager.io/v1kind: Certificatemetadata: name: my-website-tls namespace: defaultspec: secretName: my-website-tls issuerRef: name: letsencrypt-prod # ✅ 4. 向正式服机关提交申请 kind: ClusterIssuer commonName: "*.example.com" dnsNames: - "example.com" - "*.example.com"再次应用配置:
kubectl apply -f cluster-issuer-and-cert.yaml2. 【核心必做】物理销毁旧证书!
Section titled “2. 【核心必做】物理销毁旧证书!”这是无数人翻车的一步! 虽然你修改了申请单,但 Kubernetes 发现你的系统里已经存在一个叫 my-website-tls 的 Secret(刚才测试服发的那个),并且还没过期,它很可能不会去触发重新签发。
你必须手动把那个假证书“撕毁”,倒逼 cert-manager 重新去正式服申请:
# 删除测试服生成的假证书 Secretkubectl delete secret my-website-tls -n default3. 见证真锁降临
Section titled “3. 见证真锁降临”删掉假证书后,cert-manager 会立刻反应过来:“哎呀,证书没了,而且现在的发证机关变成了 Prod,我得赶紧去申请一张新的!”
再次查看状态:
kubectl get certificate my-website-tls -n default -w由于之前的网络链路已经验证过完全没问题,这次的申请会极快通过。当状态再次变为 READY: True 时,刷新你的浏览器页面(建议使用无痕模式清除缓存)。
那把坚不可摧、受全球所有设备信任的 HTTPS 绿色小锁,就已经完美挂在你的域名上了!
💡 总结: 无论是个人折腾还是企业级部署,先用 Staging 测试,再切 Prod 签发,最后 delete secret 强制重签,这套“三步走”战略能帮你避开 99% 的证书签发雷区。