Kubernetes证书自动续订优雅方案:基于cert-manager的实践指南
在Kubernetes集群中,证书管理是一个至关重要的任务。手动管理证书不仅繁琐,而且容易出错,导致服务中断。为了解决这个问题,我们需要一种能够自动续订证书的优雅方案。cert-manager 就是一个强大的工具,可以帮助我们实现这一目标。
为什么选择 cert-manager?
cert-manager 是一个 Kubernetes 的证书管理控制器,它可以自动地颁发和续订证书。它支持多种证书颁发机构(CA),包括 Let's Encrypt、HashiCorp Vault,以及自签名 CA。cert-manager 的主要优点包括:
- 自动化: 自动完成证书的申请、颁发和续订,无需人工干预。
- 灵活性: 支持多种 CA,可以根据需求选择合适的 CA。
- 易于使用: 通过 Kubernetes 的 CRD(自定义资源定义)进行配置,易于理解和管理。
- 安全性: 安全地存储和管理私钥,防止泄露。
安装 cert-manager
首先,我们需要在 Kubernetes 集群中安装 cert-manager。推荐使用 Helm 进行安装:
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.12.0 \
--set installCRDs=true
请注意,--version 参数指定了 cert-manager 的版本。建议使用最新稳定版本。
安装完成后,可以通过以下命令检查 cert-manager 的状态:
kubectl get pods --namespace cert-manager
确保所有 Pod 都处于 Running 状态。
配置 Issuer
Issuer 是 cert-manager 中的一个 CRD,用于指定证书的颁发者。cert-manager 支持两种类型的 Issuer:Issuer 和 ClusterIssuer。Issuer 只能在指定的命名空间中使用,而 ClusterIssuer 可以被整个集群使用。
使用 Let's Encrypt
Let's Encrypt 是一个免费的、自动化的证书颁发机构。要使用 Let's Encrypt,我们需要创建一个 ClusterIssuer:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: your-email@example.com # 替换为你的邮箱地址
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx # 替换为你的 Ingress Controller
这个 YAML 文件定义了一个名为 letsencrypt-prod 的 ClusterIssuer。spec.acme.email 字段需要替换为你的邮箱地址。spec.acme.server 字段指定了 Let's Encrypt 的 API 地址。spec.acme.privateKeySecretRef.name 字段指定了存储私钥的 Secret 名称。spec.acme.solvers 字段定义了验证域名所有权的方法,这里使用了 http01 挑战,通过 Ingress Controller 进行验证。你需要将 ingress.class 替换为你的 Ingress Controller 的名称,例如 nginx、traefik 等。
创建 ClusterIssuer:
kubectl apply -f cluster-issuer.yaml
使用自签名 CA
如果你想使用自签名 CA,可以创建一个 Issuer:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
namespace: your-namespace # 替换为你的命名空间
spec:
selfSigned: {}
这个 YAML 文件定义了一个名为 selfsigned-issuer 的 Issuer,它使用自签名 CA。你需要将 namespace 替换为你的命名空间。
创建 Issuer:
kubectl apply -f issuer.yaml
创建 Certificate
Certificate 是 cert-manager 中的另一个 CRD,用于定义需要颁发的证书。我们需要创建一个 Certificate,指定要颁发的域名、使用的 Issuer,以及其他配置。
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com
namespace: your-namespace # 替换为你的命名空间
spec:
secretName: example-com-tls
issuerRef:
name: letsencrypt-prod # 替换为你的 Issuer 名称
kind: ClusterIssuer
group: cert-manager.io
dnsNames:
- example.com # 替换为你的域名
- www.example.com # 替换为你的域名
这个 YAML 文件定义了一个名为 example-com 的 Certificate。spec.secretName 字段指定了存储证书和私钥的 Secret 名称。spec.issuerRef.name 字段指定了使用的 Issuer 名称。spec.dnsNames 字段指定了要颁发的域名列表。你需要将 namespace 替换为你的命名空间,将 issuerRef.name 替换为你的 Issuer 名称,将 dnsNames 替换为你的域名。
创建 Certificate:
kubectl apply -f certificate.yaml
cert-manager 会自动向 Let's Encrypt 申请证书,并将证书和私钥存储在名为 example-com-tls 的 Secret 中。你可以通过以下命令查看 Secret 的内容:
kubectl get secret example-com-tls --namespace your-namespace -o yaml
在 Ingress 中使用证书
现在,我们可以在 Ingress 中使用这个证书了。我们需要在 Ingress 的 YAML 文件中指定 tls 字段:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-com
namespace: your-namespace # 替换为你的命名空间
spec:
tls:
- hosts:
- example.com # 替换为你的域名
secretName: example-com-tls
rules:
- host: example.com # 替换为你的域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: your-service # 替换为你的服务名称
port:
number: 80
这个 YAML 文件定义了一个名为 example-com 的 Ingress。spec.tls.hosts 字段指定了域名列表。spec.tls.secretName 字段指定了存储证书和私钥的 Secret 名称。你需要将 namespace 替换为你的命名空间,将 hosts 替换为你的域名,将 secretName 替换为你的 Secret 名称,将 service.name 替换为你的服务名称。
创建 Ingress:
kubectl apply -f ingress.yaml
现在,你可以通过 https://example.com 访问你的服务了。cert-manager 会自动续订证书,确保你的服务始终使用有效的证书。
高级配置
cert-manager 还支持许多高级配置,例如:
- DNS 验证: 使用 DNS 记录验证域名所有权,适用于无法使用
http01挑战的情况。 - Vault 集成: 使用 HashiCorp Vault 作为证书颁发机构。
- Webhook: 使用自定义 Webhook 进行证书颁发和验证。
这些高级配置可以根据你的具体需求进行选择。
总结
使用 cert-manager 可以优雅地实现 Kubernetes 集群中证书的自动续订。它简化了证书管理,提高了安全性,并减少了人工干预。通过本文的介绍,你应该能够开始使用 cert-manager 管理你的 Kubernetes 证书了。记住,选择合适的 Issuer 类型,正确配置 Certificate,并在 Ingress 中使用证书,是实现自动续订的关键。
希望本文能够帮助你更好地理解和使用 cert-manager。祝你使用愉快!