前面已經介紹了 Google 代管的 GTS 證書管理工具,而今天要介紹的 Cert-Manager 是一款強大的 Kubernetes 工具,能自動執行憑證的取得、更新和部署。無論您是否使用 GCP 雲端平台,Cert-Manager 都可以不依賴雲平台,簡化憑證管理流程,讓您可以專注於應用程式開發。在文章中,我們將深入探討 Cert-Manager 的功能、優勢,並提供如何整合 GCP Cloud DNS 的逐步指南。
Cert-Manager 是一款 Kubernetes 證書管理工具,能夠自動化獲取、更新和部署 TLS/SSL 證書。它支持 Let's Encrypt、Hashicorp Vault 等多種證書頒發機構 (CA),並可與 Ingress 資源無縫集成,自動為你的網站和應用程序提供 HTTPS 保護。
Cert-Manager 簡化了證書管理流程,無需手動操作,即可確保網站安全可靠,並獲得 HTTPS 帶來的 SEO 優勢和用戶信任。
$ helm repo add jetstack https://charts.jetstack.io && helm repo update
$ helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v1.15.3 \
--set installCRDs=true \
--set serviceAccount.create=true
使用 Day6 Workload Identity 教學,綁定 GKE 內的 cert-manager 服務帳戶使其擁有 Cloud DNS 的權限
cert-manager = {
gcp_service_account = "cert-manager"
k8s_service_account = "cert-manager"
k8s_service_account_namespace = "cert-manager"
use_existing_gcp_sa = false
use_existing_k8s_sa = true
roles = [
"roles/dns.admin"
],
# 填入管理Cloud DNS所在的專案
additional_projects = {
"ithome-202409-demo" = [
"roles/dns.admin"
]
}
},
建立 ClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-demo # 替換自己的email
spec:
acme:
email: demo@demoit.shop
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-demo
solvers:
- dns01:
cloudDNS:
# The ID of the GCP project
project: ithome-202409-demo
參數說明:
https://acme-staging-v02.api.letsencrypt.org/directory
,限制上會較為寬鬆創建 Ingress 來進行證書生成掛載示範
增加 Annotations 的參數 cert-manager.io/cluster-issuer: letsencrypt-demo
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: httpd-external-dns-test-ingress
namespace: httpd
annotations:
# 指定用於自動化 TLS 證書管理的 ClusterIssuer 名稱為 "letsencrypt-demo"
cert-manager.io/cluster-issuer: letsencrypt-demo
spec:
ingressClassName: external-nginx
tls:
- hosts:
- httpd-external-dns-test.demoit.shop # 指定要啟用 TLS 加密的域名
secretName: httpd-external-dns-test-tls # 指定存放 TLS 證書和私鑰的 Secret 名稱
rules:
- host: httpd-external-dns-test.demoit.shop
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: httpd-service
port:
number: 80
會發現 Cert-manager 會在CloudDNS 寫入一筆 TXT 紀錄來確定申請者的網域的擁有權
查看 Secret 物件,會發現 Cert-manager 創建了對應網址的 Cert 和 Key
訪問 https://httpd-external-dns-test.demoit.shop
檢查證書,可以看到是 Let’s Encrypt 簽發下來的
什麼時候會使用自簽署憑證?
這裡以 gRPC 端到端直連 mTLS 配置圖來解釋
首先為客戶端與服務端準備必要的證書。證書鏈如下
首先,你需要創建一個自簽發的根證書頒發機構 SelfSigned CA。這可以使用 Issuer
資源來完成
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: demo-ca-issuer
namespace: httpd
spec:
ca:
secretName: demo-ca-secret
接下來,你需要創建一個證書請求,以從你的自簽發 CA 獲取證書。證書請求應該包含你的服務的域名
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: server-grpc-mtls
namespace: httpd
labels:
component: certificate
spec:
privateKey:
algorithm: ECDSA
size: 256
duration: 9120h0m0s
renewBefore: 720h0m0s
dnsNames:
- "server.demo.shop"
commonName: "server.demo.shop"
subject:
organizations:
- demo.shop
organizationalUnits:
- demoit
countries:
- US
localities:
- Iowa
secretName: grpc-tls
issuerRef:
name: demo-ca-issuer
kind: Issuer
group: cert-manager.io
這樣 Server Side的證書就簽發出來了,重複此步驟,將 dnsNames 換成 Client 的網域即可
$ kubectl describe secrets grpc-tls -n httpd
Name: grpc-tls
Namespace: httpd
Labels: controller.cert-manager.io/fao=true
Annotations: cert-manager.io/alt-names: *.demo.shop
cert-manager.io/certificate-name: grpc-tls
cert-manager.io/common-name: *.demo.shop
cert-manager.io/ip-sans:
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: Issuer
cert-manager.io/issuer-name: demo-ca-issuer
cert-manager.io/subject-countries: US
cert-manager.io/subject-localities: Iowa
cert-manager.io/subject-organizationalunits: demoit
cert-manager.io/subject-organizations: demo.shop
cert-manager.io/uri-sans:
Type: kubernetes.io/tls
Data
====
ca.crt: 652 bytes
tls.crt: 721 bytes
tls.key: 227 bytes
在 Kubernetes 環境中部署和管理 SSL/TLS 證書是確保應用程式安全和可靠性的關鍵步驟。Cert-manager 提供了一個自動化的解決方案,簡化了證書生命週期管理。透過整合 Let's Encrypt 等憑證頒發機構,您可以輕鬆取得和更新免費的 SSL/TLS 證書,確保您的 GKE 應用程式具備 HTTPS 安全性。
由於 Day6 介紹的 Google 簽發的 GTS 證書申請時間較長,而且 GTS 無法在 K8s 內部使用自簽證書做 為服務 mTLS 彼此的溝通,如果需要快速產生的證書比較推薦使用 Cert-manager。