K8s污點(diǎn)容忍度橫向主節(jié)點(diǎn)

污點(diǎn) 節(jié)點(diǎn)親和性 容忍度

污點(diǎn)是K8s高級(jí)調(diào)度的特性,用于限制哪些Pod可以被調(diào)度到某一個(gè)節(jié)點(diǎn)。在普通節(jié)點(diǎn)橫向時(shí)我們可以使用污點(diǎn)容忍度創(chuàng)建惡意pod來(lái)對(duì)主節(jié)點(diǎn)進(jìn)行橫向控制。

1、kube-scheduler調(diào)度

kube-schedulerKubernetes 集群的默認(rèn)調(diào)度器,并且是集群控制面(master)的一部分。對(duì)每一個(gè)新創(chuàng)建的Pod或者是未被調(diào)度的Pod,kube-scheduler會(huì)選擇一個(gè)最優(yōu)的Node去運(yùn)行這個(gè)Pod。

然而,Pod內(nèi)的每一個(gè)容器對(duì)資源都有不同的需求,而且Pod本身也有不同的資源需求。因此,Pod在被調(diào)度到Node上之前,根據(jù)這些特定的資源調(diào)度需求,需要對(duì)集群中的Node進(jìn)行一次過(guò)濾。

如下為在創(chuàng)建pod的流程中,調(diào)度器的作用:

當(dāng)創(chuàng)建pod時(shí)候,會(huì)首先把創(chuàng)建的命令請(qǐng)求提交給apiserver,通過(guò)一系列認(rèn)證授權(quán),apiserver把pod數(shù)據(jù)存儲(chǔ)到etcd,創(chuàng)建deployment資源并初始化。然后再是scheduler通過(guò)進(jìn)行l(wèi)ist-watch機(jī)制進(jìn)行監(jiān)測(cè),經(jīng)過(guò)調(diào)度算法把pod調(diào)度到某個(gè)node節(jié)點(diǎn)上,最后信息更新到etcd,再后面就是kubelet接受信息到創(chuàng)建容器。

1654856204-730990-image

2、哪些因素影響調(diào)度

1.pod資源限制

當(dāng)前調(diào)度器選擇適當(dāng)?shù)墓?jié)點(diǎn)時(shí),調(diào)度程序會(huì)檢查每個(gè)節(jié)點(diǎn)是否有足夠的資源滿足 Pod 調(diào)度,比如查看CPU和內(nèi)存限制是否滿足:

1654856218-318825-image

通過(guò)資源限制調(diào)度程序可確保由于過(guò)多 Pod 競(jìng)爭(zhēng)消耗節(jié)點(diǎn)所有可用資源,從而導(dǎo)致節(jié)點(diǎn)資源耗盡引起其他系統(tǒng)異常。

2.節(jié)點(diǎn)選擇器nodeSelector

在創(chuàng)建pod的時(shí)候,節(jié)點(diǎn)選擇器可以約束pod在特定節(jié)點(diǎn)上運(yùn)行。

nodeSelector 也是節(jié)點(diǎn)選擇約束的最簡(jiǎn)單推薦形式,nodeSelector 字段添加到 Pod 的規(guī)約中設(shè)置希望目標(biāo)節(jié)點(diǎn)所具有的節(jié)點(diǎn)標(biāo)簽。 K8s 只會(huì)將 Pod 調(diào)度到擁有你所指定的每個(gè)標(biāo)簽的節(jié)點(diǎn)上。

1654856233-741326-image

例子, 比如多個(gè)節(jié)點(diǎn)需要調(diào)度時(shí)候,通過(guò)給1,2節(jié)點(diǎn)打上標(biāo)簽,創(chuàng)建pod時(shí)候使用節(jié)點(diǎn)選擇器,那么pod會(huì)被按照節(jié)點(diǎn)選擇器希望的目標(biāo)在相應(yīng)節(jié)點(diǎn)調(diào)度。

1654856242-986859-image

為節(jié)點(diǎn)打上標(biāo)簽:

kubectl label node nodename env_role=env

1654856276-99065-image

查看節(jié)點(diǎn)的標(biāo)簽:

kubectl get nodes nodename --show-labels

1654856290-523756-image

3.節(jié)點(diǎn)親和性nodeAffinity

節(jié)點(diǎn)親和性概念上類似于 nodeSelector, 它使可以根據(jù)節(jié)點(diǎn)上的標(biāo)簽來(lái)約束 Pod 可以調(diào)度到哪些節(jié)點(diǎn)上,這種方法比上面的nodeSelector更加靈活,它可以進(jìn)行一些簡(jiǎn)單的邏輯組合了,不只是簡(jiǎn)單的相等匹配。

1654856307-694417-image

節(jié)點(diǎn)親和性和節(jié)點(diǎn)選擇器相比功能更強(qiáng)大,比如還是剛才的圖,如果我使用節(jié)點(diǎn)選擇器env_role:dev1的話是找不到相應(yīng)的節(jié)點(diǎn)的,就沒(méi)有辦法調(diào)度,會(huì)一直是一個(gè)等待的狀態(tài):

1654856328-413659-image

但我如果使用節(jié)點(diǎn)親和性,就算當(dāng)前沒(méi)有這個(gè)節(jié)點(diǎn),我還是可以根據(jù)調(diào)度調(diào)度策略進(jìn)行調(diào)度,不只是簡(jiǎn)單的相等匹配。

調(diào)度策略

調(diào)度可以分成軟策略(軟親和性)和硬策略(硬親和性)兩種方式:

  • 軟親和性(preferredDuringSchedulingIgnoredDuringExecution)就是如果你沒(méi)有滿足調(diào)度要求的節(jié)點(diǎn)的話,POD 就會(huì)忽略這條規(guī)則,繼續(xù)完成調(diào)度過(guò)程,說(shuō)白了就是滿足條件最好了,沒(méi)有的話也無(wú)所謂了的策略;

  • 硬親和性(requiredDuringSchedulingIgnoredDuringExecution)表示當(dāng)前的條件必須滿足,如果沒(méi)有滿足條件的節(jié)點(diǎn)的話,就不斷重試直到滿足條件為止,簡(jiǎn)單說(shuō)就是你必須滿足我的要求,不然我就不干的策略。

如圖可以看到軟親和性和硬親和性的字段其實(shí)差不多,軟親和性多了一個(gè)weight字段,表權(quán)重:

1654856351-643531-image

親和性操作符

如上親和性還有一個(gè)字段是operator表匹配的邏輯操作符,可以使用descirbe命令查看具體的調(diào)度情況是否滿足我們的要求,K8s提供的操作符有下面的幾種:

  • In:label 的值在某個(gè)列表中
  • NotIn:label 的值不在某個(gè)列表中
  • Gt:label 的值大于某個(gè)值
  • Lt:label 的值小于某個(gè)值
  • Exists:某個(gè) label 存在
  • DoesNotExist:某個(gè) label 不存在

如果nodeSelectorTerms下面有多個(gè)選項(xiàng)的話,滿足任何一個(gè)條件就可以了;如果matchExpressions有多個(gè)選項(xiàng)的話,則必須同時(shí)滿足這些條件才能正常調(diào)度 POD。

1654856373-652246-image

污點(diǎn)(Taints)與容忍(tolerations)

容忍度(Toleration)是應(yīng)用于 Pod 上的,允許(但并不要求)Pod 調(diào)度到帶有與之匹配的污點(diǎn)的節(jié)點(diǎn)上。污點(diǎn)說(shuō)白了就是不做普通的調(diào)度。

對(duì)于節(jié)點(diǎn)親和性無(wú)論是軟親和性和硬親和性,都是調(diào)度 POD 到預(yù)期節(jié)點(diǎn)上,而污點(diǎn)(Taints)恰好與之相反,如果一個(gè)節(jié)點(diǎn)標(biāo)記為 Taints,除非 POD 也被標(biāo)識(shí)為可以容忍污點(diǎn)節(jié)點(diǎn),否則該 Taints 節(jié)點(diǎn)不會(huì)被調(diào)度pod

污點(diǎn)(Taints)

查看污點(diǎn)情況:

kubectl describe node nodename | grep Taint

1654856395-837128-image

可以看到,默認(rèn)污點(diǎn)也只有master有。

污點(diǎn)里的值有三種:

  1. NoSchedule:POD 不會(huì)被調(diào)度到標(biāo)記為 taints 節(jié)點(diǎn)。
  2. PreferNoSchedule:NoSchedule 的軟策略版本。
  3. NoExecute:該選項(xiàng)意味著一旦 Taint 生效,如該節(jié)點(diǎn)內(nèi)正在運(yùn)行的 POD 沒(méi)有對(duì)應(yīng) Tolerate 設(shè)置,會(huì)直接被逐出。

NoSchedule就是字面意思,不會(huì)被調(diào)度,PreferNoSchedule說(shuō)白了是盡量不被調(diào)度,NoExecute是不會(huì)調(diào)度并且還會(huì)驅(qū)逐node已有的pod。

創(chuàng)建一個(gè)pod:

1654856431-844199-image

如果不加污點(diǎn),可以看到這個(gè)pod會(huì)隨機(jī)調(diào)度到節(jié)點(diǎn)1或者節(jié)點(diǎn)2:

1654856446-355374-image

這時(shí)候把pod刪除了,重新創(chuàng)建pod并且給node加上污點(diǎn):

給節(jié)點(diǎn)打污點(diǎn):

kubectl taint node nodename key=value:NoSchedule

1654856459-579523-image

重新創(chuàng)建pod并且deployment多個(gè):


1654856471-14659-image

可以發(fā)現(xiàn)全部被調(diào)度在節(jié)點(diǎn)2上,節(jié)點(diǎn)1的污點(diǎn)NoSchedule起了作用。

刪除污點(diǎn):

1654856483-233145-image

污點(diǎn)容忍度(tolerations)

容忍度tolerations是定義在 Pod對(duì)象上的鍵值型屬性數(shù)據(jù),用于配置其可容忍的節(jié)點(diǎn)污點(diǎn),而且調(diào)度器僅能將Pod對(duì)象調(diào)度至其能夠容忍該節(jié)點(diǎn)污點(diǎn)的節(jié)點(diǎn)之上。

污點(diǎn)定義在節(jié)點(diǎn)的node Spec中,而容忍度則定義在PodpodSpec中,它們都是鍵值型數(shù)據(jù)。

Pod對(duì)象上定義容忍度時(shí),它支持兩種操作符:一種是等值比較Equal,表示容忍度與污點(diǎn)必須在keyvalueeffect三者之上完全匹配;另一種是存在性判斷Exists,表示二者的keyeffect必須完全匹配,而容忍度中的value字段要使用空值。

這里的key和value對(duì)應(yīng)的值都是你自己設(shè)置的key和value:

1654856493-926957-image

說(shuō)白了就是:

  • 如果operatorExists(此時(shí)容忍度不能指定 value)
  • 如果operatorEqual,則它們的value應(yīng)該相等

而污點(diǎn)容忍的作用舉個(gè)例子,如果像上面污點(diǎn)一樣設(shè)置了NoSchedule污點(diǎn)的節(jié)點(diǎn),那么創(chuàng)建pod的時(shí)候是必不被調(diào)度到的,但是如果我使用污點(diǎn)容忍,那這個(gè)節(jié)點(diǎn)可以在設(shè)置NoSchedule污點(diǎn)的情況下可能又被調(diào)度,類似于親和性那種作用。

3、污點(diǎn)橫向滲透

污點(diǎn)和污點(diǎn)容忍度的作用也就是獲取主節(jié)點(diǎn)的shell,因?yàn)橄癯R?jiàn)或者節(jié)點(diǎn)shell的流程是創(chuàng)建pod--》分配到正常node---》通過(guò)常規(guī)掛載目錄拿到節(jié)點(diǎn)的shell,而默認(rèn)主節(jié)點(diǎn)是不被調(diào)度的,所以只有使用污點(diǎn)容忍度,創(chuàng)建一個(gè)能夠被調(diào)度到master節(jié)點(diǎn)的pod,然后通過(guò)掛載之類的手法來(lái)拿到主節(jié)點(diǎn)的shell。

通過(guò)創(chuàng)建一個(gè)具有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é)點(diǎn),當(dāng)前是在普通節(jié)點(diǎn):

1654856509-944193-image

多次創(chuàng)建可以發(fā)現(xiàn)在master節(jié)點(diǎn)上了:


1654856523-204282-image

可以通過(guò)掛載操作master節(jié)點(diǎn)母機(jī)shell:

1654856535-594334-image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容