污點 節(jié)點親和性 容忍度
污點是K8s高級調(diào)度的特性,用于限制哪些Pod可以被調(diào)度到某一個節(jié)點桂肌。在普通節(jié)點橫向時我們可以使用污點容忍度創(chuàng)建惡意pod來對主節(jié)點進(jìn)行橫向控制。
1舀寓、kube-scheduler調(diào)度
kube-scheduler
是Kubernetes
集群的默認(rèn)調(diào)度器胯舷,并且是集群控制面(master)的一部分健爬。對每一個新創(chuàng)建的Pod或者是未被調(diào)度的Pod埂软,kube-scheduler
會選擇一個最優(yōu)的Node去運行這個Pod。
然而炊汹,Pod
內(nèi)的每一個容器對資源都有不同的需求册着,而且Pod本身也有不同的資源需求拴孤。因此,Pod在被調(diào)度到Node上之前甲捏,根據(jù)這些特定的資源調(diào)度需求演熟,需要對集群中的Node進(jìn)行一次過濾。
如下為在創(chuàng)建pod的流程中司顿,調(diào)度器的作用:
當(dāng)創(chuàng)建pod時候芒粹,會首先把創(chuàng)建的命令請求提交給apiserver,通過一系列認(rèn)證授權(quán),apiserver把pod數(shù)據(jù)存儲到etcd,創(chuàng)建deployment資源并初始化大溜。然后再是scheduler通過進(jìn)行l(wèi)ist-watch機(jī)制進(jìn)行監(jiān)測化漆,經(jīng)過調(diào)度算法
把pod調(diào)度到某個node節(jié)點上,最后信息更新到etcd钦奋,再后面就是kubelet接受信息到創(chuàng)建容器座云。
2、哪些因素影響調(diào)度
1.pod資源限制
當(dāng)前調(diào)度器選擇適當(dāng)?shù)墓?jié)點時付材,調(diào)度程序會檢查每個節(jié)點是否有足夠的資源滿足 Pod 調(diào)度朦拖,比如查看CPU和內(nèi)存限制是否滿足:
通過資源限制調(diào)度程序可確保由于過多 Pod 競爭消耗節(jié)點所有可用資源,從而導(dǎo)致節(jié)點資源耗盡引起其他系統(tǒng)異常厌衔。
2.節(jié)點選擇器nodeSelector
在創(chuàng)建pod的時候贞谓,節(jié)點選擇器可以約束pod在特定節(jié)點上運行。
nodeSelector
也是節(jié)點選擇約束的最簡單推薦形式葵诈,nodeSelector
字段添加到 Pod 的規(guī)約中設(shè)置希望目標(biāo)節(jié)點所具有的節(jié)點標(biāo)簽裸弦。 K8s 只會將 Pod 調(diào)度到擁有你所指定的每個標(biāo)簽的節(jié)點上。
例子作喘, 比如多個節(jié)點需要調(diào)度時候理疙,通過給1,2節(jié)點打上標(biāo)簽泞坦,創(chuàng)建pod時候使用節(jié)點選擇器窖贤,那么pod會被按照節(jié)點選擇器希望的目標(biāo)在相應(yīng)節(jié)點調(diào)度。
為節(jié)點打上標(biāo)簽:
kubectl label node nodename env_role=env
查看節(jié)點的標(biāo)簽:
kubectl get nodes nodename --show-labels
3.節(jié)點親和性nodeAffinity
節(jié)點親和性概念上類似于 nodeSelector
贰锁, 它使可以根據(jù)節(jié)點上的標(biāo)簽來約束 Pod 可以調(diào)度到哪些節(jié)點上赃梧,這種方法比上面的nodeSelector
更加靈活,它可以進(jìn)行一些簡單的邏輯組合了豌熄,不只是簡單的相等匹配授嘀。
節(jié)點親和性和節(jié)點選擇器相比功能更強(qiáng)大,比如還是剛才的圖锣险,如果我使用節(jié)點選擇器env_role:dev1
的話是找不到相應(yīng)的節(jié)點的蹄皱,就沒有辦法調(diào)度,會一直是一個等待的狀態(tài):
但我如果使用節(jié)點親和性芯肤,就算當(dāng)前沒有這個節(jié)點巷折,我還是可以根據(jù)調(diào)度調(diào)度策略進(jìn)行調(diào)度,不只是簡單的相等匹配崖咨。
調(diào)度策略
調(diào)度可以分成軟策略(軟親和性
)和硬策略(硬親和性
)兩種方式:
軟親和性(
preferredDuringSchedulingIgnoredDuringExecution
)就是如果你沒有滿足調(diào)度要求的節(jié)點的話锻拘,POD 就會忽略這條規(guī)則,繼續(xù)完成調(diào)度過程击蹲,說白了就是滿足條件最好了署拟,沒有的話也無所謂了的策略;硬親和性(
requiredDuringSchedulingIgnoredDuringExecution
)表示當(dāng)前的條件必須滿足际邻,如果沒有滿足條件的節(jié)點的話芯丧,就不斷重試直到滿足條件為止,簡單說就是你必須滿足我的要求世曾,不然我就不干的策略缨恒。
如圖可以看到軟親和性和硬親和性的字段其實差不多,軟親和性多了一個weight
字段轮听,表權(quán)重:
親和性操作符
如上親和性還有一個字段是operator
表匹配的邏輯操作符骗露,可以使用descirbe
命令查看具體的調(diào)度情況是否滿足我們的要求,K8s
提供的操作符有下面的幾種:
- In:label 的值在某個列表中
- NotIn:label 的值不在某個列表中
- Gt:label 的值大于某個值
- Lt:label 的值小于某個值
- Exists:某個 label 存在
- DoesNotExist:某個 label 不存在
如果nodeSelectorTerms
下面有多個選項的話血巍,滿足任何一個條件就可以了萧锉;如果matchExpressions
有多個選項的話,則必須同時滿足這些條件才能正常調(diào)度 POD述寡。
污點(Taints)與容忍(tolerations)
容忍度(Toleration
)是應(yīng)用于 Pod 上的柿隙,允許(但并不要求)Pod 調(diào)度到帶有與之匹配的污點的節(jié)點上叶洞。污點說白了就是不做普通的調(diào)度。
對于節(jié)點親和性無論是軟親和性和硬親和性禀崖,都是調(diào)度 POD 到預(yù)期節(jié)點上衩辟,而污點(Taints
)恰好與之相反,如果一個節(jié)點標(biāo)記為 Taints
波附,除非 POD 也被標(biāo)識為可以容忍污點節(jié)點艺晴,否則該 Taints 節(jié)點不會被調(diào)度pod。
污點(Taints)
查看污點情況:
kubectl describe node nodename | grep Taint
可以看到掸屡,默認(rèn)污點也只有master有封寞。
污點里的值有三種:
-
NoSchedule
:POD 不會被調(diào)度到標(biāo)記為 taints 節(jié)點。 -
PreferNoSchedule
:NoSchedule 的軟策略版本仅财。 -
NoExecute
:該選項意味著一旦 Taint 生效狈究,如該節(jié)點內(nèi)正在運行的 POD 沒有對應(yīng) Tolerate 設(shè)置,會直接被逐出满着。
NoSchedule
就是字面意思谦炒,不會被調(diào)度,PreferNoSchedule
說白了是盡量不被調(diào)度风喇,NoExecute
是不會調(diào)度并且還會驅(qū)逐node
已有的pod
宁改。
創(chuàng)建一個pod:
如果不加污點,可以看到這個pod會隨機(jī)調(diào)度到節(jié)點1或者節(jié)點2:
這時候把pod刪除了魂莫,重新創(chuàng)建pod并且給node加上污點:
給節(jié)點打污點:
kubectl taint node nodename key=value:NoSchedule
重新創(chuàng)建pod并且deployment多個:
可以發(fā)現(xiàn)全部被調(diào)度在節(jié)點2上还蹲,節(jié)點1的污點NoSchedule
起了作用。
刪除污點:
污點容忍度(tolerations)
容忍度tolerations
是定義在 Pod
對象上的鍵值型屬性數(shù)據(jù)耙考,用于配置其可容忍的節(jié)點污點谜喊,而且調(diào)度器僅能將Pod
對象調(diào)度至其能夠容忍該節(jié)點污點的節(jié)點之上。
污點定義在節(jié)點的node Spec
中倦始,而容忍度則定義在Pod
的podSpec
中斗遏,它們都是鍵值型數(shù)據(jù)。
在Pod
對象上定義容忍度時鞋邑,它支持兩種操作符:一種是等值比較Equal
,表示容忍度與污點必須在key
诵次、value
和effect
三者之上完全匹配;另一種是存在性判斷Exists
枚碗,表示二者的key
和effect
必須完全匹配逾一,而容忍度中的value
字段要使用空值。
這里的key和value對應(yīng)的值都是你自己設(shè)置的key和value:
說白了就是:
- 如果
operator
是Exists
(此時容忍度不能指定 value) - 如果
operator
是Equal
肮雨,則它們的value
應(yīng)該相等
而污點容忍的作用舉個例子遵堵,如果像上面污點一樣設(shè)置了NoSchedule
污點的節(jié)點,那么創(chuàng)建pod的時候是必不被調(diào)度到的,但是如果我使用污點容忍陌宿,那這個節(jié)點可以在設(shè)置NoSchedule
污點的情況下可能又被調(diào)度锡足,類似于親和性那種作用。
3壳坪、污點橫向滲透
污點和污點容忍度的作用也就是獲取主節(jié)點的shell
舱污,因為像常見或者節(jié)點shell的流程是創(chuàng)建pod--》分配到正常node---》通過常規(guī)掛載目錄拿到節(jié)點的shell,而默認(rèn)主節(jié)點是不被調(diào)度的弥虐,所以只有使用污點容忍度,創(chuàng)建一個能夠被調(diào)度到master節(jié)點的pod媚赖,然后通過掛載之類的手法來拿到主節(jié)點的shell霜瘪。
通過創(chuàng)建一個具有node-role.kubernetes.io/master:NoSchedule
的容忍度讓Pod被Kubernetes Master所調(diào)度。
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
如上的Pod中將宿主機(jī)的根目錄掛載到容器中(volumes與volumeMounts)即可逃逸至Kubernetes Master中接管集群惧磺。
查看節(jié)點颖对,當(dāng)前是在普通節(jié)點:
多次創(chuàng)建可以發(fā)現(xiàn)在master節(jié)點上了:
可以通過掛載操作master節(jié)點母機(jī)shell: