下面说明基于  Kubernetes  v1.24+、cert-manager  v1.13+、Ingress-Nginx  v1.8+,为生产环境设计的步骤。

一、为什么需要自动化  SSL  证书?

在生产环境中,手动为  Ingress  配置  SSL证书面临三大挑战:

证书有效期短:Let's  Encrypt  等免费证书的有效期通常只有  90  天,手动更新极易出错。

操作繁琐:每次申请、更新证书都需要生成密钥、创建  Secret、修改  Ingress  配置,无法规模化。

业务风险高:证书过期将直接导致  HTTPS  访问失败,影响线上业务。

Cert-Manager  作为  Kubernetes  生态的标准证书管理工具,通过  ACME(自动证书管理环境)协议,能与  Let's  Encrypt  等证书颁发机构(CA)无缝对接,实现证书的**自动申请、部署和续期,全程零人工介入。

二、核心技术组件

Cert-Manager:Kubernetes  原生的证书生命周期管理控制器,自动处理证书的申请、续期和存储。

Let's  Encrypt:提供免费、自动化、受浏览器信任的  SSL/TLS  证书,支持  ACME  协议。

ACME  挑战:证书申请时的域名所有权验证方式。最常用的是  HTTP-01  挑战(通过域名上的特定  HTTP  路径验证)和  DNS-01  挑战(通过  DNS  TXT  记录验证)。

三、实施步骤(生产级配置)

步骤  1:安装  Ingress  Controller

Cert-Manager  需要配合  Ingress  Controller  工作,这里以最主流的  Ingress-Nginx  为例。

bash

添加  Helm  仓库并安装  Ingress-Nginx

helm  repo  add  ingress-nginx  https://kubernetes.github.io/ingress-nginx

helm  repo  update

helm  install  ingress-nginx  ingress-nginx/ingress-nginx  \

    --namespace  ingress-nginx  \

    --create-namespace  \

    --set  controller.service.type=LoadBalancer    #  根据环境调整  Service  类型

安装完成后,通过  `kubectl  get  svc  -n  ingress-nginx`  获取  **EXTERNAL-IP,将你的域名(如  `example.com`)通过  A  记录解析到该  IP  地址。

步骤  2:安装  Cert-Manager

使用  Helm  安装  Cert-Manager,并启用其  CRD(自定义资源定义):

bash

#  添加  Jetstack  仓库(Cert-Manager  官方维护)

helm  repo  add  jetstack  https://charts.jetstack.io

helm  repo  update

#  安装  Cert-Manager(指定版本以兼容生产环境)

helm  install  cert-manager  jetstack/cert-manager  \

    --namespace  cert-manager  \

    --create-namespace  \

    --version  v1.14.3  \

    --set  installCRDs=true

验证安装成功:

bash

kubectl  get  pods  -n  cert-manager

#  应看到三个  Pod  均处于  Running  状态:cert-manager-xxx,  cert-manager-cainjector-xxx,  cert-manager-webhook-xxx

步骤  3:创建  ClusterIssuer(集群级证书签发器)

ClusterIssuer  是  Cert-Manager  的核心配置,定义了如何与  Let's  Encrypt  交互。强烈建议先配置  Staging  环境进行测试,再切换到  Production,避免因配置错误触发速率限制。

创建  `cluster-issuer.yaml`  文件:

yaml

#  测试环境  ClusterIssuer(用于验证配置)

apiVersion:  cert-manager.io/v1

kind:  ClusterIssuer

metadata:

    name:  letsencrypt-staging

spec:

    acme:

        server:  https://acme-staging-v02.api.letsencrypt.org/directory

        email:  your-email@example.com                    #  ⚠️  替换为你的邮箱,用于接收证书过期提醒

        privateKeySecretRef:

            name:  letsencrypt-staging-account-key

        solvers:

        -  http01:

                ingress:

                    class:  nginx                                            #  必须与  Ingress  Controller  的  IngressClass  名称一致

#  生产环境  ClusterIssuer(稳定后使用)

apiVersion:  cert-manager.io/v1

kind:  ClusterIssuer

metadata:

    name:  letsencrypt-prod

spec:

    acme:

        server:  https://acme-v02.api.letsencrypt.org/directory

        email:  your-email@example.com

        privateKeySecretRef:

            name:  letsencrypt-prod-account-key

        solvers:

        -  http01:

                ingress:

                    class:  nginx

应用配置:

bash

kubectl  apply  -f  cluster-issuer.yaml

步骤  4:为  Ingress  配置自动  HTTPS

Cert-Manager  提供了两种自动签发证书的方式,各有适用场景:

方式      描述      适用场景  

方式一:Ingress  Annotation        在  Ingress  中添加  `cert-manager.io/cluster-issuer`  注解,Cert-Manager  自动创建证书      简单域名,证书仅在  Ingress  中使用    

方式二:Certificate  资源        创建独立的  Certificate  CRD,声明证书的域名和  Secret  名称      需要精细化控制证书配置、跨  Ingress  复用证书等  

方式一:通过  Annotation  自动签发(推荐,最简单)

创建  `ingress.yaml`:

yaml

apiVersion:  networking.k8s.io/v1

kind:  Ingress

metadata:

    name:  example-ingress

    annotations:

        cert-manager.io/cluster-issuer:  "letsencrypt-prod"      #  指定使用生产环境签发器

        kubernetes.io/ingress.class:  "nginx"                                  #  指定  Ingress  Controller

spec:

    tls:

    -  hosts:

        -  example.com

        -  www.example.com

        secretName:  example-com-tls                                                      #  Cert-Manager  会自动创建此  Secret

    rules:

    -  host:  example.com

        http:

            paths:

            -  path:  /

                pathType:  Prefix

                backend:

                    service:

                        name:  example-service

                        port:

                            number:  80

应用  Ingress  后,Cert-Manager  会自动检测到  `cert-manager.io/cluster-issuer`  注解,在几分钟内完成证书申请、验证并创建  `Secret`。

方式二:通过  Certificate  资源管理证书

对于复杂场景(如多  Ingress  共用同一证书),可以显式创建  Certificate  资源:

yaml

apiVersion:  cert-manager.io/v1

kind:  Certificate

metadata:

    name:  example-com-cert

    namespace:  default

spec:

    secretName:  example-com-tls

    issuerRef:

        name:  letsencrypt-prod

        kind:  ClusterIssuer

    dnsNames:

    -  example.com

    -  www.example.com

然后在  Ingress  中直接引用该  Secret:

yaml

spec:

    tls:

    -  hosts:

        -  example.com

        -  www.example.com

        secretName:  example-com-tls

四、自动续期机制

Cert-Manager  会主动监控已颁发证书的过期时间。对于  Let's  Encrypt  的  90  天证书,Cert-Manager  默认在到期前  30  天自动发起续期请求,无需任何人工干预。

你可以通过以下命令查看证书状态和续期历史:

bash

kubectl  get  certificate  -A

kubectl  describe  certificate  example-com-cert

五、验证  HTTPS  配置

1.    检查  Certificate  资源状态:

        bash

        kubectl  get  certificate  -A

        kubectl  describe  certificate  example-com-cert

                正常状态下,`READY`  列应为  `True`,`AGE`  列会显示证书创建时间。

2.    检查  Secret  是否成功创建:

        bash

        kubectl  get  secret  example-com-tls  -o  yaml

        应看到  `tls.crt`  和  `tls.key`  字段。

3.    测试  HTTPS  访问:

        bash

        curl  -v  https://example.com

        应返回证书信息及  HTTP  200  状态码。也可以使用浏览器访问  `https://example.com`,确认地址栏出现安全锁标志。

五、备选方案:轻量级替代工具

如果  Cert-Manager  对你来说过于复杂,可以考虑以下轻量级替代品:

工具      特点    适用场景  

KCert      配置精简,只需约  100  行  YAML,整个程序轻量部署  |  小型项目、边缘集群  

Go  原生替代品          仅  23KB  二进制,支持  ACME  +  私有  CA  +  Secret  自动轮转      资源受限的边缘设备  

六、常见问题与解决方案

问题现象        可能原因    解决方案  

`kubectl  get  certificate`  显示  `READY=False`      Ingress  中指定的  `secretName`  与  Certificate  不一致;域名  DNS  未正确解析到  Ingress  IP      检查  Secret  名称一致性;确保域名  A  记录已指向  LoadBalancer  IP  

Cert-Manager  日志报  `acme:  error:  429`      Let's  Encrypt  速率限制(Staging  环境每域名每小时  5  次失败尝试)      切换至  Staging  环境调试,或等待限制解除  

HTTP-01  挑战失败(`/.well-known/acme-challenge/`  无法访问)      Ingress  Controller  强制  HTTP→HTTPS  重定向,导致验证请求被拦截      为  Ingress  添加注解  `nginx.ingress.kubernetes.io/ssl-redirect:  "false"`  临时放行  

Ingress  未自动获取证书      未添加  `cert-manager.io/cluster-issuer`  注解      在  Ingress  的  `metadata.annotations`  中添加正确注解  

Ingress  Controller  IngressClass  不匹配      ClusterIssuer  中  `ingress.class`  与实际不符      通过  `kubectl  get  ingressclass`  确认正确的  IngressClass,并同步配置  

七、生产环境最佳实践

先  Staging  后  Production:务必先在  Let's  Encrypt  Staging  环境验证所有配置,避免触发生产环境的速率限制。

监控证书状态:通过  Prometheus  +  Alertmanager  监控  `cert-manager`  的指标,及时获知证书申请或续期失败的情况。

HTTP  强转  HTTPS:在  Ingress  中添加注解  `nginx.ingress.kubernetes.io/ssl-redirect:  "true"`,将所有  HTTP  流量永久重定向至  HTTPS。

启用  HSTS:在  Ingress  中添加注解  `nginx.ingress.kubernetes.io/hsts:  "true"`,强制浏览器在未来一段时间内仅使用  HTTPS  访问。

定期备份:定期备份  Certificate  和  Secret  资源,避免集群故障导致证书丢失。

通过上述配置,你的  Kubernetes  Ingress  即可实现  SSL证书的全自动管理,告别手动续期的繁琐与风险。如果你在实施过程中遇到具体问题,欢迎随时提出,我们可以一起排查!