HTTPS 与 cert-manager 证书自动化
手工维护证书(openssl 生成、kubectl create secret tls)不适合多域名长期运维。cert-manager 通过与 Let's Encrypt 集成,实现证书的自动申请、自动续期、自动注入 Secret。
工作原理
Ingress(带注解) → cert-manager → Let's Encrypt 校验域名 → 签发证书 → K8s Secret → Traefik 加载证书默认 90 天有效,cert-manager 会在到期前 30 天自动续期,全程无需人工干预。
安装 cert-manager
使用官方静态清单安装:
bash
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.21.1/cert-manager.yaml
# 等待就绪
kubectl -n cert-manager rollout status deploy/cert-manager --timeout=120s
kubectl -n cert-manager get pods国内服务器注意
cert-manager 镜像来自 quay.io,国内拉取较慢(首次约 30~40 秒)。首次签发时 solver 镜像也是从 quay.io 拉取,可能出现短暂 503,属正常现象。
创建 ClusterIssuer
ClusterIssuer 是集群级别的证书签发方配置:
yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com # 到期提醒邮箱
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
ingressClassName: traefik校验方式选型
| 方式 | 原理 | 适用 |
|---|---|---|
| HTTP-01 | 访问 http://域名/.well-known/acme-challenge/<token> | 公网可访问 80 端口 |
| DNS-01 | 写入 TXT 记录 _acme-challenge.域名 | 泛域名、80 端口不可达 |
本环境使用 HTTP-01(域名已解析到公网 IP,80 由 Traefik 提供)。
给 Ingress 配置 TLS
只需在 Ingress 上加两处:
yaml
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod # ① 触发签发
spec:
tls:
- hosts:
- docs.ljdou.cn
secretName: docs-ljdou-cn-tls # ② 证书存放的 Secretcert-manager 会创建 docs-ljdou-cn-tls Secret(类型 kubernetes.io/tls),Traefik 自动加载。
状态查看
bash
# 查看证书状态(READY=True 即签发成功)
kubectl get certificate -A
# 查看签发订单与挑战过程
kubectl get order,challenge -A
# 查看证书详情
kubectl describe certificate docs-ljdou-cn-tls -n default常见问题
1. 国内服务器 HTTP-01 失败
报错特征:
During secondary validation: ...: Timeout during connect (likely firewall problem)原因:Let's Encrypt 会从多个网络视角校验(多视角校验),部分海外校验点到国内服务器的 80 端口连通性不稳定。
应对:
- 优先改用 DNS-01(无入站连接要求,最稳)
- 或重试(cert-manager 会自动退避重试)
- 首次失败常因 solver 镜像未拉取完成,重试即可
2. 证书一直 False
bash
kubectl describe challenge <name> -n <ns> # 查看具体失败原因
kubectl logs -n cert-manager deploy/cert-manager --tail=503. 多个域名合并一张证书
同一 Ingress 的 tls.hosts 写多个域名即可(SAN 证书):
yaml
tls:
- hosts:
- ljdou.cn
- www.ljdou.cn
secretName: ljdou-cn-tls