Home

cert-manager 详解:自动管理 Kubernetes 证书

cert-manager 是 Kubernetes 中最常见的证书自动化组件之一。它的价值不在于“能申请证书”这么简单,而在于把证书的申请、续期、下发和更新,全部纳入集群声明式管理流程里,减少手工维护 TLS 的成本和风险。

cert-manager 解决了什么问题

如果没有 cert-manager,证书管理通常会变成一堆重复劳动:

  • 手动申请证书
  • 手动更新 Secret
  • 手动替换 Ingress 或服务引用
  • 记着证书什么时候过期

cert-manager 的目标,就是把这些事情自动化。

核心作用

功能说明
自动申请证书从 Let’s Encrypt、私有 CA 等自动获取 TLS 证书
自动续订证书在证书过期前自动续订,减少中断风险
证书注入自动把证书写入 Secret,供 Ingress 或应用使用
多 CA 支持支持 Let’s Encrypt、Vault、Venafi、自签 CA 等
域名验证支持 HTTP-01 和 DNS-01 挑战
多环境适配既能用于公网证书,也能用于内部证书体系

核心概念

cert-manager 主要通过一组 CRD 资源来工作:

资源作用
Issuer / ClusterIssuer定义证书颁发机构
Certificate描述需要申请的证书
CertificateRequest一次具体的证书申请请求
OrderACME 模式下的订单对象
ChallengeACME 域名验证挑战

理解这几个对象的关系后,后面的排障和使用就会清晰很多。

安装 cert-manager

使用 Helm 安装

helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.14.4 \
  --set installCRDs=true

这里 installCRDs=true 很关键,否则证书相关自定义资源不会被一起安装。

验证安装结果

kubectl get pods -n cert-manager

预期会看到 cert-managercainjectorwebhook 相关 Pod 正常运行。

典型场景一:自动申请 Let’s Encrypt 证书

这是最常见的公网场景。

1. 创建 ClusterIssuer

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    email: admin@example.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-prod-account-key
    solvers:
    - http01:
        ingress:
          class: nginx

这里用的是生产环境地址,如果只是测试,可以换成 Let’s Encrypt 的 staging 地址,避免触发正式环境限流。

2. 创建 Certificate

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-com
  namespace: default
spec:
  secretName: example-com-tls
  duration: 90d
  renewBefore: 15d
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - example.com
    - www.example.com

这一步定义的是“我要什么证书”,而不是“怎么签发”。

3. 在 Ingress 中引用证书

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  tls:
    - hosts:
        - example.com
      secretName: example-com-tls
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80

当证书签发成功后,cert-manager 会把结果写进 example-com-tls 这个 Secret,Ingress 再去引用它。

4. 查看签发结果

kubectl get certificate example-com -o wide
kubectl describe secret example-com-tls

典型场景二:使用私有 CA

在内网环境里,很多时候不会直接使用 Let’s Encrypt,而是接入内部 CA,例如 Vault。

1. 配置 Vault Issuer

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: vault-issuer
  namespace: default
spec:
  vault:
    server: https://vault.example.com
    path: pki/sign/example-com
    auth:
      tokenSecretRef:
        name: vault-token
        key: token

2. 申请内部证书

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: internal-cert
  namespace: default
spec:
  secretName: internal-tls
  issuerRef:
    name: vault-issuer
    kind: Issuer
  dnsNames:
    - internal.example.com

这个场景特别适合内部服务、Service Mesh、Webhook 或内部 API 网关证书管理。

cert-manager 怎么续期

证书并不是签下来就完事了。cert-manager 会持续监控证书有效期,并在 renewBefore 指定的时间之前触发续期。

它大致会做这些事:

  1. 监控证书有效期
  2. 到期前自动发起续订
  3. 更新对应的 Secret
  4. 让引用这个 Secret 的组件使用到新证书

这也是它比“手动上传一张证书”更有价值的地方。

总结

cert-manager 的真正意义,不是把证书申请这一步自动化,而是把“证书生命周期”放回 Kubernetes 的声明式管理模型里。只要理解这三层关系,基本就抓住重点了:

  • Issuer 决定“由谁签”
  • Certificate 决定“我要什么”
  • Secret 承载“最终结果给谁用”

在生产环境里,一旦证书开始多起来,越早把它交给 cert-manager 管,后面越省事。

Kubernetes 存储 Linux