内网kubernetes+cloudflare+cert-Manager自动签发证书

这个场景非常的有意思:

公司内部有若干个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就足够了

image-20250709104459501

然后获得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

CORS跨域在不同环境中的配置
comments powered by Disqus