cert-manager 简介
cert-manager 在 Kubernetes 集群中添加了证书和证书发放者等资源类型,并简化了获取、更新和使用这些证书的过程。
它可以从各种支持的来源,包括 Let's Encrypt、HashiCorp Vault、Venafi 以及私有 PKI 发放证书。
它将确保证书有效且最新,并在到期前在配置的时间尝试续订证书。
它松散地基于 kube-lego 的工作,并从其他类似项目如 kube-cert-manager 中借鉴了一些智慧。
部署
Helm
# 添加 jetstack 仓库
helm repo add jetstack https://charts.jetstack.io
# 更新 helm 仓库信息
helm repo update
# 安装
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.12.0 \
--set installCRDs=true \
--set clusterResourceNamespace=cert-manager
- 需要根据自己的 k8s 版本选择合适的 chart 版本 cert-manager's ArtifactHub page.
- clusterResourceNamespace 后续指定 ClusterIssuers 需要的 secret 所在命名空间
验证安装结果:
kubectl get pod -n cert-manager
看到所有 pod 是运行中状态,说明安装成功了
NAME READY STATUS RESTARTS AGE
cert-manager-55649d64b4-cr74s 1/1 Running 0 1s
cert-manager-cainjector-666db4777-w72pf 1/1 Running 0 1s
cert-manager-webhook-586f966d4d-tmn2m 1/1 Running 0 1s
DNS token 配置
Cloudflare
从 Cloudflare 后台,我的个人资料 -> API 令牌 -> 创建一个 API 令牌,配置适当的权限,此处使用 YOUR_CF_TOKEN 代替。
直接使用命令行创建
kubectl create secret generic --from-literal=api-token=$(YOUR_CF_TOKEN) -n cert-manager cloudflare-api-token-secret
使用 yaml 创建
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
namespace: cert-manager
type: Opaque
stringData:
api-token: YOUR_CF_TOKEN
Issuer 配置
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: cert-manager@example.com # acme需要使用的邮箱,修改为自己的
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token #跟上边secret key对应
这里为了方便直接使用 ClusterIssuer,如果需要更细粒度的控制,需要使用 Issuer
Ingress 配置
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
containers:
- image: docker.io/kong/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: httpbin-service
spec:
selector:
app: httpbin
ports:
- port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
name: abc-example-ingress
labels:
name: abc-example-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- abc.example.com
secretName: abc-example-ingress-cert
rules:
- host: abc.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: example-service
port:
number: 80
验证结果:
kubectl get certificates
等待 READY 状态变成 True
curl https://abc.example.com --resolve abc.example.com:127.0.0.1