cert-manager证书自动化实战:Let’s Encrypt签发与Ingress HTTPS配置方案

证书管理是HTTPS站点运维里最繁琐的环节,证书默认90天有效期,手动续期在服务器规模超过三台后基本不可维护。cert-manager是Kubernetes生态的事实标准证书控制器,通过CRD把证书申请、续期、注入Secret全流程声明式化,支持Let’s Encrypt、ZeroSSL及自建CA。配合Ingress的自动化签发,一个新域名从解析到HTTPS可访问可以在两分钟内完成。

cert-manager安装与ClusterIssuer配置方法

安装推荐Helm方式,便于版本管理与卸载:

helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager   --namespace cert-manager --create-namespace   --set crds.enabled=true   --version v1.15.3

安装后创建ClusterIssuer。Let’s Encrypt推荐HTTP-01与HTTP-01两种验证方式里选前者做通用签发,后者用于通配符证书:

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

HTTP-01验证要求域名的80端口可从公网访问,cert-manager会自动创建一个临时Pod完成验证。如果集群前面有CDN或WAF,需要放行 /.well-known/acme-challenge/ 路径回源。签发通配符证书改用DNS-01,以Cloudflare DNS为例:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-dns
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ops@yourdomain.com
    privateKeySecretRef:
      name: letsencrypt-dns-account-key
    solvers:
    - dns01:
        cloudflare:
          apiTokenSecretRef:
            name: cloudflare-api-token
            key: api-token

Cloudflare API Token需要Zone.DNS编辑权限,存入Secret后cert-manager通过它动态写入TXT记录验证域名所有权,验证完成自动清理记录。相比HTTP-01,DNS-01不依赖公网入口,适合内网K8s集群使用公网证书的场景。

Ingress自动签发证书的annotation触发方式

日常加域名最省事的方式是在Ingress上打annotation,cert-manager检测到后自动创建Certificate资源:

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

spec.tls段是触发点:指定了hosts与secretName且带cluster-issuer annotation,cert-manager就生成Certificate对象并走签发流程,证书写入名为api-yourdomain-tls的Secret,Ingress控制器热加载。这个方式缺点是证书与Ingress生命周期耦合,删除Ingress时cert-manager默认会清理证书资源。生产上更建议显式创建Certificate CR,把证书作为独立资产维护:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: api-yourdomain
spec:
  secretName: api-yourdomain-tls
  duration: 2160h    # 90天
  renewBefore: 720h  # 到期前30天开始续期
  dnsNames:
  - api.yourdomain.com
  issuerRef:
    kind: ClusterIssuer
    name: letsencrypt-prod

renewBefore默认是有效期的三分之二处开始续期,显式设置留出失败重试窗口。Let’s Encrypt有重复签发限速(同一证书一周内最多5次),duration不能自定义缩短,生产环境务必用生产端点。

证书签发失败排查与续期监控告警配置

签发失败的高频原因排第一位的是ACME challenge路径被拦截,第二是ClusterIssuer引用的Secret不存在。排查命令链:

# 1. 查看Certificate状态与事件
kubectl describe certificate api-yourdomain
# 看 Events 里 Ready 字段与报错信息

# 2. 追踪CertificateRequest(每1次申请一个CR)
kubectl get certificaterequests -o wide
kubectl describe certificaterequest <name>

# 3. 查看Order与Challenge状态
kubectl get orders,challenges -A
kubectl describe challenge <name>
# 报http01 challenge路径不可达时,检查Ingress/防火墙/CDN回源

监控方面,cert-manager暴露Prometheus指标,关键指标certmanager_controller_certificates_ready_status的0值持续时间就是告警条件。告警规则示例:

- alert: CertManagerCertNotReady
  expr: certmanager_controller_certificates_ready_status{condition="False"} == 1
  for: 1h
  labels:
    severity: warning
  annotations:
    summary: "证书 {{ $labels.namespace }}/{{ $labels.name }} 未就绪超过1小时"

配合检查证书实际到期时间的blackbox exporter做双保险,能覆盖cert-manager自身故障的情况。对于非K8s的裸机服务,可以用step-ca自建ACME服务器复用同一套流程,把内网数百张自签证书也纳入自动化续期,彻底告别人工更换证书的运维负担。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/certmanager-zheng-shu-zi-dong-hua-shi-zhan-letsencrypt-qian/

(0)
小编小编
上一篇 50分钟前
下一篇 50分钟前

相关推荐