Cert-Manager 概述
cert-manager 是 Kubernetes 的原生证书管理器(CRD 控制器),它能够为 Kubernetes 或 OpenShift 集群中的工作负载创建 TLS 证书,并在证书到期前自动续订证书。
它的作用是监控 Kubernetes 中的 Certificate 资源,自动向配置的证书颁发者(Issuer)申请证书,获取到证书后生成包含私钥和证书的 Kubernetes Secret(signed keypair),该 Secret 由应用程序 Pod 挂载或由 Ingress 控制器使用。
- 而使用 csi-driver、csi-driver-spiffe 或 istio-csr 时,私钥会在应用程序启动前按需生成;私钥永远不会离开节点,也不会存储在 Kubernetes Secret 中。
cert-manager 可以从各种证书颁发机构获取证书,包括: Let’s Encrypt、HashiCorp Vault、 Venafi 和私有 PKI(私有证书颁发机构,自签名证书)。
参考文档
- 官网:https://cert-manager.io
- 官方文档:https://cert-manager.io/docs/
- github:https://github.com/cert-manager/cert-manager
Cert-Manager 架构
Issuers(证书颁发者)图中展示了 cert-manager 配置的多个 Issuer 或 ClusterIssuer,这些是不同的证书来源:
- letsencrypt-prod:Let’s Encrypt 生产环境,用于颁发真实可信的公网证书。
- letsencrypt-staging:Let’s Encrypt 测试环境,用于开发测试,避免触发频率限制。
- hashicorp-vault:HashiCorp Vault 的证书颁发功能(通常通过 Vault 的 PKI secrets engine)。
- cyberark-saas:CyberArk 的云托管证书服务(Conjur 或 CyberArk Trust Protection)。
- cyberark-self-hosted:自托管的 CyberArk 证书颁发服务。
- 这些 Issuer 都指向同一个 cert-manager,意思是 cert-manager 可以根据不同的需求选择不同的后端来签发证书。
Certificates(证书资源)这是 Kubernetes 中的 cert-manager 自定义资源(Certificate CR),代表你想要申请的证书。图中举了两个例子:
foo.bar.comIssuer: cyberark-saas(使用 CyberArk 的 SaaS 服务来签发这个域名证书)example.com / www.example.comIssuer: letsencrypt-prod(使用 Let’s Encrypt 生产环境签发这个域名证书)
Kubernetes Secret:
- cert-manager 在成功从 Issuer 获取证书后,会自动创建一个 Kubernetes Secret。
- 图中用黄色卷轴图标表示,名称为 “signed keypair”,里面包含:
- tls.key(私钥)
- tls.crt(证书链)
- 这些 Secret 随后可以被 Ingress、Pod 等资源通过 volume 或环境变量挂载使用,实现 TLS 终止。
整体流程总结:
- 你在 Kubernetes 集群中创建 Certificate 自定义资源,指定域名和要使用的 Issuer。
- cert-manager 监听到这个 Certificate 资源。
- cert-manager 根据指定的 Issuer 去对应的证书颁发机构申请证书(可能需要 ACME challenge、Vault API 调用等)。
- 证书签发成功后,cert-manager 生成或更新一个 Kubernetes Secret(包含私钥 + 证书)。
- 你的应用(如 Ingress Controller)使用这个 Secret 来启用 HTTPS。
这个架构的优势:
- 统一管理:所有证书都通过 cert-manager 集中自动化管理,无需手动申请和续期。
- 多后端支持:可以根据不同域名的合规要求,选择不同的 CA(公网用 Let’s Encrypt,企业内部域名用 Vault 或 CyberArk)。
- 环境分离:开发用 staging,避免污染生产配额;生产用 prod 或企业内部 CA。
- 安全合规:对于需要更高安全要求的企业,可以用 Vault 或 CyberArk 这种企业级 PKI 系统。
Cert-Manager 核心组件
cert-manager-controller(主控制器 Deployment)
- 这是 cert-manager 的核心大脑。
- 负责监控自定义资源(如 Certificate、Issuer、ClusterIssuer、CertificateRequest 等)。
- 处理证书的颁发、续期、撤销等整个生命周期。
- 运行多个内部控制器(如 certificates、issuers、certificaterequests、orders、challenges 等),协调与外部 CA(如 Let’s Encrypt、Vault)的交互。
- 通常部署为单副本(使用 leader election 确保高可用)。
cert-manager-webhook(Webhook Deployment)
- 提供 Admission Webhook 服务。
- 主要用于验证 cert-manager 的自定义资源(CR)的 API 请求(如 Issuer、Certificate 的创建/更新),确保配置有效。
- 同时处理 webhook 自身的 TLS 证书(通常由 cert-manager 自己管理)。
- 也是单副本运行。
cert-manager-cainjector(CA Injector Deployment)
- 负责将证书权威(CA)的公钥证书自动注入到 Kubernetes 的资源中。
- 典型用途:将 Issuer/ClusterIssuer 引用的 CA 证书注入到 ValidatingWebhookConfiguration、MutatingWebhookConfiguration 和 Pod 的 ConfigMap 中(例如为 Ingress Controller 或 API Server 添加信任)。
- 这确保了集群能信任 cert-manager 签发的证书。
- 同样使用 leader election,通常单副本。
cert-manager-acmesolver(ACME Solver Deployment,可选/按需)
- 专门处理 ACME 协议的 DNS01 挑战(HTTP01 通常由独立的 per-challenge Pod 处理)。
- 当使用 Let’s Encrypt 等 ACME Issuer 并选择 DNS01 验证时,会创建这个组件的 Pod 来临时更新 DNS 记录。
- 不是常驻的主组件,而是按需运行。
附加说明:
- 安装 cert-manager 时(例如通过 Helm 或静态 manifest),会自动部署以上组件的 Pod,可以用
kubectl get pods -n cert-manager查看,通常看到cert-manager-*、cert-manager-cainjector-*和cert-manager-webhook-*。 - 还有一些扩展组件(如 cert-manager-csi-driver、istio-csr 等),但它们不属于核心,而是可选的卫星项目,用于更高级的场景(如 secretless 证书分发)。
- cert-manager 本身还定义了许多 CRD(Custom Resource Definitions),如 Certificate、Issuer 等,这些是 API 资源而非运行组件。
这些组件协同工作,确保 cert-manager 在 Kubernetes 中实现自动化、安全的 TLS 证书管理。
Cert-Manager CRDs
cert-manager 的 API 主要基于 Kubernetes 的 Custom Resource Definitions (CRDs),所有自定义资源都属于 API Group cert-manager.io(核心部分)和 acme.cert-manager.io(ACME 特定部分)。
cert-manager 定义了以下核心 CRDs(可以通过 kubectl get crd | grep cert-manager.io 查看):
| CRD 全名 | Kind | 作用域 | 主要用途 |
|---|---|---|---|
| certificates.cert-manager.io | Certificate | Namespaced | 用户最常用的资源:描述所需的 TLS 证书(域名、私钥算法、有效期等),cert-manager 会自动向 Issuer 申请、续期,并将证书+私钥存入 Secret。 |
| certificaterequests.cert-manager.io | CertificateRequest | Namespaced | 代表一个具体的证书签名请求(CSR),包含 PEM 编码的 CSR。通常由 Certificate 资源自动创建,用于与 Issuer 交互。 |
| issuers.cert-manager.io | Issuer | Namespaced | 定义命名空间级别的证书颁发者(CA),支持 ACME(Let’s Encrypt)、CA、Vault、Venafi 等类型。Certificate 资源引用它来签发证书。 |
| clusterissuers.cert-manager.io | ClusterIssuer | Cluster | 与 Issuer 类似,但集群级别,可被任何命名空间的 Certificate 引用。 |
| orders.acme.cert-manager.io | Order | Namespaced | ACME 协议专用的资源:代表向 ACME 服务(如 Let’s Encrypt)发起的一个证书订单,管理多个域名的验证过程。 |
| challenges.acme.cert-manager.io | Challenge | Namespaced | ACME 协议专用的资源:代表一个域名验证挑战(HTTP-01 或 DNS-01),cert-manager 会自动创建 solver Pod 来完成验证。 |
说明:
- 核心流程:用户创建 Certificate → cert-manager 生成 CertificateRequest → 根据引用的 Issuer/ClusterIssuer(如果是 ACME 类型,会创建 Order 和 Challenge)→ 最终签发证书。
- API 版本:所有以上 CRDs 的稳定版本为
cert-manager.io/v1和acme.cert-manager.io/v1。早期版本有 v1alpha2、v1beta1 等,现已废弃。 - 其他内部/配置 CRD:cert-manager 还有一些内部配置 CRD(如 controller.config.cert-manager.io/v1alpha1 用于控制器配置),但用户通常不直接操作。
- 查看 API 文档:完整字段和结构体详见官方 API Reference:https://cert-manager.io/docs/reference/api-docs/
这些 CRDs 构成了 cert-manager 的完整 API 接口,让用户以声明式方式管理 Kubernetes 中的 TLS 证书。
Cert-Manager 部署
Helm
helm repo add cert-manager https://charts.jetstack.io
helm repo update cert-manager
helm pull cert-manager/cert-manager --version v1.16.5
helm show values cert-manager/cert-manager --version 1.16.5 > values-cert-manager-v1.16.5.yaml
# 修改 values-cert-manager-v1.16.5.yaml 文件
...
crds:
enabled: true # 启用CRD
...
# 安装/升级
helm upgrade --install cert-manager ./cert-manager-v1.16.5.tgz \
--version 1.16.5 \
--namespace cert-manager \
--create-namespace \
-f values-cert-manager-v1.16.5.yaml
# 验证
kubectl get pod -n cert-manager
kubectl api-resources | grep -i cert-manager
kubectl get crd | grep cert-manager
注意事项:
Be sure never to embed cert-manager as a sub-chart of other Helm charts; cert-manager manages non-namespaced resources in your cluster and care must be taken to ensure that it is installed exactly once.
官方文档中说明 cert-manager 在一个 Kubernetes 集群中必须且只能安装一次,如果在同一个集群中安装多个 cert-manager 实例(例如多次 helm install,或者把 cert-manager 当作其他 Helm chart 的 sub-chart 来嵌入),就会导致:
- 多个控制器同时管理同一个集群级资源,造成冲突、竞争或不可预测的行为(例如多个 webhook 同时验证、多个控制器处理同一个 CertificateRequest)。
- 潜在的资源覆盖、错误或集群不稳定。
Cert-Manager 使用
自建 CA 并签发应用证书
- 先创建一个自签名的根 CA 证书(Issuer 和 Subject 相同,但设置 Basic Constraints: CA:true)。
- 然后用这个根 CA 的私钥签名其他端实体证书(叶证书,叶证书的 Issuer 是根 CA,Subject 是服务器域名等)。
使用场景:
内网多服务器、企业私有 PKI、需要管理多个证书的场景。只需在所有客户端信任一次根 CA 证书,所有由它签发的叶证书就自动被信任(更安全、管理方便、私钥泄露时可吊销叶证书)。
目录结构
cert-manager/
├── 00-Namespace-pki.yaml
├── 01-root-ca-selfsigned-ClusterIssuer.yaml
├── 02-root-ca-Certificate.yaml
├── 03-root-ca-clusterissuer.yaml
│
├── apps/
│ └── backend/
│ ├── certificate-backend-api.yaml
│ └── deployment.yaml
创建自签名根CA
00-Namespace-pki.yaml
- 创建单独的 namespace 存放根 CA,避免业务 namespace 能访问 CA 私钥,以及后续好做 RBAC 控制。
apiVersion: v1
kind: Namespace
metadata:
name: pki
01-root-ca-selfsigned-ClusterIssuer.yaml
- 定义集群级别的证书颁发者(CA),Certificate 资源引用它来签发证书。
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: root-ca-selfsigned
spec:
selfSigned: {}
02-root-ca-Certificate.yaml
- 生成根 CA 证书与私钥的 Secret,其中包括:
tls.key:根 CA 的私钥,用于签发所有业务证书,最敏感,需要严格 RBAC 控制。tls.crt:根 CA 的公钥(自己的证书)。ca.crt:与tls.crt的内容一样,但语义不同:字段 语义 tls.crtCA 自己的证书(Issuer 身份) ca.crt“这是你要信任的 CA”
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: root-ca
namespace: pki
spec:
# Root CA 的证书与私钥将存储在该 Secret 中
secretName: root-ca-secret
# Root CA 有效期可以较长
duration: 87600h # 10 年
renewBefore: 8760h # 提前 1 年续期
# 声明该证书为 CA
isCA: true
# 私钥算法与大小
privateKey:
algorithm: RSA
size: 4096
# 参考哪个 Issuer
issuerRef:
name: root-ca-selfsigned
kind: ClusterIssuer
# 写入证书 Subject 字段中的内容
commonName: bjhit-prod-k8s-root-ca
subject:
organizations:
- Bjhit
应用:
kubectl apply -f .