跳至主要内容

Cert-Manager 與 Let's Encrypt 整合使用手冊

巴尼巴比人

本手冊介紹如何使用 cert-manager 自動申請 Let's Encrypt TLS 憑證,並將其應用於 sample.org 網域的 Kubernetes Ingress。


1. 簡介

巴尼巴比人

Cert-Manager 能夠自動為 Kubernetes Ingress 申請與續期 TLS 憑證。本手冊示範完整流程:

  • 使用 Helm 安裝 Cert-Manager
  • 建立 Let's Encrypt ClusterIssuer
  • 在 Ingress 上自動申請 HTTPS 憑證
  • 建立 wildcard 憑證 (*.sample.org)
  • Rancher Ingress 使用 wildcard 憑證
  • 自動同步跨命名空間的 TLS Secret

2. 使用 Helm Chart 安裝 Cert-Manager

巴尼巴比人

2.1 建立 cert-manager/Chart.yaml

apiVersion: v2
name: cert-manager
version: 1.0.0
dependencies:
- name: cert-manager
version: v1.17.0
repository: https://charts.jetstack.io
condition: cert-manager.enabled

2.2 建立 values.yaml

cert-manager:
enabled: true
installCRDs: true

2.3 安裝 Cert-Manager

helm repo add jetstack https://charts.jetstack.io
helm repo update
helm dependency update cert-manager/
helm install cert-manager ./ -n cert-manager --create-namespace

2.4 確認 Cert-Manager 運行狀態

kubectl get pods -n cert-manager

成功時應出現:

cert-manager-xxxxxxx
cert-manager-cainjector-xxxxxxx
cert-manager-webhook-xxxxxxx

3. 設定 Let's Encrypt ClusterIssuer

巴尼巴比人

3.1 建立 cert-manager/issuer.yaml

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: your-email@sample.org
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx

3.2 套用 ClusterIssuer

kubectl apply -f cert-manager/issuer.yaml

4. 配置 Ingress 並申請 TLS 憑證

巴尼巴比人

4.1 建立 cert-manager/ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: sample-ingress
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
acme.cert-manager.io/http01-edit-in-place: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- sample.org
- www.sample.org
secretName: wildcard-sample-clm5l
rules:
- host: sample.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80
- host: www.sample.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80

4.2 套用 Ingress

kubectl apply -f cert-manager/ingress.yaml

5. 驗證憑證申請狀態

巴尼巴比人

5.1 檢查 Certificate

kubectl get certificate -A

5.2 檢查 Challenge(如憑證未成功)

kubectl get challenge -A
kubectl describe challenge -n cert-manager

6. 使用泛域名 (Wildcard) 憑證

巴尼巴比人

6.1 建立 cert-manager/certificate-wildcard.yaml

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard-sample
namespace: default
spec:
secretName: wildcard-sample-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: "*.sample.org"
dnsNames:
- "*.sample.org"
- "sample.org"

6.2 申請憑證

kubectl apply -f cert-manager/certificate-wildcard.yaml

7. Rancher Ingress 使用泛域名 TLS 憑證

巴尼巴比人

Kubernetes Ingress 不能跨 namespace 使用 Secret

因此要將 wildcard-sample-tls 複製至 cattle-system

kubectl get secret wildcard-sample-tls -n default -o yaml | sed 's/namespace: default/namespace: cattle-system/' | kubectl apply -f -

7.1 設定 Rancher Ingress

建立 cert-manager/rancher-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rancher
namespace: cattle-system
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- "rancher.sample.org"
secretName: wildcard-sample-tls
rules:
- host: rancher.sample.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rancher
port:
number: 80

8. 自動同步 Secret(可選)

巴尼巴比人

8.1 建立 CronJob

cert-manager/sync-secret-cronjob.yaml

apiVersion: batch/v1
kind: CronJob
metadata:
name: sync-wildcard-tls
namespace: cattle-system
spec:
schedule: "0 */6 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: sync-secret
image: bitnami/kubectl
command:
- /bin/sh
- -c
- |
kubectl get secret wildcard-sample-tls -n default -o yaml | sed 's/namespace: default/namespace: cattle-system/' | kubectl apply -f -
restartPolicy: OnFailure

9. 診斷與錯誤排除

巴尼巴比人

問題 1:找不到 cert-manager 目錄

→ Chart.yaml 不在 cert-manager/ 下
→ cd 進去後執行安裝

問題 2:CRD 已存在

解決方法:

kubectl delete crd certificaterequests.cert-manager.io   certificates.cert-manager.io   clusterissuers.cert-manager.io   issuers.cert-manager.io   challenges.acme.cert-manager.io   orders.acme.cert-manager.io

再重新安裝:

helm install cert-manager . -n cert-manager --create-namespace --set installCRDs=true

問題 3:Helm metadata 缺失

→ 補上 Helm annotation:

kubectl annotate crd certificaterequests.cert-manager.io   meta.helm.sh/release-name=cert-manager   meta.helm.sh/release-namespace=cert-manager

10. 結論

巴尼巴比人

你現在已成功:

  • 安裝 cert-manager
  • 建立 Let's Encrypt ClusterIssuer
  • 自動為 Ingress 簽發 TLS 憑證
  • 建立泛域名 wildcard 憑證
  • Rancher 使用 wildcard TLS
  • 自動同步跨 namespace Secret

你的 Kubernetes 已具備完整、自動化、企業級的 HTTPS 能力。