Kubernetes Ingress、证书与 cert-manager 总结

This article is extracted from the chat log with AI. Please identify it with caution.

本文边界:本文聚焦业务入口 TLS、证书 Secret 与 cert-manager 的协作;Ingress 资源和 Ingress Controller 的路由模型请阅读入口专题。

推荐深读Ingress 详解:Kubernetes 集群的"智能交通指挥中心"

说明:本文由 Codex 根据作者提问、上下文讨论与官方文档辅助整理,属于 AI 生成/整理内容。涉及生产环境证书与集群控制面维护时,请结合实际发行版、安装方式和官方文档交叉验证。

先说结论#

在 Kubernetes 里,IngressIngress Controllercert-manager 是三类不同角色:

Ingress 是规则;
Ingress Controller 是执行规则的网关或反向代理;
cert-manager 是自动签发、续期、分发证书的控制器。

它们常见的协作链路是:

Client
  -> DNS
  -> LoadBalancer / NodePort
  -> Ingress Controller
  -> Service
  -> Pod

cert-manager
  -> Issuer / ClusterIssuer
  -> CA / Let's Encrypt / Vault / 私有 CA
  -> Secret(tls.crt, tls.key)
  -> Ingress Controller 加载 TLS 证书

证书方面可以先抓住一个边界:

  • 控制面证书保护 Kubernetes 自身,例如 API Server、etcd、controller-manager、scheduler、kubelet。
  • 业务入口证书保护应用入口,例如 Ingress HTTPS 证书。
  • 扩展组件证书保护 webhook、aggregated API server、operator 等扩展链路。
  • 服务间 mTLS 证书保护 Pod 到 Pod 的通信,常见于 service mesh。

cert-manager 很适合管理业务层和扩展层证书,但不建议把 Kubernetes 控制面 PKI 全部交给 cert-manager 管。

Ingress、Ingress Controller 与 cert-manager 的区别#

Ingress#

Ingress 是 Kubernetes API 资源对象,描述外部 HTTP/HTTPS 流量应该如何进入集群。

它通常定义:

  • 域名:例如 app.example.com
  • 路径:例如 /api/
  • 后端服务:例如 app-service:80
  • TLS Secret:例如 app-tls
  • IngressClass:例如 nginx
  • Controller 专属注解:例如 NGINX rewrite、限流、白名单等

示例:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app
  namespace: demo
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - app.example.com
      secretName: app-tls
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app
                port:
                  number: 80

需要注意:只创建 Ingress 资源本身不会让流量真正进入集群。Kubernetes 官方文档也强调,必须有 Ingress Controller 来满足这个 Ingress。

Ingress Controller#

Ingress Controller 是真正处理流量的组件。

常见实现包括:

  • ingress-nginx
  • Traefik
  • HAProxy
  • Envoy / Contour
  • AWS Load Balancer Controller
  • GCE Ingress Controller
  • Azure Application Gateway Ingress Controller

它通常以 DeploymentDaemonSet 运行,并通过一个 Service 暴露 80/443。

以 ingress-nginx 为例,常见 Helm 安装方式是:

helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace

Ingress Controller 的核心工作:

  • watch IngressServiceEndpointSliceSecretIngressClass
  • 判断哪些 Ingress 属于自己处理
  • 把 Ingress 规则转换为 NGINX、Traefik、Envoy 或云 LB 配置
  • 接收外部 HTTP/HTTPS 流量
  • 按 host/path 转发到后端 Service
  • 读取 TLS Secret,完成 HTTPS 终止

在云厂商集群中,Ingress Controller 常通过 LoadBalancer 类型 Service 对外暴露。在裸金属环境中,则常见使用 NodePort、hostNetwork 或 MetalLB。

cert-manager#

cert-manager 是 Kubernetes 里的证书生命周期管理器。

它会安装一组 CRD,例如:

  • Issuer
  • ClusterIssuer
  • Certificate
  • CertificateRequest
  • Order
  • Challenge

它的基本模型是:

Certificate
  -> Issuer / ClusterIssuer
  -> 外部或内部 CA
  -> Secret

常见安装方式:

helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \
  --version v1.20.3 \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

cert-manager 负责:

  • 根据 Certificate 资源申请证书
  • 通过 IssuerClusterIssuer 找到签发方
  • 对接 Let’s Encrypt、Vault、私有 CA 等
  • 完成 ACME HTTP-01 或 DNS-01 验证
  • 把证书和私钥写入 Kubernetes Secret
  • 在证书过期前自动续期

三者如何配合工作#

最典型的场景是:Ingress + ingress-nginx + cert-manager + Let’s Encrypt。

流程如下:

sequenceDiagram
    participant User as Client
    participant DNS as DNS
    participant IC as Ingress Controller
    participant APP as App Service/Pod
    participant CM as cert-manager
    participant LE as Let's Encrypt
    participant SEC as Kubernetes Secret

    CM->>CM: 监听 Ingress 注解与 Certificate
    CM->>LE: 请求签发 app.example.com 证书
    LE->>CM: 返回 ACME Challenge
    CM->>IC: 创建临时 HTTP-01 solver Ingress
    LE->>DNS: 解析 app.example.com
    LE->>IC: 访问 /.well-known/acme-challenge/...
    IC->>CM: 转发到 solver Pod
    CM->>LE: 验证通过
    LE->>CM: 签发证书
    CM->>SEC: 写入 tls.crt / tls.key
    IC->>SEC: 加载 TLS Secret
    User->>DNS: 访问 app.example.com
    DNS->>IC: 指向入口地址
    IC->>APP: TLS 终止后转发请求

如果 Ingress 上有这样的注解:

metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod

并且 spec.tls.secretName 指定了 Secret 名称,cert-manager 的 ingress-shim 会自动创建或维护对应的 Certificate

一个典型 ClusterIssuer

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

HTTP-01 的关键要求是:Let’s Encrypt 必须能从公网访问这个域名的 80 端口,并最终打到 cert-manager 创建的 solver Pod。

DNS-01 则不要求公网 HTTP 可达,而是通过 DNS TXT 记录证明域名所有权。它更适合:

  • 泛域名证书,例如 *.example.com
  • 内网服务证书
  • 不方便暴露 HTTP-01 路径的场景

集群中常见证书类型#

CA 证书#

CA 是信任根,负责签发和验证其他证书。

在 kubeadm 集群中,常见 CA 有:

证书作用常见路径
Kubernetes CA签发 API Server、组件客户端、用户等证书/etc/kubernetes/pki/ca.crt
etcd CA签发 etcd server、peer、client 证书/etc/kubernetes/pki/etcd/ca.crt
front-proxy CA用于聚合 API / extension API server/etc/kubernetes/pki/front-proxy-ca.crt

ca.keyetcd/ca.keyfront-proxy-ca.key 是私钥,必须严格保护。

服务端证书#

服务端证书证明“我是这个服务”。

证书谁使用谁验证
apiserver.crtkube-apiserverkubectl、kubelet、controller-manager、scheduler
etcd/server.crtetcd serverkube-apiserver、etcdctl
kubelet serving certkubelet HTTPS endpointkube-apiserver、metrics-server
Ingress TLS SecretIngress Controller浏览器、外部客户端
webhook serving certadmission webhook / conversion webhookkube-apiserver

服务端证书最容易踩坑的是 SAN,即 Subject Alternative Name。客户端访问的 IP 或 DNS 必须包含在证书 SAN 中,否则会出现类似:

x509: certificate is valid for ..., not ...

客户端证书#

客户端证书证明“调用方是谁”。

证书调用方向身份含义
admin.conf 中的 client certadmin / kubectl -> apiserver管理员身份
controller-manager.confcontroller-manager -> apiserversystem:kube-controller-manager
scheduler.confscheduler -> apiserversystem:kube-scheduler
kubelet client certkubelet -> apiserversystem:node:<nodeName>
kube-proxy client certkube-proxy -> apiserverkube-proxy 身份
apiserver-etcd-client.crtapiserver -> etcdapiserver 作为 etcd 客户端
apiserver-kubelet-client.crtapiserver -> kubeletapiserver 作为 kubelet 客户端

Kubernetes 认证时会从证书中读取 CNO 等字段,并结合 RBAC 判断这个身份可以做什么。

etcd peer 证书#

etcd 比较特殊,它除了 server/client 证书,还有 peer 证书。

证书作用
etcd/peer.crtetcd 节点之间互相认证和通信
etcd/server.crtetcd 对客户端提供 TLS 服务
etcd/healthcheck-client.crt健康检查客户端访问 etcd
apiserver-etcd-client.crtapiserver 访问 etcd

etcd 集群内部通常启用双向 TLS。也就是说,节点之间既要证明自己,也要验证对方。

Ingress 业务证书#

Ingress 证书一般存放在 Kubernetes Secret 中:

tls.crt
tls.key

它只负责业务入口 HTTPS,例如:

Browser
  -> Ingress Controller
  -> Service
  -> Pod

它和 Kubernetes 控制面证书不是一类东西。它面向业务域名,例如 app.example.com,通常适合由 cert-manager 维护。

webhook 与聚合 API 证书#

Admission webhook、conversion webhook、aggregated API server 都可能需要服务端证书。

链路通常是:

kube-apiserver
  -> webhook service
  -> webhook pod

如果 webhook 证书过期、CA bundle 不对,常见错误是:

failed calling webhook
x509: certificate signed by unknown authority
certificate has expired or is not yet valid

这类证书适合由 cert-manager 管理,配合 cainjector 自动注入 CA bundle。

service mesh / workload mTLS 证书#

如果集群中使用 Istio、Linkerd、Consul Connect、SPIFFE/SPIRE,还会有 workload 证书。

特点:

  • 生命周期通常较短
  • 每个 workload 有独立身份
  • 常使用 SPIFFE ID
  • 不一定存放在 Kubernetes Secret 中
  • 通常由 service mesh 或 SPIRE 自己维护

这类证书主要保护服务间通信,不是 Ingress 对外 HTTPS 证书。

证书有没有过期时间#

大多数 X.509 证书都有过期时间,包括 CA、服务端证书和客户端证书。

以 kubeadm 默认配置为例:

类型默认有效期通常谁维护是否适合 cert-manager
Kubernetes CA10 年kubeadm / 外部 CA通常不适合
etcd CA10 年kubeadm / 外部 CA通常不适合
front-proxy CA10 年kubeadm / 外部 CA通常不适合
apiserver server cert1 年kubeadm不建议
apiserver-etcd-client cert1 年kubeadm不建议
apiserver-kubelet-client cert1 年kubeadm不建议
controller-manager / scheduler / admin client cert1 年kubeadm不建议
kubelet client cert通常 1 年左右kubelet 自动轮转 + Kubernetes CSR不是典型职责
kubelet serving cert取决于配置kubelet / CSR / 发行版机制通常不建议
Ingress TLS 证书常见 90 天cert-manager适合
webhook serving cert取决于配置chart / operator / cert-manager适合
workload mTLS 证书小时到天级常见service mesh / SPIRE通常由 mesh 管

kubeadm 支持在配置中调整证书有效期:

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
certificateValidityPeriod: 8760h      # 默认 1 年
caCertificateValidityPeriod: 87600h   # 默认 10 年

cert-manager 的 Certificate 也可以指定有效期和提前续期时间:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: app-cert
  namespace: demo
spec:
  secretName: app-tls
  duration: 2160h     # 90 天
  renewBefore: 360h   # 提前 15 天续期
  dnsNames:
    - app.example.com
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer

cert-manager 默认 duration 是 90 天。如果没有设置 renewBefore,它会在证书实际有效期走到约 2/3 时尝试续期。

cert-manager 能不能管理所有证书#

结论:不能简单地把所有证书都交给 cert-manager,尤其不要把控制面 PKI 依赖在集群内的 cert-manager 上。

原因很直接:

cert-manager 运行在 Kubernetes 集群里;
cert-manager 依赖 kube-apiserver 正常工作;
控制面证书失效时,kube-apiserver、etcd 或认证链路可能已经不可用;
此时 cert-manager 也可能无法正常补救。

所以更合理的职责边界是:

证书范围推荐维护方式
控制面证书kubeadm、发行版工具、外部 CA、集群生命周期管理工具
etcd 证书kubeadm、etcd 运维流程、发行版工具、外部 CA
kubelet client certkubelet certificate rotation + Kubernetes CSR
Ingress HTTPS 证书cert-manager
应用 TLS Secretcert-manager
webhook serving certcert-manager / operator / Helm chart
service mesh workload certIstio、Linkerd、SPIRE 等自身 CA 系统

常用排查命令#

查看 kubeadm 控制面证书过期时间#

kubeadm certs check-expiration

续期 kubeadm 管理的证书#

kubeadm certs renew all

续期后通常需要重启相关控制面静态 Pod 或节点服务,让组件加载新证书。具体操作要结合集群发行版和高可用部署方式。

查看 cert-manager 管理的证书#

kubectl get certificate -A

查看某个证书详情#

kubectl describe certificate -n <namespace> <name>

查看 CertificateRequest / Order / Challenge#

kubectl get certificaterequest -A
kubectl get order -A
kubectl get challenge -A

查看 TLS Secret 内容#

kubectl get secret -n <namespace> <secret-name> -o yaml

解码证书并查看有效期#

kubectl get secret -n <namespace> <secret-name> \
  -o jsonpath='{.data.tls\.crt}' \
  | base64 -d \
  | openssl x509 -noout -text -dates

手动触发 cert-manager 续期#

cmctl renew -n <namespace> <certificate-name>

不建议通过删除 Secret 来作为常规续期手段。cert-manager 官方更推荐通过 cmctl renew 或调整 Certificate 资源触发重新签发。

生产实践建议#

控制面证书#

  • 定期运行 kubeadm certs check-expiration 或发行版提供的检查命令。
  • 将证书过期时间接入监控和告警。
  • 保持 Kubernetes 小版本和补丁版本及时升级;kubeadm 会在控制面升级时处理证书续期。
  • 不要等证书过期后再处理,尤其是 apiserver、etcd、admin.conf。
  • 对 CA 轮换保持谨慎,CA 轮换比 leaf certificate 续期风险更高。

Ingress 证书#

  • 优先使用 cert-manager 管理。
  • HTTP-01 要确认公网能访问 80 端口。
  • DNS-01 要确认 DNS provider 权限、TXT 记录传播和递归 DNS 行为。
  • 不同环境建议分开使用 staging 和 production Issuer,避免触发 Let’s Encrypt 限流。
  • 对重要域名监控 Certificate 状态和 Secret 证书过期时间。

webhook 证书#

  • webhook 证书过期会影响资源创建、更新甚至集群扩展组件运行。
  • 如果使用 cert-manager 管理 webhook 证书,应确认 cainjector 正常工作。
  • 排查 webhook 错误时同时看 ValidatingWebhookConfiguration / MutatingWebhookConfiguration 中的 caBundle

service mesh 证书#

  • 不要把 mesh 的工作负载证书和 Ingress 证书混为一类。
  • 按 mesh 自身文档维护根 CA、中间 CA、workload cert rotation。
  • 重点关注根证书过期、trust bundle 分发和多集群信任域。

关键区别速记#

Ingress:声明 HTTP/HTTPS 路由规则。
Ingress Controller:真正接收和转发流量。
cert-manager:签发和续期证书。

server cert:证明服务是谁。
client cert:证明调用方是谁。
CA cert:证明谁有资格签发和校验证书。

控制面证书:不要依赖集群内 cert-manager 兜底。
业务入口证书:非常适合 cert-manager。
webhook 证书:适合 cert-manager,但要关注 caBundle 注入。
service mesh 证书:通常由 mesh 自己管理。

参考资料#

本文共 4163 字,创建于 Jul 7, 2026

相关标签: Kubernetes, DevOps, ByAI