kubernetes從入門到精通系列18-高級調度設置

kubernetes從入門到精通系列目錄:


kubernetes從入門到精通系列18-高級調度設置


節點選擇器:nodeselector、nodeName

節點親和調度:nodeAffinity

18.1 節點選擇器

  • 使用 nodeselector 來將預選範圍縮小,沒有被 nodeselector 選中的節點將被預選階段淘汰
<code>apiVersion: v1
kind: Pod
metadata:
name: pod-schedule-demo
namespace: default
labels:
app: myapp
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
nodeSelector:
gpu: ok
/<code>
  • 此時如果沒有任何一個節點有 gpu 這個標籤,那麼這個 POD 的調度將會被掛起,Pending 狀態,直到滿足條件
<code>kubectl label nodes node2 gpu=ok --overwrite
/<code>
  • 查看 POD 被調度的節點,POD 已經被調度到 node2 節點了
<code>kubectl get pods -o wide
/<code>

18.2 對節點的親和性

親和性定義,詳見:kubectl explain pods.spec.affinity.nodeAffinity

  • POD 對節點親和性定義
<code>nodeAffinity             <object>                                # POD 對 node 節點的親和性
preferredDuringSchedulingIgnoredDuringExecution # 軟親和性要求,儘量滿足親和性
preference <object> # 親和的節點對象
matchExpressions # 查找表達式
key <string> # 標籤
operator <string> # 操作:比較
values # 值
matchFields # 查找字段
key <string> # 標籤
operator <string> # 操作:比較
values # 值
weight <integer> # 權重 1 - 100
requiredDuringSchedulingIgnoredDuringExecution <object> # 硬親和性要求,不滿足則 Pending
nodeSelectorTerms # 選擇器對象列表
matchExpressions # 選擇器對象列表
key <string> # 標籤
operator <string> # 操作:比較
values # 值
matchFields # 查找字段
key <string> # 標籤
operator <string> # 操作:比較
values # 值
/<string>/<string>/<string>/<string>/<object>/<integer>/<string>/<string>/<string>/<string>/<object>/<object>/<code>
  • 示例配置
<code>apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity1-demo
namespace: default
labels:
app: myapp
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬親和性要求,不滿足就 Pending
nodeSelectorTerms:
- matchExpressions:
- key: zone
operator: In
values:
- foo
- bar

---
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity2-demo
namespace: default
labels:
app: myapp
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 軟親和性要求,不滿足也可以對湊
- preference:
matchExpressions:
- key: zone
operator: In
values:
- foo
- bar
weight: 50
/<code>
  • 查看結果,kubectl get pods
<code>NAME                     READY   STATUS    RESTARTS   AGE
pod-nodeaffinity1-demo 0/1 Pending 0 6m16s # 硬親和性要求,沒有就等待
pod-nodeaffinity2-demo 1/1 Running 0 7s # 軟親和性要求,沒有合適主機也可以湊和
/<code>

18.3 對 POD 的親和性

POD 和 POD 出於高效的通信這種需求,所以需要將 POD 和 POD 組織在同一臺機器,同一個機房,例如:LNMT 如果能運行在同一個主機上更好。

  1. 想把一組 POD 運行在一起,使用節點親和性就可以實現,為了達成這個目的,我們需要:把節點標籤精心編排,希望在一起運行的 POD,就使用同一組標籤選擇器來選擇節點,這種方式需要管理節點標籤和 POD 親和性才能做到。
  2. 想把一組 POD 運行在一起,使用 POD 親和性,我們可以設置 POD 對某個 POD 的親和性,那麼比如:LNMT,那麼 MySQL 和 Tomcat 可以設置為更加親和 Ngninx 所在的主機或機櫃,所以必須有個前提就是 POD 和 POD 怎麼才是最近的,這個標準是什麼,也就是什麼是同一位置,怎麼才能知道 node 和 node 是在一個機櫃。所以可以為同一個機櫃的 node 節點打上相同的標籤。
  3. MySQL 和 Tomcat 一定不能和 Nginx 運行在一起,這就是反親和性。
  • POD 對其他 POD 的親和性,詳見:kubectl explain pods.spec.affinity.podAffinity
<code>podAffinity                <object>                              # POD 對其他 POD 的親和性
preferredDuringSchedulingIgnoredDuringExecution # 軟性親和性,儘量滿足親和性
podAffinityTerm <object> # 親和的 POD 對象
labelSelector <object> # 標籤選擇器對象列表
matchExpressions # 標籤選擇器對象,選 POD 標籤
key <string> # 標籤
operator <string> # 操作:比較
values # 值
matchLabels # 集合標籤選擇器
namespaces # 名稱空間的列表
topologyKey <string> # 親和判斷條件
weight <integer> # 權重 1 - 100
requiredDuringSchedulingIgnoredDuringExecution # 硬性親和性,不滿足則 Pending
labelSelector <object> # 標籤選擇器對象列表
matchExpressions # 標籤選擇器對象,選 POD 標籤
key <string> # 標籤
operator <string> # 操作:比較
values # 值
matchLabels # 集合標籤選擇器
namespaces # 名稱空間的列表
topologyKey <string> # 親和判斷條件
/<string>
/<string>/<string>/<object>/<integer>/<string>
/<string>/<string>/<object>/<object>/<object>/<code>
  • 示例配置
<code>apiVersion: v1
kind: Pod
metadata:
name: pod1
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1

---
apiVersion: v1
kind: Pod
metadata:
name: pod2
namespace: default
labels:
app: db
tier: db
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command:
- "sh"
- "-c"
- "sleep 3600"
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬親和性要求,不滿足的 Pending
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp
topologyKey: kubernetes.io/hostname # 親和性的依據為同一個主機名則親和
/<code>
  • 查看結果,kubectl get pods -o wide
<code>NAME   READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
pod1 1/1 Running 0 3m33s 10.244.2.4 node3 <none> <none>
pod2 1/1 Running 0 3m33s 10.244.2.5 node3 <none> <none>
/<none>/<none>/<none>/<none>/<code>

18.4 對 POD 的反親和性

  • POD 對其他 POD 的反親和性,詳見:kubectl explain pods.spec.affinity.podAntiAffinity
<code>podAntiAffinity              <object>                            # POD 對其他 POD 的反親和性
preferredDuringSchedulingIgnoredDuringExecution # 軟性反親和性,儘量滿足親和性
podAffinityTerm <object> # 反親和的 POD 對象
labelSelector <object> # 標籤選擇器對象列表
matchExpressions # 標籤選擇器對象,選 POD 標籤
key <string> # 標籤
operator <string> # 操作:比較
values # 值
matchLabels # 集合標籤選擇器
namespaces # 名稱空間的列表
topologyKey <string> # 親和判斷條件
weight <integer> # 權重 1 - 100
requiredDuringSchedulingIgnoredDuringExecution # 硬性反親和性,不滿足則 Pending
labelSelector <object> # 標籤選擇器對象列表
matchExpressions # 標籤選擇器對象,選 POD 標籤
key <string> # 標籤
operator <string> # 操作:比較
values # 值
matchLabels # 集合標籤選擇器

namespaces # 名稱空間的列表
topologyKey <string> # 親和判斷條件
/<string>
/<string>/<string>/<object>/<integer>/<string>
/<string>/<string>/<object>/<object>/<object>/<code>
  • 配置清單
<code>apiVersion: v1
kind: Pod
metadata:
name: pod3
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1

---
apiVersion: v1
kind: Pod
metadata:
name: pod4
namespace: default
labels:
app: db
tier: db
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command:
- "sh"
- "-c"
- "sleep 3600"
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬親和性要求,不滿足的 Pending
- labelSelector:
matchExpressions:
- key: app
operator: In

values:
- myapp
topologyKey: kubernetes.io/hostname # 反親和性的依據為同一個主機名
/<code>

18.5 node 汙點

汙點只用在 node 上的鍵值屬性(nodes.spec.taints),它的作用是拒絕不能容忍這些汙點的 POD 運行的,因此需要在 POD 上定義容忍度(pods.spec.tolerations),它也是鍵值數據,是一個列表,表示 POD 可以容忍的汙點列表。

一個 POD 能不能運行在一個節點上,就是 pods.spec.tolerations 列表中是否包括了 nodes.spec.taints 中的數據。

  • node 汙點清單格式,詳見:kubectl explain node.spec.taints
<code>taints               # 汙點對象列表
effect <string> # 當 POD 不能容忍這個汙點的時候,要採取的行為,也就是排斥不容忍汙點的 POD
NoSchedule # 影響調度過程,但是已經調度完成 POD 無影響
PreferNoSchedule # 影響調度過程,嘗試驅逐調度已經完成的但不容忍新汙點的 POD
NoExecute # 新增的汙點,影響新的調度過程,且強力驅逐調度已經完成的但不容忍新汙點的 POD
key <string> # 鍵
timeAdded <string> #
value <string> # 值
/<string>/<string>/<string>/<string>/<code>
  • 給 node 打上汙點,鍵為 node-type 值為 production,汙點動作
<code>kubectl taint node node2 node-type=production:NoSchedule
/<code>
  • 刪除 node 上的一個汙點
<code>kubectl taint node node2 node-type-
/<code>
  • 測試清單
<code>apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 4
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v2
ports:
- name: http
containerPort: 80
/<code>
  • 查看結果,kubectl get pods -o wide,因為 POD 沒有定義容忍 node2 的汙點
<code>NAME                            READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
myapp-deploy-675558bfc5-4x5cf 1/1 Running 0 9s 10.244.2.13 node3 <none> <none>
myapp-deploy-675558bfc5-58f2s 1/1 Running 0 9s 10.244.2.10 node3 <none> <none>
myapp-deploy-675558bfc5-gz4kv 1/1 Running 0 9s 10.244.2.12 node3 <none> <none>
myapp-deploy-675558bfc5-hlxdd 1/1 Running 0 9s 10.244.2.11 node3 <none> <none>
/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<code>
  • 此時給 node3 也打上汙點,並驅逐原有的 POD
<code>kubectl taint node node3 node-type=dev:NoExecute
/<code>
  • 查看結果,kubectl get pods -o wide,因為 node3 新增的汙點驅逐了不能容忍汙點的 POD ,所以 POD 被掛起
<code>NAME                            READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
myapp-deploy-675558bfc5-22wpj 0/1 Pending 0 10s <none> <none> <none> <none>
myapp-deploy-675558bfc5-lctv5 0/1 Pending 0 14s <none> <none> <none> <none>
myapp-deploy-675558bfc5-m5qdh 0/1 Pending 0 15s <none> <none> <none> <none>
myapp-deploy-675558bfc5-z8c4q 0/1 Pending 0 14s <none> <none> <none> <none>
/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<code>

18.6 POD 汙點容忍

  • POD 容忍度,詳見:kubectl explain pods.spec.tolerations
<code>tolerations                # 容忍度對象
effect <string> # 能否容忍 node 上的汙點驅逐策略,為空表示容忍任何驅逐策略
NoSchedule # 能容忍 node 汙點的 NoSchedule
PreferNoSchedule # 能容忍 node 汙點的 PreferNoSchedule
NoExecute # 能容忍 node 汙點的 NoExecute
key <string> # 汙點的鍵
operator <string> # Exists 汙點存在不管什麼值,Equal 汙點的值必須等值

tolerationSeconds <integer> # 容忍時間,即如果被驅逐,可以等多久再走,默認 0 秒,NoExecute 使用
value <string> # 汙點的值
/<string>/<integer>/<string>/<string>/<string>/<code>
  • 給 node2 、node3 分別打汙點
<code>kubectl taint node node2 node-type=production:NoSchedule
kubectl taint node node3 node-type=dev:NoExecute
/<code>
  • 定義 POD 清單文件,容忍 node 上存在 node-type 值為 dev 的汙點、接受被驅逐。
<code>apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 4
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v2
ports:
- name: http
containerPort: 80
tolerations:
- key: node-type
operator: Equal
value: dev
effect: NoExecute

/<code>
  • 查看結果,kubectl get pods -o wide,運行在自己容忍的汙點的節點上了
<code>NAME                           READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
myapp-deploy-97578cf74-5v2r6 1/1 Running 0 6m22s 10.244.2.16 node3 <none> <none>
myapp-deploy-97578cf74-gbfj7 1/1 Running 0 6m22s 10.244.2.14 node3 <none> <none>
myapp-deploy-97578cf74-l4lbv 1/1 Running 0 6m22s 10.244.2.15 node3 <none> <none>
myapp-deploy-97578cf74-zvn8f 1/1 Running 0 6m20s 10.244.2.17 node3 <none> <none>
/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<code>
  • 為節點增加新的汙點,設置驅離 POD
<code>kubectl taint node node3 disk=hdd:NoExecute --overwrite
/<code>
  • 查看結果,kubectl get pods -o wide,POD 不能容忍新的汙點,結果被驅逐
<code>NAME                           READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
myapp-deploy-97578cf74-84bfz 0/1 Pending 0 6s <none> <none> <none> <none>
myapp-deploy-97578cf74-fxk2d 0/1 Pending 0 5s <none> <none> <none> <none>
myapp-deploy-97578cf74-jp99j 0/1 Pending 0 6s <none> <none> <none> <none>
myapp-deploy-97578cf74-vdkbx 0/1 Pending 0 6s <none> <none> <none> /<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<code>


分享到:


相關文章: