这个场景非常的有意思:
公司内部有若干个kubernetes集群,属于测试环境,研发搭建了一套SAAS的环境,这个环境需要xxx.abc.com的域名来访问,域名解析记录全都是192.168.0.x,供内部访问,域名会动态生成,需要证书也随之生成,且dns域名托管在cloudflare上。
基本环境如上,麻烦的是 cert-manager 不可能签发私网的证书,只能曲线救国,用dns验证的方式来签发证书了,如果配上 external-dns,那dns解析也不用做了;只要发布一个ingress,就直接生成dns解析记录和对应的https证书。
具体做法如下:
一、配置 cloudflare API token
登录cloudflare,去生成API Token,路径是:User Profile > API Tokens > API Tokens.
-
Permissions:
-
Zone - DNS - Edit
-
Zone Resources:
Include - All Zones
cert-manager的官方文档居然是错的,https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/
推荐的 Zone - Zone - Read 是加不上的,有Edit就足够了
然后获得Token的字符串xxxxxx
二、安装cert-manager
这个简单,直接用helm安装
现在这个时间节点,2025.07.09,cert-manager 是 v1.18.2
,所以用新命令执行安装
1helm repo add jetstack https://charts.jetstack.io
2helm repo update
3
4#老版本比如1.0
5helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true
6
7#新版本v1.18.2
8helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set crds.enabled=true
三、准备签发机构Issuer
下面要特别注意,secret必须在namespace:cert-manager中,因为上一步我们创建了ns cert-manager,pod也在这个ns中,签发的过程中是由cert-manager中的pod发起请求的
1# secret
2---
3apiVersion: v1
4kind: Secret
5metadata:
6 name: cloudflare-api-token-secret
7 namespace: cert-manager
8type: Opaque
9stringData:
10 api-token: xxxxxxxx
11# Issuer
12---
13apiVersion: cert-manager.io/v1
14kind: ClusterIssuer
15metadata:
16 name: letsencrypt-prod
17spec:
18 acme:
19 server: https://acme-v02.api.letsencrypt.org/directory
20 email: zhangranrui@gmail.com
21 privateKeySecretRef:
22 name: letsencrypt-prod
23 solvers:
24 - dns01:
25 cloudflare:
26 email: zhangranrui@gmail.com
27 apiTokenSecretRef:
28 name: cloudflare-api-token-secret
29 key: api-token
四、准备pod和ingress
1# nginx deployment
2---
3apiVersion: apps/v1
4kind: Deployment
5metadata:
6 name: nginx
7 labels:
8 app: nginx
9spec:
10 replicas: 1
11 selector:
12 matchLabels:
13 app: nginx
14 template:
15 metadata:
16 labels:
17 app: nginx
18 spec:
19 containers:
20 - name: nginx
21 image: nginx:latest
22 ports:
23 - containerPort: 80
24---
25# nginx Service
26apiVersion: v1
27kind: Service
28metadata:
29 name: nginx
30spec:
31 selector:
32 app: nginx
33 ports:
34 - protocol: TCP
35 port: 80
36 targetPort: 80
37 type: ClusterIP
然后我们直接发布一个ingress,就会自动签发证书了
1---
2apiVersion: networking.k8s.io/v1
3kind: Ingress
4metadata:
5 name: test-ingress
6 annotations:
7 cert-manager.io/cluster-issuer: "letsencrypt-prod"
8spec:
9 tls:
10 - hosts:
11 - test.abc.com
12 secretName: test-tls
13 rules:
14 - host: test.abc.com
15 http:
16 paths:
17 - path: /
18 pathType: Prefix
19 backend:
20 service:
21 name: nginx
22 port:
23 number: 80
四、一些调试命令:
1$ kubectl get issuer
2$ kubectl get clusterissuer
3$ kubectl get challenges
4$ kubectl describe challenge
5$ kubectl describe certificaterequest
6$ kubectl describe order