Kubernetes证书管理与cert-manager深度实战:从Let-s-Encrypt到内部CA与mTLS的自动化证书全解
Kubernetes证书管理与cert-manager深度实战:从Let-s-Encrypt到内部CA与mTLS的自动化证书全解析
引言
TLS证书是云原生安全的基石——API Server通信、Ingress入口加密、服务间mTLS、代码签名都依赖证书。但证书管理曾是一个巨大的运维负担——申请、签发、分发、续期、吊销每个环节都需人工操作,证书过期导致的服务中断是常见事故。cert-manager作为K8s原生证书管理方案,将证书生命周期完全自动化——Let’s Encrypt集成实现公网证书自动签发,内部CA实现服务间mTLS自动签发,到期前自动续期。本文从证书基础出发,系统性地讲解PKI体系、cert-manager安装、Let’s Encrypt集成、内部CA、mTLS签发、证书监控与告警,通过大量可运行配置帮助读者实现零运维的证书管理。
一、PKI基础
# PKI(Public Key Infrastructure)核心概念
#
# CA(Certificate Authority):
# 根证书颁发机构,签发其他证书
# 自签名根CA → 中间CA → 终端证书
#
# 证书类型:
# 公网证书:Let's Encrypt/ZeroSSL(需要域名验证)
# 内部证书:自建CA(用于mTLS)
# 通配符证书:*.example.com
#
# 证书格式:
# PEM(Base64编码,最常见)
# DER(二进制,Java常用)
# PKCS12(.p12,Windows常用)
#
# 续期策略:
# Let's Encrypt:90天有效期,到期前30天自动续期
# 内部CA:可自定义有效期(通常1-2年)
# 最佳实践:有效期<90天(即使泄露影响有限)
二、cert-manager安装
2.1 Helm安装
#!/bin/bash
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace \
--set installCRDs=true \
--set global.leaderElection.namespace=cert-manager \
--set replicaCount=2 \
--set podDisruptionBudget.enabled=true \
--set podDisruptionBudget.minAvailable=1 \
--set resources.requests.cpu=50m \
--set resources.requests.memory=128Mi
# 验证
kubectl get pods -n cert-manager
kubectl get crd | grep cert-manager
三、Let’s Encrypt集成
3.1 HTTP-01验证
# ClusterIssuer:Let's Encrypt生产环境
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
# HTTP-01验证(通过Ingress暴露验证文件)
- http01:
ingress:
class: nginx
# 或使用Gateway API
# ingressTemplate:
# annotations:
# external-dns.alpha.kubernetes.io/ttl: "60"
---
# 证书申请
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-tls
namespace: production
spec:
secretName: api-tls
duration: 2160h # 90天
renewBefore: 360h # 提前15天续期
subject:
organizations:
- My Company
commonName: api.example.com
dnsNames:
- api.example.com
- www.api.example.com
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
---
# Ingress自动证书
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
namespace: production
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- api.example.com
secretName: api-tls
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
3.2 DNS-01验证(通配符证书)
# DNS-01验证:通过DNS TXT记录验证域名所有权
# 适用于通配符证书和内网证书
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-dns
solvers:
# Route53 DNS验证
- dns01:
route53:
region: us-east-1
hostedZoneID: Z123ABC
accessKeyID: AKIAXXX
secretAccessKeySecretRef:
name: route53-credentials
key: secret-access-key
# Cloudflare DNS验证
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-token
key: token
---
# 通配符证书
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard-cert
namespace: production
spec:
secretName: wildcard-tls
dnsNames:
- "*.example.com"
- "example.com"
issuerRef:
name: letsencrypt-dns
kind: ClusterIssuer
四、内部CA
4.1 自建CA
# 自签名根CA
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: root-ca
namespace: cert-manager
spec:
isCA: true
commonName: "My Organization Root CA"
subject:
organizations: ["My Organization"]
organizationalUnits: ["CA"]
countries: ["CN"]
secretName: root-ca-tls
duration: 87600h # 10年
renewBefore: 720h
privateKey:
algorithm: RSA
size: 4096
rotationPolicy: Always
usages:
- certsign
- crlsign
issuerRef:
name: self-signed
kind: ClusterIssuer
---
# 从根CA签发中间CA
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: intermediate-ca
namespace: cert-manager
spec:
ca:
secretName: root-ca-tls
---
# 从中间CA签发终端证书
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: internal-service
namespace: production
spec:
secretName: internal-service-tls
commonName: internal-service.production.svc.cluster.local
dnsNames:
- internal-service.production.svc
- internal-service.production.svc.cluster.local
duration: 720h # 30天
renewBefore: 168h # 提前7天续期
privateKey:
algorithm: ECDSA
size: 256
rotationPolicy: Always
usages:
- serverauth
- clientauth
issuerRef:
name: intermediate-ca
kind: Issuer
五、mTLS自动化
5.1 Istio集成
# cert-manager + Istio实现自定义mTLS
# 默认Istio使用自签CA
# 生产环境可以用cert-manager管理
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: istio-ca
namespace: istio-system
spec:
secretName: istio-ca-secret
isCA: true
commonName: "Istio CA"
duration: 720h
renewBefore: 168h
privateKey:
algorithm: RSA
size: 2048
issuerRef:
name: intermediate-ca
kind: Issuer
# Istio CA注解
keystores:
jks:
create: true
passwordSecretRef:
name: istio-keystore-password
key: password
---
# Istio配置使用外部CA
apiVersion: istio.io/v1alpha1
kind: IstioOperator
metadata:
name: external-ca
spec:
meshConfig:
ca:
address: cert-manager.cert-manager.svc:443
# 或使用Vault
# ca:
# address: vault.vault.svc:8200
5.2 Pod级mTLS证书注入
# CSI Driver:将证书以卷方式挂载到Pod
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: service-mtls
namespace: production
spec:
secretName: service-mtls
commonName: my-service.production.svc
dnsNames:
- my-service.production.svc.cluster.local
issuerRef:
name: intermediate-ca
kind: Issuer
---
# Pod挂载证书
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service
namespace: production
spec:
template:
spec:
containers:
- name: service
image: service:v1.0
volumeMounts:
- name: tls
mountPath: /etc/tls
readOnly: true
env:
- name: TLS_CERT
value: /etc/tls/tls.crt
- name: TLS_KEY
value: /etc/tls/tls.key
- name: CA_CERT
value: /etc/tls/ca.crt
volumes:
- name: tls
csi:
driver: cert-manager.io
readOnly: true
volumeAttributes:
certificate-name: service-mtls
六、证书监控与告警
# Prometheus告警规则
groups:
- name: certificate-alerts
rules:
- alert: CertExpiringSoon
expr: |
certmanager_certificate_expiration_timestamp_seconds
- time() < 86400 * 7
for: 1h
labels:
severity: warning
annotations:
summary: "证书 {{ $labels.name }} 将在7天内过期"
- alert: CertFailed
expr: certmanager_certificate_ready_status == 0
for: 10m
labels:
severity: critical
annotations:
summary: "证书签发失败: {{ $labels.name }}"
description: "{{ $labels.namespace }}/{{ $labels.name }}"
七、总结
cert-manager将TLS证书管理从运维负担变成了零运维的自动化流程。Let’s Encrypt集成让公网证书免费且自动续期——90天有效期+到期前15天自动续期确保了证书安全性和可用性的平衡。HTTP-01验证适用于标准Ingress场景,DNS-01验证适用于通配符证书和内网证书。内部CA实现服务间mTLS的自动化签发——自签名根CA签发中间CA,中间CA签发终端证书,证书作为K8s Secret自动分发到Pod。Istio集成可以用cert-manager替代默认的自签CA,实现更规范的证书管理。CSI Driver将证书以卷方式挂载到Pod,应用直接读取文件而无需修改代码。证书监控通过Prometheus指标实现——certmanager_certificate_expiration_timestamp_seconds可以精准监控过期时间,配合Alertmanager在到期前7天告警。生产证书管理的核心原则:有效期不超过90天(减少泄露风险)、自动续期而非人工操作、内部服务使用ECDSA(比RSA更快更小)、根CA离线存储(中间CA签发终端证书)、证书使用范围最小化(每个服务独立证书)。cert-manager不是可选项而是K8s生产环境的基础设施——没有它,证书过期导致的服务中断只是时间问题。
- 点赞
- 收藏
- 关注作者
评论(0)