1. 项目概述:为什么Kubernetes需要cert-manager?
在云原生环境中,TLS证书管理一直是个令人头疼的问题。传统方式中,我们需要手动申请证书、定期更新、部署到各个服务,这个过程不仅繁琐还容易出错。cert-manager作为Kubernetes原生的证书管理工具,彻底改变了这种状况。
我最早接触cert-manager是在一个金融级微服务项目中,当时我们有200+服务需要配置HTTPS,手动管理几乎不可能。cert-manager通过自定义资源定义(CRD)将证书生命周期管理融入Kubernetes工作流,实现了:
- 自动从Let's Encrypt等CA机构申请证书
- 定时检查证书有效期并自动续期
- 将证书自动注入Ingress或Pod
- 支持多种签发器(Issuer)类型
目前最新稳定版本是v1.13.x,支持Kubernetes 1.22+版本。与早期版本相比,v1.x系列在ACME协议实现、证书轮换机制等方面有重大改进。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 安装cert-manager的三种姿势
2.1 标准Helm安装(生产推荐)
这是最主流的安装方式,适合大多数场景。我习惯先添加jetstack的helm仓库:
bash复制helm repo add jetstack https://charts.jetstack.io
helm repo update
安装时有几个关键参数需要注意:
bash复制helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.13.3 \
--set installCRDs=true \
--set prometheus.enabled=true \ # 开启监控
--set webhook.timeoutSeconds=30 # 调大超时避免网络问题
重要提示:生产环境务必指定版本号,避免自动升级到不兼容版本。我曾因为没指定版本导致半夜证书服务中断。
2.2 kubectl直接安装(快速测试)
对于测试环境,可以使用静态manifest快速部署:
bash复制kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.yaml
这种方式虽然简单,但缺少定制化选项,也不方便后续升级管理。
2.3 Operator模式安装(高级用法)
对于需要深度集成的环境,cert-manager也提供了Operator安装方式。这种方式下,cert-manager会以Operator模式运行,提供更精细的生命周期管理。不过复杂度较高,一般只有特殊需求时才使用。
3. 核心签发器(Issuer)详解
3.1 Issuer与ClusterIssuer的区别
这是新手最容易混淆的概念。简单来说:
- Issuer:命名空间级别,只能在当前namespace使用
- ClusterIssuer:集群级别,所有namespace共享
我通常的实践是:
- 开发环境用Issuer,隔离各团队证书
- 生产环境用ClusterIssuer,统一管理
3.2 ACME签发器配置(Let's Encrypt)
这是最常用的签发器类型,配置示例:
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
关键参数说明:
- server:ACME服务器地址,生产用v02,测试用staging
- email:证书过期提醒邮件
- solvers:验证方式,http01最常用
踩坑记录:Let's Encrypt有严格的速率限制,测试时务必先用staging环境(acme-staging-v02),否则很容易触发限制导致生产证书申请失败。
3.3 CA签发器配置(内部PKI)
对于内部服务,我们可能希望使用私有CA签发证书:
yaml复制apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: my-ca-issuer
namespace: my-app
spec:
ca:
secretName: my-ca-key-pair
需要提前将CA证书和私钥存入Secret:
bash复制kubectl create secret tls my-ca-key-pair \
--cert=ca.crt \
--key=ca.key \
--namespace=my-app
3.4 Vault签发器配置(企业级)
大型企业通常已有Vault作为证书中心,cert-manager可以直接集成:
yaml复制apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: vault-issuer
spec:
vault:
server: https://vault.example.com
path: pki/sign/my-role
auth:
tokenSecretRef:
name: vault-token
key: token
4. 证书申请与管理实战
4.1 创建第一个证书
有了签发器后,申请证书就很简单了:
yaml复制apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: my-app-cert
spec:
secretName: my-app-tls
dnsNames:
- myapp.example.com
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
证书状态可以通过describe查看:
bash复制kubectl describe certificate my-app-cert
4.2 证书自动注入Ingress
更常见的用法是让Ingress自动申请证书:
yaml复制apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- myapp.example.com
secretName: my-app-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80
4.3 证书轮换与更新
cert-manager会自动管理证书生命周期:
- 默认在证书到期前30天开始续期
- 可以通过spec.renewBefore调整
- 续期失败会不断重试
查看证书事件可以了解状态:
bash复制kubectl get events --field-selector involvedObject.kind=Certificate
5. 生产环境最佳实践
5.1 监控与告警配置
证书失效是P0级故障,必须配置监控:
yaml复制apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
labels:
app: cert-manager
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: critical
annotations:
summary: Certificate expiring soon (instance {{ $labels.instance }})
description: "Certificate {{ $labels.name }} will expire in 7 days"
5.2 资源配额与调优
高负载环境下需要调整资源限制:
yaml复制# values.yaml
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
特别是webhook组件,在证书申请高峰时可能CPU飙升。
5.3 多集群部署策略
对于多集群环境,我推荐:
- 每个集群独立部署cert-manager
- 使用相同的ClusterIssuer配置
- 通过GitOps工具保持配置同步
避免使用一个cert-manager服务多个集群,这会引入单点故障。
6. 故障排查手册
6.1 常见错误代码
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| ErrRegisterACMEAccount | 网络问题或ACME服务不可用 | 检查网络连接,确认ACME服务地址正确 |
| CertificateNotReady | DNS配置错误或验证失败 | 检查DNS记录,确认域名解析正确 |
| InvalidOrder | 证书配置错误 | 检查dnsNames和issuerRef配置 |
6.2 诊断工具与命令
查看cert-manager日志:
bash复制kubectl logs -l app.kubernetes.io/instance=cert-manager -n cert-manager
检查CRD状态:
bash复制kubectl get issuers,certificates,certificaterequests -A
6.3 ACME验证问题排查
http01验证失败时:
- 确认Ingress Controller工作正常
- 检查临时创建的Challenge Pod日志
- 验证域名解析是否正确
dns01验证失败时:
- 检查DNS提供商API权限
- 确认DNS记录已正确添加
- 检查secret中的API凭证
7. 高级功能探索
7.1 证书外部管理
通过External Issuer可以集成外部证书管理系统:
yaml复制apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: external-issuer
spec:
external:
url: https://external-ca.example.com
requestTimeout: 30s
auth:
secretRef:
name: external-ca-credentials
7.2 证书模板
使用CertificateTemplate实现统一证书策略:
yaml复制apiVersion: cert-manager.io/v1
kind: CertificateTemplate
metadata:
name: company-template
spec:
usages:
- server auth
- client auth
privateKey:
algorithm: RSA
size: 4096
7.3 证书导出与备份
虽然cert-manager会自动管理证书,但关键证书还是应该备份:
bash复制kubectl get secret my-app-tls -o jsonpath='{.data.tls\.crt}' | base64 -d > backup.crt
kubectl get secret my-app-tls -o jsonpath='{.data.tls\.key}' | base64 -d > backup.key
在实际项目中,cert-manager已经成为我们Kubernetes集群中不可或缺的基础组件。从最初的简单证书管理,到现在支持各种复杂的证书场景,它的功能越来越强大。对于刚开始使用的团队,建议从小规模测试开始,逐步熟悉各种签发器和证书策略,最终实现全自动化的证书生命周期管理。
