1. 项目概述:当Kubernetes遇上HTTPS加密
在Kubernetes集群中管理TLS证书就像给每个集装箱贴上防伪标签——传统手动操作既繁琐又容易出错。cert-manager的出现彻底改变了这种局面,它如同集群中的"证书管家",能够自动化完成从申请、续期到分发的全生命周期管理。我在生产环境中部署过数十次cert-manager,最深刻的体会是:它把原本需要人工干预数小时的工作压缩到了几分钟内自动完成。
以最常见的Let's Encrypt证书为例,传统方式需要手动配置ACME客户端、处理DNS验证、定期续期。而在Kubernetes中,通过cert-manager只需声明几个CRD资源,配合Ingress的几行注解,就能实现全自动的证书管理。这种声明式的工作流正是Kubernetes生态的精髓所在。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心组件解析:cert-manager架构揭秘
2.1 cert-manager的三层架构设计
cert-manager的核心架构分为控制面、签发机构和存储后端三层。控制面包含我们部署的Controller Pod,负责监听Certificate等CRD资源的变化;签发机构可以是Let's Encrypt这样的公共CA,也可以是私有CA(如Vault);存储后端则通常使用Kubernetes Secret,但也支持对接外部系统如Google Cloud CAS。
bash复制# 典型安装命令(使用helm)
helm upgrade --install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.13.1 \
--set installCRDs=true
注意:生产环境建议始终指定版本号,避免自动升级带来意外变更。我曾因未固定版本导致ACMEv1到ACMEv2的升级问题,造成证书签发失败。
2.2 关键CRD资源解析
- Issuer/ClusterIssuer:定义证书签发机构
- Certificate:声明需要的证书属性
- CertificateRequest:证书申请中间件(通常自动创建)
- Order:ACME专用资源(记录订单状态)
其中ClusterIssuer与Issuer的区别就像Kubernetes中的ClusterRole和Role——前者是集群级别的,后者限定在特定Namespace。在多租户环境中需要特别注意权限隔离。
3. 实战演练:从申请到部署全流程
3.1 配置ACME签发机构
以Let's Encrypt为例,首先需要创建ClusterIssuer。以下是生产环境推荐配置:
yaml复制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
privateKeySecretRef:
name: letsencrypt-prod-account-key
solvers:
- http01:
ingress:
class: nginx
selector:
dnsNames:
- "*.example.com"
这里有几个关键点:
- 生产环境务必使用acme-v02端点(ACMEv2协议)
- privateKeySecretRef保存ACME账户密钥,丢失会导致无法管理已有证书
- http01验证适用于80端口开放的场景,否则需要用dns01验证
3.2 创建证书申请
证书申请通过Certificate资源实现。以下示例展示了泛域名证书的申请:
yaml复制apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard-example-com
namespace: default
spec:
secretName: wildcard-example-com-tls
duration: 2160h # 90天
renewBefore: 720h # 到期前30天续期
dnsNames:
- "*.example.com"
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
实测经验:duration设置超过90天会被Let's Encrypt自动调整为90天。我曾试图设置365天证书,结果发现cert-manager会自动调整为最大允许值。
4. Ingress集成:注解的魔法
4.1 基础注解配置
将证书自动应用到Ingress是最常见的用法。通过以下注解即可实现:
yaml复制apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- app.example.com
secretName: app-example-com-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
这个配置会触发cert-manager:
- 自动创建同名的Certificate资源
- 通过ACME完成域名验证
- 将最终证书存入指定Secret
4.2 高级注解技巧
- 强制HTTPS重定向:
yaml复制nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
- 自定义证书有效期:
yaml复制cert-manager.io/duration: 2160h
- 使用特定DNS解析器(适用于私有DNS):
yaml复制acme.cert-manager.io/dns01-recursive-nameservers: "10.0.0.1:53"
我在金融项目中遇到过私有DNS解析问题,通过设置递归nameserver解决了验证失败的问题。
5. 生产环境避坑指南
5.1 常见问题排查
-
证书状态卡在Pending:
- 检查Issuer状态:
kubectl describe issuer - 查看事件日志:
kubectl get events --sort-by=.metadata.creationTimestamp - 常见原因:ACME账户配额耗尽、DNS解析失败
- 检查Issuer状态:
-
证书续期失败:
- 检查renewBefore时间是否合理
- 验证私钥是否有效:
kubectl get secret <name> -o jsonpath='{.data.tls\.key}' | base64 -d
-
HTTPS连接不安全:
- 确认Secret已生成:
kubectl get secret - 检查Ingress控制器日志
- 确认Secret已生成:
5.2 性能优化建议
- 为cert-manager设置资源限制:
yaml复制resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
- 在高负载集群中启用Leader Election:
yaml复制leaderElection:
enabled: true
- 定期清理旧的CertificateRequest资源:
bash复制kubectl delete certificaterequest --field-selector status.conditions.status=False
6. 安全加固与监控
6.1 安全最佳实践
-
私钥保护:
- 启用privateKeyRotationPolicy:
rotationPolicy: Always - 限制Secret访问权限:使用RBAC和NetworkPolicy
- 启用privateKeyRotationPolicy:
-
审计日志:
yaml复制--v=2 # 控制器日志级别
--audit-log-path=/var/log/cert-manager/audit.log
- 网络隔离:
- 限制cert-manager Pod的网络出口
- 只允许访问必要的ACME端点
6.2 监控方案
建议配置以下监控指标:
- 证书过期时间:
certmanager_certificate_expiration_timestamp - 签发失败次数:
certmanager_certificate_ready_status{condition="False"} - ACME验证时长:
certmanager_acme_client_request_duration_seconds
Prometheus示例告警规则:
yaml复制- alert: CertificateExpiringSoon
expr: (certmanager_certificate_expiration_timestamp - time()) / 86400 < 30
for: 5m
labels:
severity: warning
annotations:
summary: "Certificate will expire soon (instance {{ $labels.instance }})"
7. 进阶场景探索
7.1 多集群证书管理
通过External Issuer可以实现跨集群证书管理。例如使用Vault作为中央CA:
yaml复制apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: vault-issuer
spec:
vault:
server: https://vault.example.com
path: pki/sign/example-com
auth:
tokenSecretRef:
name: vault-token
key: token
7.2 证书透明度日志
大型组织应该监控证书透明度日志(CT Log)。cert-manager支持自动提交:
yaml复制apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ct-enabled
spec:
usages:
- digital signature
- key encipherment
- server auth
isCA: false
ctStrictPolicy: true
7.3 密钥算法选择
对于需要更高安全性的场景,可以指定密钥算法:
yaml复制spec:
privateKey:
algorithm: ECDSA
size: 256
实测数据显示,ECDSA相比RSA在握手阶段能减少约40%的CPU开销。
