前提
在 Kubernetes 或是 DCOS 這種集群管理系統上要分配工作相當的方便,但是有些時候我們需要指定某些特定的任務在指定的機器上面才能夠執行.
在 DCOS 上面可以使用 Constraints
Kubernetes 裡面要達到指定 POD 到特定的機器上面,一般來說而言有以下幾種方式:
- nodeSelector (1.0)
- Kubernetes 1.6 之前官方推薦的方式,不過 1.6 之後請使用 Affinity
- Affinity (After Kubernetes 1.6)
- Taints and Tolerations (After Kubernetes 1.6)
nodeSelector
簡單的方式就是透過對於 node 設定不同的 label 來讓 nodeSelector 可以找到適當的機器.
比如說你有一台機器有特殊的硬體,比如說 GPU
kubectl label nodes windows-node1 hardware=gpu
以本次的範例來說,我們部署了不少的機器.其中有一台專門負責部署 Web App
kubectl label nodes windows-node1 usage=app
設定好之後,也可以去查詢你目前節點所有的 labels
kubectl get nodes --show-labels
提供一個官方的簡單範例,讓我們了解如何使用 nodeSelector
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
usage: app
試著跑起來看看…. (架設檔案名稱為 testpod.yaml)
kubectl create -f testpod.yaml
查看結果….
kubectl get pods -o wide
以下的部分只允許在 Kubernetes 1.6 以後才能正確執行.
Affinity (After Kubernetes 1.6)
Affinity 透過類似的方式可以指定 POD 所執行的位置,但是語法不是很類似. 以下先展示一個跟上面範例相同語法的範例
(testpod_affinity.yaml)
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: usage
operator: In
values:
- app
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
那大家會問說, Affinity 究竟功能有哪些比起 nodeSelector 還強大.讓之後官方會建議使用這個?
這邊稍微解釋一下:
優先權語法的加強:
這邊有兩種 Scheduling 的方式,
- requiredDuringSchedulingIgnoredDuringExecution
- preferredDuringSchedulingIgnoredDuringExecution
這兩種有些許的不同,由字面上可以看到一個是”必要” (required) 另一個則是 “偏好” (preferred) .
用法上的建議是,如果要部署的 POD 比較少,而且必須要部署在特定的機器上.可以使用 required .
而如果要部署的 POD 可能超過目標,已如說部署 10 個 POD 在五個區域中. 可以使用 Preferred 這時候有資源會以偏好的優先.
判斷語法的加強:
對於判斷上,也再也不是相等而已.還有以下的判斷語法可以使用.
- In
- NotIn
- Exists
- DoesNotExist
- Gt (greater than)
- Lt (lower than)
這邊的用法比較直覺,也就不再去補充了.
Taints and tolerations
前面介紹的 Affinity 是透過一種偏好的方式來選擇你的執行節點.也就是設定好策略之後讓 POD 透過 “吸引” 的方式來挑選他應該去的節點.
但是反過來,如果你有以下的情況該怎麼辦?
- 如果有些機器絕對不能執行到某些的 POD 不然就會有效能的不完整或是極大的錯誤發生
- 有台機器是要給某個 task 獨佔,分配之後就不希望他再去接任何其他的 task
類似這些的狀況,你就可以使用 taints .指令也相當的簡單….
kubectl taint nodes node1 key1=2:NoSchedule
這樣一來 node1
再也不會分配到任何的工作. (除非.. 等等再提)
恢復的方式也很簡單
kubectl uncordon node1
現在來討論剛剛的限制條件裡面的:
kubectl taint nodes node1 key1=2:NoSchedule
就是必須要 key 與 value 都要相同,並且要 effect (NoSchedule) 也相同. 才會被排到這個節點.
寫法可以參考以下: (某個 pod.yaml 中)
...
tolerations:
- key: "key1"
operator: "Equal"
value: "2"
effect: "NoSchedule"
其實 taints 還有更多應用可以探討… 先到這吧…