Kubernetes Operator 與 Custom Resources (CRD)
在 Kubernetes 中,我們熟悉了 Deployment, Service, ConfigMap 等內建資源。但如果這些內建資源無法滿足你的需求怎麼辦?例如,你想在 K8s 上管理一個 "MySQLCluster",並且希望它能自動處理備份、Failover 與復原。
這時候,你需要的是 Custom Resources (自定義資源) 與 Operator Pattern。
這也是 Kubernetes 之所以在雲原生時代如此強大的原因:它允許你無限擴充 K8s 的 API。
什麼是 Custom Resource Definition (CRD)?
CRD 允許你定義「新的資源類型」。 一旦你建立了 CRD,Kubernetes API Server 就會多出一種新的 API。
舉個例子,假設我們定義了一個叫做 MySQL 的 CRD,你就可以用這樣的 YAML 來建立資料庫:
# 這完全是自定義的 API Group (公司網域通常作為 Group Name)
apiVersion: database.example.com/v1
# 這是我們自己定義的 Resource Kind
kind: MySQL
metadata:
name: my-db
spec:
# 下面的欄位都是我們自己在 CRD 裡面定義的 (Schema)
version: '8.0'
storage: 100Gi
replicas: 3
有了 CRD,K8s 只知道「有這個資料結構」,但還不知道「該怎麼做」。 就像你在資料庫開了一張表,但沒有程式去讀寫它,它就只是一個靜態的資料而已。
這時候就需要 Operator 出場了。
什麼是 Operator?
Operator 是一個軟體 (通常也是跑在 K8s 裡的 Pod),它的工作是:
- 監聽 (Watch) 特定 CRD 的變動 (Create/Update/Delete)。
- 協調 (Reconcile): 比較「期望狀態 (Spec)」與「實際狀態 (Status)」。
- 執行動作: 呼叫 K8s API 或外部 API,讓實際狀態趨近於期望狀態。
公式:Operator = Controller + Custom Resource (CR) + Domain Knowledge (領域知識)
為什麼這很強大?
Operator 將「人類維運工程師的知識」寫成了程式碼。
- 傳統方式: 資料庫壞了 -> Call 工程師 -> 工程師 SSH 進去修 -> 恢復。
- Operator: 資料庫壞了 -> Operator 偵測到 -> Operator 自動重啟/切換 -> 恢復。
常見的 Operator 範例
Kubernetes 生態系中有數千個 Operator,最著名的包括:
- Prometheus Operator: 自動管理 Prometheus Server, AlertManager, 並且只要新增一個
ServiceMonitorCRD,Prometheus 就會自動去抓 metrics,完全不用手改設定檔。 - ECK (Elastic Cloud on Kubernetes): 自動部署與管理 Elasticsearch Cluster。
- Cert-Manager: 自動申請與續約 TLS 憑證 (支援 Let's Encrypt)。它定義了
Certificate與Issuer這些 CRD。
實戰:安裝並使用 Cert-Manager
我們以 Cert-Manager 為例,看看 Operator 是如何運作的。
1. 安裝 Operator (連同 CRD)
大部分 Operator 都可以用 Helm 安裝:
helm repo add jetstack https://charts.jetstack.io
helm repo update
# 安裝 cert-manager
# installCRDs=true 會自動幫你建立 Certificate, Issuer 等 CRD
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set installCRDs=true
2. 檢查 CRD
安裝完後,你會發現叢集多了一些「看不懂」的資源類型:
kubectl get crd
# 輸出範例:
# certificates.cert-manager.io
# issuers.cert-manager.io
# ...
3. 使用自定義資源 (建立 Issuer)
有了 CRD,我們就能建立 ClusterIssuer 資源 (這不是 K8s 內建的,是 cert-manager 擴充的):
# issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: user@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
kubectl apply -f issuer.yaml
過程發生了什麼事?
- 你 Apply 了 YAML。
- API Server 存下了這個物件。
- Cert-Manager Controller (Operator) 監聽到有一個
ClusterIssuer被建立了。 - 它開始驗證這個 Issuer 的設定是否正確,並準備好去跟 Let's Encrypt 溝通。
如何開發自己的 Operator?
雖然 Operator 很強大,但從零開始寫 Controller 非常困難 (要處理併發、Retry、Cache 等)。 通常我們會使用框架來開發:
- Kubebuilder: 官方 SIG 維護的 SDK (Go 語言)。最推薦,效能最好。
- Operator SDK: RedHat 推出的 SDK,支援 Go, Ansible, Helm。
開發流程通常是:
- 定義 API (struct fields)。
- 生成 CRD YAML。
- 撰寫 Reconcile Loop (核心邏輯)。
總結
- CRD: 定義 API 介面 (資料結構)。
- Operator: 實作 API 邏輯 (程式碼)。
- 效益: 將複雜的「有狀態應用 (Stateful App)」或「維運流程」程式碼化,實現真正的自動化維運。
如果你只是想「使用」K8s,通常只需要會安裝現成的 Operator (如 Prometheus, ArgoCD)。但如果你想成為 K8s 專家或開發平台工具,理解並開發 Operator 是必經之路。