延續昨天的討論,今天我們將深入 Kubernetes 中兩個對叢集穩定運作至關重要的概念:配置管理(ConfigMap) 與 節點調度策略(Affinity / Taint)。這兩項功能不僅決定了應用程式的配置彈性,也影響 Pod 的排程效率與叢集穩定性。透過實務範例,我們將展示如何在多服務環境中應用這些工具,提升部署一致性與高可用性。
在應用程式開發中,「設定不應該寫死在程式碼裡」是基本原則。
Kubernetes 提供的 ConfigMap
,正是為了讓設定與應用程式分離,讓部署時可以依不同環境靈活調整。
以下以實務案例說明:在多服務共用設定時,如何用 ConfigMap 作為唯一設定值來源。
在 Flink Session Mode 中,每個 Job 的執行都依賴已存在的 SessionCluster
。
若 Job 需要連接 Kafka,通常必須取得 bootstrap.servers
等連線資訊。
若透過 Helm 或 CI 流程將變數注入至 SessionJob,這些參數會在 部署階段才被寫入,導致 無法在 Flink 啟動階段(ClassLoader 初始化或 Connector 啟動) 建立唯一且一致的 Kafka 連線。
更穩定的作法,是透過 ConfigMap
定義共用連線參數,讓 SessionCluster 與所有 Job 共用同一份設定:
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: kafka-bootstrap-config
data:
BOOTSTRAP_SERVERS: "kafka-service:9092"
在 Flink Session Cluster 的 Deployment 中掛載這份設定:
# flink-sessioncluster.yaml
spec:
template:
spec:
containers:
- name: flink-main
envFrom:
- configMapRef:
name: kafka-bootstrap-config
🔹 說明:
任何透過 SessionCluster 提交的 Job 都能在初始化階段(open()
或 configure()
)即取得 Kafka 連線設定,確保連線一致性,也避免 pipeline 中多次注入參數造成的不一致。
情境:
你有多個 Helm release(例如不同命名空間或環境),希望每個 release 啟動的 kube-state-metrics 都依同一份設定,擷取一致指標。
做法(同 namespace 範例):
ConfigMap
(例如 ksm-config
),內容為 kube-state-metrics 所需的設定檔。/etc/ksm/config.yaml
),或將必要 key 注入環境變數。apiVersion: v1
kind: ConfigMap
metadata:
name: ksm-config
data:
ksm-config.yaml: |
collect:
- pods
- deployments
# Deployment 掛載 ConfigMap
volumeMounts:
- name: ksm-config-volume
mountPath: /etc/ksm
readOnly: true
volumes:
- name: ksm-config-volume
configMap:
name: ksm-config
注意事項:
總結:ConfigMap 將「參數注入」抽象為一份唯一檔案或 key-value 集合,讓多個服務在初始化階段一致地取得相同設定。這不僅是配置解耦,也讓「部署時序」明確化。
接下來介紹 Affinity / Taint,用擬人化的方式理解更直覺。
Taint 設定在 Node 上,類比「屋子有髒汙」:
只有願意 容忍(Toleration) 髒汙的人(Pod)才能進入。
Affinity 以 Pod 為單位判斷:
若用於 Node,表示「人想住哪間屋子就住哪裡」。
值得注意的是,Kubernetes 沒有 Node Anti-Affinity,因為這種排斥已由 Taint / Toleration 覆蓋。
小技巧:建議從 Pod 角度理解這些機制,更容易掌握排程行為。
偏好是否強制可用:
requiredDuringSchedulingIgnoredDuringExecution
:強制條件 (Pod: 必需的!)preferredDuringSchedulingIgnoredDuringExecution
:偏好條件 (Pod: 我妥協)apiVersion: v1
kind: Pod
metadata:
name: affinity-example
spec:
containers:
- name: app
image: nginx
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/type
operator: In
values:
- data-node
🔹 說明:
Pod 只會被排到標記為 data-node
的節點,就像「人喜歡某間屋子,所以住進去」。
# 節點上加 taint
kubectl taint nodes node1 dedicated=flink:NoSchedule
對應 Pod 需加 toleration:
apiVersion: v1
kind: Pod
metadata:
name: taint-example
spec:
containers:
- name: flink-job
image: flink:latest
tolerations:
- key: "dedicated"
operator: "Equal"
value: "flink"
effect: "NoSchedule"
🔹 說明:
只有帶有對應 toleration 的 Pod 才能進入「髒屋子」。
apiVersion: v1
kind: Pod
metadata:
name: pod-anti-example
spec:
containers:
- name: web
image: nginx
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-service
topologyKey: "kubernetes.io/hostname"
🔹 說明:
相同標籤的 Pod 不會被排在同一節點,就像「不喜歡某人,所以不跟他住一起」。
適合高可用或避免單點故障的服務。
機制 | 設定位置 | 功能 | 類比 |
---|---|---|---|
Node Affinity | Pod spec | Pod 選擇節點 | 想住哪間屋子 |
Pod Affinity | Pod spec | Pod 靠近另一個 Pod | 想跟誰待在一起 |
Pod Anti-Affinity | Pod spec | Pod 避開另一個 Pod | 不喜歡某人,選擇不在一起 |
Taint / Toleration | Node/Pod | Node 有特殊標記,限制 Pod | 容忍特殊要求才能進 |
今天介紹了 Kubernetes 中兩個對穩定運作至關重要的概念:配置管理(ConfigMap) 與 節點調度策略(Affinity / Taint)。
在 ConfigMap 部分,我們說明了如何將設定與程式碼解耦,並透過實務範例展示了多服務共用配置的方法,包括 Flink Session Cluster 與 Kafka 的 bootstrap 連線,以及多個 Helm release 下的 kube-state-metrics 配置共享。透過 ConfigMap,可以將參數注入抽象為唯一來源,確保服務在初始化階段就能取得一致設定,提升部署可控性與可重現性。
在 Affinity / Taint 部分,我們用擬人化方式理解調度邏輯:
透過今天的介紹,相信讀者已經能掌握如何使用 ConfigMap 來解耦配置,確保多服務在初始化階段取得一致設定,提高部署可控性與重現性。
同時,也能運用 Affinity / Taint 精準控制 Pod 的調度,提升叢集的穩定性與高可用性,並在實務操作中更靈活地管理資源。
希望今天的分享,能讓大家對 Kubernetes 的 ConfigMap 與 Affinity / Taint 有更清晰的理解,也能在實務操作中更有效地管理配置與調度策略。
謝謝各位的閱讀,祝福中秋佳節愉快,我們明天見!