告别证书噩梦:Kubernetes下百个微服务Let's Encrypt自动化之道
在微服务架构盛行的今天,将应用容器化并部署到Kubernetes已是常态。但当服务的数量从个位数膨胀到上百个,并且每个服务都拥有独立的域名,运维的复杂度会呈几何级数增长。其中,“证书管理”无疑是许多DevOps工程师心中的一道坎,尤其是在使用免费、短期有效的Let's Encrypt证书时。
想象一下:每个月都要手动为上百个域名申请或续期证书,填表、验证、部署,这些重复性工作不仅效率低下,而且极易出错。一个不留神,证书过期,线上服务瞬间宕机,这简直是运维人员的噩梦。那么,有没有一种高效、可靠,并且能与现有CI/CD流程无缝集成的自动化方案呢?答案是肯定的:Cert-Manager。
为什么手动管理Let's Encrypt证书是噩梦?
- 规模化挑战: 随着微服务数量增多,手动操作的耗时与出错率急剧上升。
- 续期频率: Let's Encrypt证书通常只有90天有效期,意味着你每隔几个月就得进行一轮“证书大扫除”。
- 人为错误: 证书配置错误、密钥泄露风险、忘记续期等,都可能导致生产事故。
- 运维负担: 大量精力被消耗在重复性劳动上,无法专注于更有价值的系统优化工作。
- CI/CD集成难: 手动流程难以融入自动化部署管道,形成瓶颈。
Cert-Manager:Kubernetes上的证书自动化专家
Cert-Manager是一个强大的Kubernetes附加组件,它能自动为您的Kubernetes服务颁发和管理X.509证书。它支持多种证书颁发机构(CA),包括Let's Encrypt,并能自动处理证书的生命周期,从申请、验证到续期,全程无需人工干预。
Cert-Manager的核心优势:
- 全生命周期管理: 自动申请、续期和撤销证书。
- 多CA支持: 不仅支持Let's Encrypt,还支持Vault、ACME、Venafi等。
- Kubernetes原生集成: 以CRD(Custom Resource Definitions)的方式与Kubernetes深度融合,使用Kubernetes API来管理证书资源。
- 多种验证方式: 支持HTTP-01和DNS-01挑战,适应不同场景。
- 高可靠性: 自动重试机制,确保证书顺利颁发。
Cert-Manager工作原理简述
Cert-Manager通过监控Kubernetes集群中的自定义资源(CRD)来工作,主要涉及以下几个核心概念:
Issuer或ClusterIssuer: 定义证书的颁发机构和验证方式。Issuer作用于特定命名空间,ClusterIssuer作用于整个集群。通常,我们为了Let's Encrypt的方便,会使用ClusterIssuer。Certificate: 定义你想要获取的证书的细节,比如域名、私钥算法、以及引用的Issuer或ClusterIssuer。Order和Challenge: 当Certificate被创建后,Cert-Manager会为它创建一个Order资源,并根据Issuer的配置发起一个或多个ACMEChallenge(如HTTP-01或DNS-01),以证明您对域名的所有权。Secret: 证书颁发成功后,Cert-Manager会将私钥和证书链存储在一个KubernetesSecret中,供Ingress控制器或其他服务引用。
部署和配置Cert-Manager
以下是一个基于Helm的快速部署和配置Cert-Manager的示例。
1. 安装Cert-Manager
首先,确保你的Kubernetes集群版本支持Cert-Manager,并添加其Helm仓库:
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.13.2 \
--set installCRDs=true # 关键:确保CRD被安装
等待Pod启动并运行正常。
2. 配置ClusterIssuer(以Let's Encrypt DNS-01为例)
对于大量域名管理,DNS-01挑战是首选,因为它支持通配符证书(*.example.com)且不需要服务暴露在公网。这里以Cloudflare作为DNS提供商为例,您需要先获取Cloudflare API Token。
创建一个名为letsencrypt-prod-dns.yaml的文件:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod-dns
spec:
acme:
email: your-email@example.com # 替换为您的邮箱,用于接收通知
server: https://acme-v02.api.letsencrypt.org/directory # 生产环境
privateKeySecretRef:
name: letsencrypt-prod-dns-key
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token-secret # 引用包含Cloudflare API Token的Secret
key: api-token # Secret中存储API Token的key
创建Cloudflare API Token Secret:
kubectl create secret generic cloudflare-api-token-secret \
--from-literal=api-token='YOUR_CLOUDFLARE_API_TOKEN' \
--namespace cert-manager # 或您部署Cert-Manager的命名空间
注意: 确保这个Secret存在于Cert-Manager能够访问的命名空间。
应用ClusterIssuer:
kubectl apply -f letsencrypt-prod-dns.yaml
验证ClusterIssuer状态:
kubectl get clusterissuer letsencrypt-prod-dns -o yaml
您应该看到Status.Conditions中Ready为True。
3. 创建Certificate资源并与Ingress集成
现在,您可以通过定义Certificate资源来请求证书。最常见的方式是与Ingress资源结合使用,让Ingress控制器(如Nginx Ingress)自动使用颁发的证书。
假设你有一个名为my-service的微服务,需要为api.example.com和www.example.com这两个域名申请证书。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-service-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod-dns # 引用之前创建的ClusterIssuer
spec:
tls:
- hosts:
- api.example.com
- www.example.com
secretName: my-service-tls-secret # 证书颁发后将存储在此Secret中
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service-frontend
port:
number: 80
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: my-service-cert
namespace: default # 证书所属的命名空间
spec:
secretName: my-service-tls-secret # 必须与Ingress中定义的secretName一致
dnsNames:
- api.example.com
- www.example.com
issuerRef:
name: letsencrypt-prod-dns
kind: ClusterIssuer
当这个Ingress和Certificate资源被创建后,Cert-Manager会自动:
- 检测到新的
Certificate资源。 - 向Let's Encrypt发起证书请求。
- 通过DNS-01挑战验证域名所有权。
- 获取证书,并将其存储在
my-service-tls-secret这个Secret中。 - Nginx Ingress控制器会自动发现并使用这个Secret中的证书。
- 在证书即将过期时,Cert-Manager会自动触发续期流程。
4. 与CI/CD流水线集成
将Cert-Manager融入CI/CD非常简单:
- GitOps实践: 将
ClusterIssuer、Certificate和Ingress等所有Kubernetes资源定义存储在Git仓库中。 - 自动化部署: 您的CI/CD流水线只需负责将这些YAML文件通过
kubectl apply -f或Argo CD/Flux CD等工具部署到Kubernetes集群。Cert-Manager会检测到这些资源并自动处理证书。
这样,证书管理就完全自动化了,不再需要人工干预,大大减轻了运维负担。
总结
Cert-Manager彻底解决了Kubernetes微服务环境下Let's Encrypt证书管理的“噩梦”。通过将证书生命周期管理交给一个专业的自动化工具,我们不仅能够显著提高运维效率,减少人为错误,还能确保服务始终运行在安全、可靠的HTTPS连接上,避免因证书过期导致的任何业务中断。对于部署了上百个微服务的团队而言,拥抱Cert-Manager,是提升生产力、保障系统稳定性的必由之路。