Incubator4

Incubator4

github
steam
nintendo switch

Cert-Manager 自動管理證書

前言#

上一篇文章中提到,Traefik 可以實現自動化 HTTPS 加密,其原理是使用 Let’s Encrypt。
然而由於 Traefik 在啟用 LE 時,不僅需要一個 PVC 用於存儲創建的證書,並且由於依賴了 PVC 的緣故,不支持多副本擴容。
所以我們需要一個更優秀的 HTTPS 方案,就是今天我們的主角 Cert-Manager 了。

原理介紹#

Cert Manger 支持多種 HTTPS 方式,包括自簽名 / CA 根證書 / Vault / Venafi / 外部引入 / ACME 的方式。
由於我們需要自動化 HTTPS,所以原理上和上一期一樣,需要使用 ACME 自動化配置 Let's Encrypted。

CertManage 名詞#

Issuer#

Issuer 直接翻譯過來就是頒發者,也就是用來頒發證書的單元。普通的 Issuer 是有命名空間隔離的資源。所以在整個集群中使用的話,需要 ClusterIssuer

Certificate#

Certificate 就是證書的概念了,證書需要引用 Issuer 來頒發證書。
Certificate 引用了一個同命名空間的 Secret (不存在會自動創建) 用來存儲 X509 證書。所以不用擔心證書的存儲問題,它使用了 Kubernetes 原生的方式來存儲證書公私鑰敏感信息。

CertificateRequest#

CertificateRequest 是一個用來記錄證書向 Issuer 請求資源的過程。
在一般情況下,都不需要手動創建,可以通過觀察 CertificateRequest 的狀態來判斷證書的申請結果

安裝 Traefik#

Traefik 安裝可以參考 Traefik Automatic Https

安裝 Cert-Manager#

helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.11.0 \
  --set installCRDs=true

創建 ClusterIssuer#

Issuer 和 ClusterIssuer 一個是命名空間維度的,一個是集群維度的,這裡我們為了方便直接創建 Cluster Issuer

我們使用 Acme 方式,這樣能夠自動簽發證書

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: acme
spec:
  acme:
    email: <your-emaill-address>
    preferredChain: ""
    privateKeySecretRef:
      name: acme-cert-key
    server: https://acme-v02.api.letsencrypt.org/directory
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              key: api-token
              name: cf-nsl-xyz-api-token

給 Ingress/IngressRoutes/GatewayAPI 簽發證書#

對於 Ingress 和 GatewayAPI 而言, Cert-Manager 已經做了集成,所以我們只需要在資源上添加註解即可,如下所示:

Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    # add an annotation indicating the issuer to use.
    cert-manager.io/cluster-issuer: nameOfClusterIssuer
  name: myIngress
  namespace: myIngress
spec:
  rules:
    - host: example.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: myservice
                port:
                  number: 80
  tls: # < placing a host in the TLS config will determine what ends up in the cert's subjectAltNames
    - hosts:
        - example.com
      secretName: myingress-cert # < cert-manager will store the created certificate in this secret.

Gateway

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
  name: example
  annotations:
    cert-manager.io/issuer: foo
spec:
  gatewayClassName: foo
  listeners:
    - name: http
      hostname: example.com
      port: 443
      protocol: HTTPS
      allowedRoutes:
        namespaces:
          from: All
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-com-tls

對於 IngressRoute 而言,我們需要手動創建 Certificate, 如下所示

IngressRoute

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: example
spec:
  entryPoints: # We listen to requests coming from ports 80 and 443
    - web
    - websecure
  routes:
    - match: Host(`example.domain.com`)
      kind: Rule
      services:
        - name: example # Requests will be forwarded to this service
          port: 80
  tls:
    secretName: example-cert

Certificate

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-cert
spec:
  dnsNames:
    - example.domain.com
  secretName: example-cert
  issuerRef:
    name: acme
    kind: ClusterIssuer
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。