在这里插入图片描述

1. 引言:云原生时代的信任基石

在零信任(Zero Trust)安全模型和 HTTPS 全面普及的今天,TLS 证书的管理已成为基础设施运维中不可忽视的一环。手动申请、部署和轮换证书不仅效率低下,更是导致服务中断(因证书过期)的常见原因。

cert-manager 是 Kubernetes 生态中事实上的标准证书管理控制器。它不仅是一个从 Let’s Encrypt、HashiCorp Vault、Venafi 或私有 PKI 获取证书的工具,更是一套基于 CRD(自定义资源定义)的声明式证书自动化编排系统

本文将深入剖析 cert-manager 的工作原理,并展示其在复杂生产场景下的应用。


2. 核心架构与工作原理

cert-manager 遵循 Kubernetes 的控制器模式(Controller Pattern)。它引入了一组 CRD 来描述证书的生命周期。理解这些资源对象是掌握 cert-manager 的关键。

2.1 核心 CRD 资源关系图谱

  • Issuer / ClusterIssuer: 定义证书颁发机构(CA)。Issuer: 命名空间(Namespace)隔离,只能为同 namespace 下的资源签发。ClusterIssuer: 全局资源,可服务于所有 namespace。
  • Certificate: 定义用户期望的证书状态(域名、有效期、密钥算法等)。这是用户主要交互的资源。
  • CertificateRequest: 类似于传统的 CSR(证书签名请求)。cert-manager 根据 Certificate 自动生成此资源,向 Issuer 申请签名。
  • Order & Challenge (仅 ACME): 当使用 ACME 协议(如 Let’s Encrypt)时,cert-manager 会创建 Order 资源来追踪订单,并创建 Challenge 资源来处理域名所有权验证(HTTP-01 或 DNS-01)。
  • Secret: 最终存储 TLS 私钥和证书的 Kubernetes 原生资源,供 Ingress 或 Pod 挂载使用。

2.2 控制回路(Reconciliation Loop)

  1. 用户创建一个 Certificate 对象。
  2. cert-manager 控制器检测到新对象,验证其有效性。
  3. 控制器生成私钥(如果不存在)并创建 CertificateRequest。
  4. 根据指定的 Issuer 类型:如果是 CA/SelfSigned/Vault:直接签署并返回证书。如果是 ACME:触发 Order 和 Challenge 流程,完成域名验证后获取证书。
  5. 获取的证书被保存到 Kubernetes Secret 中。
  6. 控制器持续监控证书有效期,在临近过期(默认 30 天前)时自动触发更新流程。

3. 实战配置:ACME 协议与 Let’s Encrypt

这是最常用的场景,用于为公网服务提供免费、自动续期的可信证书。

3.1 HTTP-01 vs DNS-01:深度对比

在选择验证方式时,必须根据网络架构做出决策:

特性HTTP-01DNS-01
原理在特定路径放置文件,CA 通过 HTTP 访问验证在 DNS 区域添加 TXT 记录,CA 查询 DNS 验证
依赖需要 80 端口对外开放且指向集群需要 DNS 提供商的 API 访问权限
通配符证书不支持 (*.example.com)支持
内网环境仅适用于公网可达的服务适用于内网服务(只要公网 DNS 可解析)
适用场景简单 Web 应用,非通配符复杂架构、通配符、防火墙后的服务

3.2 实战:配置 ClusterIssuer (HTTP-01)

首先,通过 Helm 安装 cert-manager(略)。然后定义 ClusterIssuer:

code Yaml

downloadcontent_copy

expand_less

    apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # 生产环境 URL
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-account-key
    solvers:
    - http01:
        ingress:
          class: nginx # 指定处理验证请求的 Ingress Class
  

3.3 实战:配置 ClusterIssuer (DNS-01 with Cloudflare)

对于 DNS-01,需要配置 DNS 提供商的凭据(以 Cloudflare 为例):

  1. 创建 Secret 存储 API Token: code Bashdownloadcontent_copyexpand_less kubectl create secret generic cloudflare-api-token-secret \ --from-literal=api-token=<YOUR_CLOUDFLARE_API_TOKEN> \ -n cert-manager
  2. 定义 ClusterIssuer: code Yamldownloadcontent_copyexpand_less apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-dns-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: admin@example.com privateKeySecretRef: name: letsencrypt-dns-prod-key solvers: - dns01: cloudflare: email: admin@example.com apiTokenSecretRef: name: cloudflare-api-token-secret key: api-token

4. 应用集成:如何消费证书

配置好 Issuer 后,有两种主要方式将证书应用到工作负载中。

4.1 模式一:Ingress Shim(推荐,全自动化)

这是最优雅的方式。只需在 Ingress 资源中添加 Annotation,cert-manager 会监视 Ingress 资源,自动创建 Certificate 对象、申请证书并回填到 Secret。

code Yaml

downloadcontent_copy

expand_less

    apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    # 关键注解:指定使用哪个 ClusterIssuer
    cert-manager.io/cluster-issuer: "letsencrypt-prod" 
    # 可选:强制 HTTP 重定向到 HTTPS
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - app.example.com
    secretName: app-tls-secret # cert-manager 将自动创建此 Secret
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app
            port:
              number: 80
  

4.2 模式二:显式 Certificate 资源(高级场景)

如果你不使用 Ingress(例如使用 Gateway API,或者直接挂载证书到 Pod 进行 mTLS),或者需要更复杂的证书配置(如增加 SAN IP、自定义密钥算法),则需要显式定义 Certificate。

code Yaml

downloadcontent_copy

expand_less

    apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: internal-db-cert
  namespace: database
spec:
  secretName: db-tls-auth
  duration: 2160h # 90天
  renewBefore: 360h # 15天前续期
  commonName: db-service.database.svc
  isCA: false
  privateKey:
    algorithm: ECDSA
    size: 256
  usages:
    - server auth
    - client auth
  dnsNames:
    - db-service.database.svc.cluster.local
    - localhost
  issuerRef:
    name: internal-ca-issuer # 指向一个内部 CA Issuer
    kind: ClusterIssuer
  

5. 进阶场景:私有 PKI 与企业级应用

在企业内部,通常需要签发不受信任公网认可但企业内部受信任的证书(Intranet)。

5.1 使用 CA Issuer

最简单的方法是将现有的 CA 根证书和私钥导入 Kubernetes Secret,然后创建一个 CA Issuer。

code Yaml

downloadcontent_copy

expand_less

    # 1. 创建 Secret 包含 ca.crt 和 tls.key
# 2. 定义 Issuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: corporate-ca
spec:
  ca:
    secretName: corporate-root-ca-secret
  

这使得你可以像申请 Let’s Encrypt 证书一样,轻松地为内部微服务签发证书,实现全链路加密(End-to-End Encryption)。

5.2 集成 HashiCorp Vault

对于高安全性要求的环境,私钥不应存储在 Kubernetes Secret 中。cert-manager 可以作为中间人,通过 PKI 引擎向 Vault 申请签名,而 Vault 负责私钥的安全管理。


6. 运维与故障排查深度指南

6.1 故障排查流程

当证书没有成功签发(Secret 未生成或为空)时,请遵循以下排查路径:

  1. 检查 Certificate 状态: code Bashdownloadcontent_copyexpand_less kubectl describe certificate <name> 查看 Conditions 和 Events。通常会显示 “Waiting for CertificateRequest”。
  2. 检查 CertificateRequest: code Bashdownloadcontent_copyexpand_less kubectl describe certificaterequest <name> 如果失败,通常是 Issuer 配置错误或拒绝了请求。
  3. 检查 Order 和 Challenge (仅 ACME):
    这是最容易出错的地方。 code Bashdownloadcontent_copyexpand_less kubectl get order -n <ns> kubectl describe challenge <challenge-name> -n <ns> 常见错误 1: DNS 记录未传播。常见错误 2: 防火墙阻止了 Let’s Encrypt 访问 .well-known/acme-challenge 路径。常见错误 3: Self-check 失败(cert-manager 会在通过 ACME 验证前先自测,如果集群内部网络不通,这里会报错)。

6.2 监控与告警

不要等到证书过期导致服务宕机才发现问题。建议利用 Prometheus 监控 cert-manager 暴露的指标:

  • certmanager_certificate_expiration_timestamp_seconds: 证书过期时间戳。
  • certmanager_certificate_ready_status: 证书是否就绪。

设置告警规则:当 ready_status 为 0 或 有效期小于 15 天且未成功续期时触发 P1 告警。

7. 总结

cert-manager 不仅仅是一个证书申请工具,它是 Kubernetes 安全基础设施的重要组件。通过将证书生命周期管理抽象为 CRD,它实现了“基础设施即代码”在安全领域的落地。

  • 对于公网服务,使用 ClusterIssuer + Ingress Annotation + Let’s Encrypt 实现零成本自动化。
  • 对于内网服务,使用 CA Issuer 或 Vault 实现微服务间的 mTLS。
  • 对于运维,建立完善的监控体系,关注 Challenge 资源的执行状态。

掌握 cert-manager,意味着构建了一个健壮、自动化的信任分发网络,这是云原生架构迈向成熟的必经之路。

更多推荐