cert-manager + Let‘s Encrypt + DNS 實現基於K8S的https證書自動簽發

StarsL發表於2024-11-03

原理

  1. 建立ClusterIssuer或者Issuer資源用於建立頒發者,決定cert-manager簽發證書的方式,然後會在cert-manager上的namespace下生成該頒發者的secret用於證書申請的準備。

  2. 透過建立Certificate資源來告知cert-manager :在哪個namespace生成證書、需要簽發的域名的證書名稱,域名對應的secret資源,以及的引用ClusterIssuer或者Issuer資源等等資訊。

  3. cert-manager拿著建立好的Certificate資源與ClusterIssuer或者Issuer資源的secret透過內部或外部的webhook向所支援的域名服務提供商對域名進行解析,這裡會發起certificaterequests與challenges動作。

  4. 解析透過acme校驗後將證書返回至cert-manager,certificatere對應項會變成True驗證透過狀態,再將證書轉換到對應namespace下的secret資源做證書引用準備。

  5. 在Ingress-controller上生成ingress資源引用該證書secret即可實現https可信訪問。

部署cert-manager

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.yaml

匯入阿里雲的AKSK(管理DNS的許可權)

apiVersion: v1
kind: Secret
metadata:
  name: alidns-secret
  namespace: cert-manager
stringData:
  access-key-id: "Your Access Key Id"
  access-key-secret: "Your Access Key Secret"

部署alidns-webhook

K8S v1.30.4 + cert-manager v1.15.3 測試證書籤發成功

# alidns-webhook 倉庫
# https://github.com/wjiec/alidns-webhook

helm upgrade --install alidns-webhook alidns-webhook \
    --repo https://wjiec.github.io/alidns-webhook \
    --namespace cert-manager --create-namespace \
    --set groupName=acme.yourcompany.com
# groupName=設定成你的名稱(可以不是申請證書的域名)

# 部署後更換國內映象
# registry.cn-shenzhen.aliyuncs.com/starsl/alidns-webhook:v1.0.0

建立CA證書頒發者

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: example-acme
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your@aaabbbccc.com # 填寫郵箱名稱
    privateKeySecretRef:
      name: example-acme # 用於儲存 ACME 帳戶私鑰的金鑰名稱(可自定義名稱)
    solvers:
      - dns01:
          webhook:
            groupName: acme.yourcompany.com # 要和安裝的時候配置的groupName一致
            solverName: alidns
            config:
              region: "cn-hangzhou" # 不用修改
              accessKeyIdRef:
                name: alidns-secret
                key: access-key-id
              accessKeySecretRef:
                name: alidns-secret
                key: access-key-secret

建立證書

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: star-example-com
  namespace: cert-manager
spec:
  secretName: star-example-com-tls #生成證書檔案的名稱
  dnsNames: # 需要簽發證書的域名
  - "example.com" 
  - "*.example.com"
  issuerRef:
    name: example-acme # 上一步生成的ClusterIssuer的名稱
    kind: ClusterIssuer

建立Certificate後,cert-manager與alidns-webhook開始進行證書籤發工作:

  • alidns-webhook使用AKSK去請求阿里的DNS域名解析介面去進行解析記錄操作。
  • 檢查建立的certificate資源,狀態變為True表示證書已經簽發成功。
  • 檢視secret資源,生成的star-example-com-tls即為證書檔案。

從ingress自動生成證書

kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: foo-example-com
  annotations:
    cert-manager.io/cluster-issuer: "example-acme" # 增加該行即可自動生成證書
spec:
  tls:
  - hosts:
    - foo.example.com
    secretName: foo-example-com-tls
  rules:
  - host: foo.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: backend-service
            port:
              name: http

相關文章