ingress-nginx证书管理:Let's Encrypt自动化
在Kubernetes集群中管理TLS证书一直是运维人员的痛点。手动创建、更新和轮换证书不仅繁琐,还容易出错。本文将详细介绍如何使用ingress-nginx结合cert-manager实现Let's Encrypt证书的自动化管理,让你的HTTPS服务永不过期。
为什么需要自动化证书管理?
传统证书管理面临的主要挑战:
| 挑战 | 传统方案 | 自动化方案 |
|---|---|---|
| 证书申请 | 手动操作 | 自动申请 |
| 证书更新 | 手动续期 | 自动续期 |
| 证书部署 | 手动更新Secret | 自动同步 |
| 错误处理 | 人工监控 | 自动重试 |
架构概览
环境准备
1. 安装ingress-nginx
首先确保已安装ingress-nginx控制器:
# 使用Helm安装
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
# 或者使用manifest文件
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
2. 安装cert-manager
cert-manager是证书管理的核心组件:
# 添加jetstack仓库
helm repo add jetstack https://charts.jetstack.io
helm repo update
# 安装cert-manager
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.8.0 \
--set installCRDs=true
配置Let's Encrypt签发器
创建ClusterIssuer
ClusterIssuer是集群级别的证书签发器配置:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: admin@example.com
accountKeySecretRef:
name: letsencrypt-staging-account-key
solvers:
- http01:
ingress:
class: nginx
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
accountKeySecretRef:
name: letsencrypt-prod-account-key
solvers:
- http01:
ingress:
class: nginx
自动化证书申请配置
Ingress资源配置
在Ingress资源中添加cert-manager注解,实现自动化证书管理:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
# 指定cert-manager签发器
cert-manager.io/cluster-issuer: "letsencrypt-prod"
# 其他ingress-nginx注解
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-example-com-tls # cert-manager将自动创建此Secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
证书状态监控
查看证书状态
# 查看Certificate资源状态
kubectl get certificates
# 查看详细证书信息
kubectl describe certificate app-example-com-tls
# 查看CertificateRequest状态
kubectl get certificaterequests
# 查看Order状态(ACME订单)
kubectl get orders
常见状态说明
| 状态 | 含义 | 处理建议 |
|---|---|---|
| Ready | 证书就绪 | 正常状态 |
| Pending | 等待处理 | 检查网络或配置 |
| Failed | 申请失败 | 查看事件日志 |
| Unknown | 状态未知 | 检查cert-manager状态 |
高级配置选项
自定义证书参数
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: my-app-certificate
spec:
secretName: my-app-tls-secret
duration: 2160h # 90天
renewBefore: 720h # 30天前开始续期
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: app.example.com
dnsNames:
- app.example.com
- www.example.com
usages:
- server auth
- client auth
多域名证书配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-domain-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- app1.example.com
- app2.example.com
- api.example.com
secretName: multi-domain-tls
rules:
- host: app1.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- host: app2.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
故障排除指南
常见问题及解决方案
-
证书申请失败
# 查看cert-manager日志 kubectl logs -n cert-manager deploy/cert-manager # 查看具体Order资源 kubectl describe order <order-name> -
HTTP-01挑战失败
- 检查ingress-nginx是否正常运行
- 验证域名解析是否正确
- 检查网络策略是否允许流量
-
证书未自动创建
# 检查ClusterIssuer状态 kubectl describe clusterissuer letsencrypt-prod # 检查RBAC权限 kubectl auth can-i create secrets --as=system:serviceaccount:cert-manager:cert-manager
监控和告警配置
建议配置监控告警,及时发现证书问题:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: cert-manager-alerts
spec:
groups:
- name: cert-manager
rules:
- alert: CertificateExpiringSoon
expr: certmanager_certificate_expiration_timestamp_seconds - time() < 86400 * 7
for: 5m
labels:
severity: warning
annotations:
summary: "证书即将过期"
description: "证书 {{ $labels.name }} 将在7天内过期"
- alert: CertificateRequestFailed
expr: rate(certmanager_certificate_request_errors_total[5m]) > 0
for: 2m
labels:
severity: critical
annotations:
summary: "证书申请失败"
description: "检测到证书申请失败"
最佳实践
-
分阶段部署
- 先在staging环境测试
- 验证通过后再切换到production环境
-
证书备份
# 备份证书Secret kubectl get secret app-example-com-tls -o yaml > certificate-backup.yaml -
定期审计
# 检查即将过期的证书 kubectl get certificates -o wide # 查看证书详细过期时间 kubectl get certificates -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.notAfter}{"\n"}{end}' -
资源清理
# 清理旧的CertificateRequest kubectl delete certificaterequests --field-selector status.conditions[0].status==True
总结
通过ingress-nginx与cert-manager的集成,我们实现了Let's Encrypt证书的全自动化管理。这种方案不仅减少了运维负担,还提高了系统的安全性和可靠性。关键优势包括:
- ✅ 自动证书申请和续期
- ✅ 无需人工干预
- ✅ 支持多域名和通配符证书
- ✅ 完善的监控和告警机制
- ✅ 符合安全最佳实践
现在,你的Kubernetes集群已经具备了企业级的证书管理能力,可以安心地部署生产环境的HTTPS服务了。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



