目标:用你现有的 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
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
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
| 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
|
链的原理:cert-manager 用中间 CA 签出来的叶子证书,secret 里的 tls.crt
会是「leaf + 中间CA」的链;客户端信任 root 即可验通(leaf→中间→root)。
⚠️ 安全提醒:把中间 CA 的私钥放进集群,意味着能拿到这个 secret 的人都能用你的 CA 签证书。
lab 环境没问题;生产建议用一张「专供集群」的独立中间 CA,或改用 step-ca server + ACME 让私钥不出 CA。
三、安装 Traefik
- 添加仓库并更新
1 2
| helm repo add traefik https://traefik.github.io/charts helm repo update traefik
|
- 准备 values:
1 2 3 4 5 6 7 8 9 10 11 12 13
| ingressClass: enabled: true isDefaultClass: true
api: dashboard: true
ingressRoute: dashboard: enabled: false
|
- 安装
1 2 3 4 5 6
| helm install traefik traefik/traefik \ --namespace traefik --create-namespace \ -f traefik-values.yaml
kubectl get svc -n traefik traefik
|
四、暴露Traefik dashboard
先让 cert-manager 给 dashboard 签一张证书:
- 编辑资源清单文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: traefik-dashboard namespace: traefik spec: secretName: traefik-dashboard-tls dnsNames: - traefik.qx.lab issuerRef: name: qx-ca-issuer kind: ClusterIssuer
|
- 再建一个 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
| 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 2
| kubectl apply -f dashboard-cert.yaml -f dashboard-route.yaml kubectl get certificate -n traefik
|
- 访问验证
https://traefik.qx.lab
五、部署 whoami 示例服务
- 编辑资源清单文件
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
| 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 spec: ingressClassName: traefik tls: - hosts: - whoami.qx.lab secretName: whoami-tls rules: - host: whoami.qx.lab http: paths: - path: / pathType: Prefix backend: service: name: whoami port: number: 80
|
- 创建资源并验证
1 2
| kubectl apply -f whoami.yaml kubectl get certificate -n demo
|
- 浏览器访问
https://whoami.qx.lab