目标:用你现有的 step PKI(root CA + intermediate CA),让集群里任何服务都能
自动获得 HTTPS 证书并自动续期。以后新增服务 = 复制一份 Ingress 即可。

准备环境,harbor、dnsmaqs 等。

一、安装 cert-manager

1
2
3
4
5
6
7
8
9
10
11
12
13
helm repo add jetstack https://charts.jetstack.io
helm repo update jetstack

# 查最新版本(可选)
helm search repo cert-manager --versions | head

helm install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace \
--version v1.20.2 \
--set crds.enabled=true # 注意:新版是 crds.enabled,不是旧的 installCRDs

# 三个 pod 都 Running 才算好:controller / webhook / cainjector
kubectl get pods -n cert-manager

二、中间 CA 交给 cert-manager

cert-manager 的 CA Issuer 需要一个含「证书 + 私钥」的 secret。
ClusterIssuer 引用的 secret 必须放在 cert-manager 所在命名空间(默认 cert-manager)。

1
2
3
4
5
6
7
cd ~/qx-ca

# 用中间 CA 的证书 + 私钥建一个 tls 类型的 secret
kubectl create secret tls qx-intermediate-ca \
--namespace cert-manager \
--cert=intermediate_ca.crt \
--key=intermediate_ca.key

建 ClusterIssuer:

1
2
3
4
5
6
7
8
# clusterissuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: qx-ca-issuer
spec:
ca:
secretName: qx-intermediate-ca
1
2
kubectl apply -f clusterissuer.yaml
kubectl get clusterissuer qx-ca-issuer # READY 应为 True

链的原理:cert-manager 用中间 CA 签出来的叶子证书,secret 里的 tls.crt
会是「leaf + 中间CA」的链;客户端信任 root 即可验通(leaf→中间→root)。

⚠️ 安全提醒:把中间 CA 的私钥放进集群,意味着能拿到这个 secret 的人都能用你的 CA 签证书。
lab 环境没问题;生产建议用一张「专供集群」的独立中间 CA,或改用 step-ca server + ACME 让私钥不出 CA。

三、安装 Traefik

  1. 添加仓库并更新
1
2
helm repo add traefik https://traefik.github.io/charts
helm repo update traefik
  1. 准备 values:
1
vim traefik-values.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
# traefik-values.yaml
ingressClass:
enabled: true
isDefaultClass: true # 设为默认 ingressClass,Ingress 不写 class 也走 Traefik

api:
dashboard: true # 打开 dashboard(下一步用我们自己的 IngressRoute 暴露它)

ingressRoute:
dashboard:
enabled: false # 关掉自带的 dashboard 路由,避免和我们带 TLS 的那个冲突

# service 默认就是 LoadBalancer 类型,会自动向 MetalLB 要一个 IP
  1. 安装
1
2
3
4
5
6
helm install traefik traefik/traefik \
--namespace traefik --create-namespace \
-f traefik-values.yaml

# 看 Traefik 是否拿到了 MetalLB 分的 IP(记下 EXTERNAL-IP)
kubectl get svc -n traefik traefik

四、暴露Traefik dashboard

先让 cert-manager 给 dashboard 签一张证书:

  1. 编辑资源清单文件
1
vim dashboard-cert.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
# dashboard-cert.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: traefik-dashboard
namespace: traefik
spec:
secretName: traefik-dashboard-tls # cert-manager 会自动创建这个 secret
dnsNames:
- traefik.qx.lab
issuerRef:
name: qx-ca-issuer
kind: ClusterIssuer
  1. 再建一个 IngressRoute,把 dashboard(api@internal)挂到 443 + 这张证书:
1
vim dashboard-route.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# dashboard-route.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: traefik
spec:
entryPoints:
- websecure
routes:
- match: Host(`traefik.qx.lab`)
kind: Rule
services:
- name: api@internal
kind: TraefikService
tls:
secretName: traefik-dashboard-tls
  1. 创建资源并验证
1
2
kubectl apply -f dashboard-cert.yaml -f dashboard-route.yaml
kubectl get certificate -n traefik # traefik-dashboard 应 READY=True
  1. 访问验证

https://traefik.qx.lab

五、部署 whoami 示例服务

  1. 编辑资源清单文件
1
vim whoami.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# whoami.yaml
apiVersion: v1
kind: Namespace
metadata:
name: demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: demo
spec:
replicas: 1
selector:
matchLabels: { app: whoami }
template:
metadata:
labels: { app: whoami }
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: demo
spec:
selector: { app: whoami }
ports:
- port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whoami
namespace: demo
annotations:
cert-manager.io/cluster-issuer: qx-ca-issuer # ★ 这一行让 cert-manager 自动签证书
spec:
ingressClassName: traefik
tls:
- hosts:
- whoami.qx.lab
secretName: whoami-tls # ★ cert-manager 自动创建并填充
rules:
- host: whoami.qx.lab
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: whoami
port:
number: 80
  1. 创建资源并验证
1
2
kubectl apply -f whoami.yaml
kubectl get certificate -n demo # whoami-tls 应 READY=True
  1. 浏览器访问

https://whoami.qx.lab