關(guān)于K8s中Pod調(diào)度[選擇器,指定節(jié)點,主機親和性]方式和節(jié)點[coedon,drain,taint]標記的Demo
寫在前面
嗯,整理K8s中pod調(diào)度相關(guān)筆記,這里分享給小伙伴
博文內(nèi)容涉及:
kube-scheduler組件的簡述
Pod的調(diào)度(選擇器、指定節(jié)點、主機親和性)方式
節(jié)點的coedon與drain標記
節(jié)點的taint(污點)標記及pod的容忍污點(tolerations)定義
食用方式:
需要了解K8s基礎(chǔ)知識
熟悉資源對象pod,deploy的創(chuàng)建,了解資源對象定義yaml文件
了解kubectl常用命令
理解不足小伙伴幫忙指正
「 所謂成功就是用自己的方式度過人生。--------《明朝那些事》」
Scheduler 調(diào)度組件簡述
Kubernetes Scheduler是什么
眾多周知,Kubernetes Scheduler 是 Kubernetes中負責Pod調(diào)度的重要功能模塊,運行在k8s 集群中的master節(jié)點。
「作用」 : Kubernetes Scheduler的作用是將待調(diào)度的Pod (API新創(chuàng)建的Pod, Controller Manager為補足副本而創(chuàng)建的Pod等)按照特定的調(diào)度算法和調(diào)度策略綁定(Binding)到集群中某個合適的Node上,并將綁定信息寫入etcd中。
在整個調(diào)度過程中涉及三個對象,分別是
待調(diào)度Pod列表
可用Node列表
以及調(diào)度算法和策略
「整體流程」 :通過調(diào)度算法調(diào)度,為待調(diào)度Pod列表中的每個Pod從Node列表中選擇一個最適合的Node隨后, 目標node節(jié)點上的kubelet通過APIServer監(jiān)聽到Kubernetes Scheduler產(chǎn)生的Pod綁定事件,然后獲取對應(yīng)的Pod清單,下載Image鏡像并啟動容器。
kubelet進程通過與API Server的交互,每隔一個時間周期,就會調(diào)用一次API Server的REST接口報告自身狀態(tài), API Server接收到這些信息后,將節(jié)點狀態(tài)信息更新到etcd中。同時kubelet也通過API Server的Watch接口監(jiān)聽Pod信息,
如果監(jiān)聽到新的Pod副本被調(diào)度綁定到本節(jié)點,則執(zhí)行Pod對應(yīng)的容器的創(chuàng)建和啟動邏輯;
如果監(jiān)聽到Pod對象被刪除,則刪除本節(jié)點上的相應(yīng)的Pod容器;
如果監(jiān)聽到修改Pod信息,則kubelet監(jiān)聽到變化后,會相應(yīng)地修改本節(jié)點的Pod容器。
所以說,kubernetes Schedule 在整個系統(tǒng)中承擔了承上啟下的重要功能,對上負責接收聲明式API或者控制器創(chuàng)建新pod的消息,并且為其安排一個合適的Node,對下,選擇好node之后,把工作交接給node上的kubelet,由kubectl負責pod的剩余生命周期。
Kubernetes Scheduler調(diào)度流程
Kubernetes Scheduler當前提供的默認調(diào)度流程分為以下兩步。這部分隨版本一直變化,小伙伴以官網(wǎng)為主
流程 描述
「預(yù)選調(diào)度過程」 即遍歷所有目標Node,篩選出符合要求的候選節(jié)點。為此, Kubernetes內(nèi)置了多種預(yù)選策略(xxx Predicates)供用戶選擇
「確定最優(yōu)節(jié)點」 在第1步的基礎(chǔ)上,采用優(yōu)選策略(xxxPriority)計算出每個候選節(jié)點的積分,積分最高者勝出
Kubernetes Scheduler的調(diào)度流程是通過插件方式加載的"調(diào)度算法提供者” (AlgorithmProvider)具體實現(xiàn)的。一個AlgorithmProvider其實就是包括了一組預(yù)選策略與一組優(yōu)先選擇策略的結(jié)構(gòu)體.
Scheduler中可用的預(yù)選策略包含:NoDiskConflict、PodFitsResources、PodSelectorMatches、PodFitsHost、CheckNodeLabelPresence、CheckServiceAffinity 和PodFitsPorts策略等。
其默認的AlgorithmProvider加載的預(yù)選策略返回布爾值包括:
PodFitsPorts(PodFitsPorts):判斷端口是否沖突
PodFitsResources(PodFitsResources):判斷備選節(jié)點的資源是否滿足備選Pod的需求
NoDiskConflict(NoDiskConflict):判斷備選節(jié)點和已有節(jié)點是否磁盤沖突
MatchNodeSelector(PodSelectorMatches):判斷備選節(jié)點是否包含備選Pod的標簽選擇器指定的標簽。
HostName(PodFitsHost):判斷備選Pod的spec.nodeName域所指定的節(jié)點名稱和備選節(jié)點的名稱是否一致
即每個節(jié)點只有通過前面提及的5個默認預(yù)選策略后,才能初步被選中,進入到確認最優(yōu)節(jié)點(優(yōu)選策略)流程。
Scheduler中的優(yōu)選策略包含(不限于下面3個):
LeastRequestedPriority:從備選節(jié)點列表中選出資源消耗最小的節(jié)點,對各個節(jié)點公式打分
CalculateNodeLabelPriority:判斷策略列出的標簽在備選節(jié)點中存在時,是否選擇該備選節(jié),這不太懂,打分
BalancedResourceAllocation:從備選節(jié)點列表中選出各項資源使用率最均衡的節(jié)點。對各個節(jié)點公式打分
每個節(jié)點通過優(yōu)先選擇策略時都會算出一個得分,計算各項得分,最終選出得分值最大的節(jié)點作為優(yōu)選的結(jié)果(也是調(diào)度算法的結(jié)果)。
Pod的調(diào)度
手動指定pod的運行位置
:
通過給node節(jié)點設(shè)置指定的標簽,然后我們可以在創(chuàng)建pod里指定通過選擇器選擇node標簽,類似前端里面DOM操作元素定位,或者直接指定節(jié)點名
節(jié)點標簽常用命令
標簽設(shè)置 --
查看 kubectl get nodes --show-labels
設(shè)置 kubectl label node node2 disktype=ssd
取消 kubectl label node node2 disktype
所有節(jié)點設(shè)置 kubectl label node all key=vale
給節(jié)點設(shè)置標簽
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl label node vms82.liruilongs.github.io disktype=node1
node/vms82.liruilongs.github.io labeled
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl label node vms83.liruilongs.github.io disktype=node2
node/vms83.liruilongs.github.io labeled
查看節(jié)點標簽
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
vms81.liruilongs.github.io Ready control-plane,master 45d v1.22.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=vms81.liruilongs.github.io,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
vms82.liruilongs.github.io Ready <none> 45d v1.22.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=node1,kubernetes.io/arch=amd64,kubernetes.io/hostname=vms82.liruilongs.github.io,kubernetes.io/os=linux
vms83.liruilongs.github.io Ready <none> 45d v1.22.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=node2,kubernetes.io/arch=amd64,kubernetes.io/hostname=vms83.liruilongs.github.io,kubernetes.io/os=linux
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$
「特殊的內(nèi)置標簽node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,用于設(shè)置角色列roles」
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl get node
NAME STATUS ROLES AGE VERSION
vms81.liruilongs.github.io Ready control-plane,master 45d v1.22.2
vms82.liruilongs.github.io Ready <none> 45d v1.22.2
vms83.liruilongs.github.io Ready <none> 45d v1.22.2
「我們也可以做worker節(jié)點上設(shè)置標簽」
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl label nodes vms82.liruilongs.github.io node-role.kubernetes.io/worker1=
node/vms82.liruilongs.github.io labeled
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl label nodes vms83.liruilongs.github.io node-role.kubernetes.io/worker2=
node/vms83.liruilongs.github.io labeled
查看標簽
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl get node
NAME STATUS ROLES AGE VERSION
vms81.liruilongs.github.io Ready control-plane,master 45d v1.22.2
vms82.liruilongs.github.io Ready worker1 45d v1.22.2
vms83.liruilongs.github.io Ready worker2 45d v1.22.2
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$
選擇器(nodeSelector)方式
「在特定節(jié)點上運行pod,給vms83.liruilongs.github.io節(jié)點打disktype=node2的標簽,yaml文件選擇器指定對應(yīng)的標簽」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get nodes -l disktype=node2
NAME STATUS ROLES AGE VERSION
vms83.liruilongs.github.io Ready worker2 45d v1.22.2
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$vim pod-node2.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl apply -f pod-node2.yaml
pod/podnode2 created
「pod-node2.yaml」
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: podnode2
name: podnode2
spec:
nodeSelector:
disktype: node2
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: podnode2
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
pod被調(diào)度到了vms83.liruilongs.github.io
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
podnode2 1/1 Running 0 13m 10.244.70.60 vms83.liruilongs.github.io <none> <none>
指定節(jié)點名稱(nodeName)的方式
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$vim pod-node1.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl apply -f pod-node1.yaml
pod/podnode1 created
「pod-node1.yaml」
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: podnode1
name: podnode1
spec:
nodeName: vms82.liruilongs.github.io
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: podnode1
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
需要注意 「當pod資源文件指定的節(jié)點標簽,或者節(jié)點名不存在時,這個pod資源是無法創(chuàng)建成功的」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
podnode1 1/1 Running 0 36s 10.244.171.165 vms82.liruilongs.github.io <none> <none>
podnode2 1/1 Running 0 13m 10.244.70.60 vms83.liruilongs.github.io <none> <none>
主機親和性
所謂主機親和性,即在滿足指定條件的節(jié)點上運行。分為硬策略(必須滿足),軟策略(最好滿足)
硬策略(requiredDuringSchedulingIgnoredDuringExecution)
所調(diào)度節(jié)點的標簽必須為其中的一個,這個標簽是一個默認標簽,會自動添加
affinity:
nodeAffinity: #主機親和性
requiredDuringSchedulingIgnoredDuringExecution: #硬策略
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- vms85.liruilongs.github.io
- vms84.liruilongs.github.io
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl apply -f pod-node-a.yaml
pod/podnodea created
「pod-node-a.yaml」
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: podnodea
name: podnodea
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: podnodea
resources: {}
affinity:
nodeAffinity: #主機親和性
requiredDuringSchedulingIgnoredDuringExecution: #硬策略
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- vms85.liruilongs.github.io
- vms84.liruilongs.github.io
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
「條件不滿足,所以 Pending」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods
NAME READY STATUS RESTARTS AGE
podnodea 0/1 Pending 0 8s
「我修改一下,修改為存在的標簽」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$sed -i 's/vms84.liruilongs.github.io/vms83.liruilongs.github.io/' pod-node-a.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl apply -f pod-node-a.yaml
pod/podnodea created
「可以發(fā)現(xiàn)pod調(diào)度成功」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
podnodea 1/1 Running 0 13s 10.244.70.61 vms83.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$
軟策略(preferredDuringSchedulingIgnoredDuringExecution)
所調(diào)度節(jié)點盡量為其中一個
affinity:
nodeAffinity: #主機親和性
preferredDuringSchedulingIgnoredDuringExecution: # 軟策略
- weight: 2
preference:
matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- vms85.liruilongs.github.io
- vms84.liruilongs.github.io
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$vim pod-node-a-r.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl apply -f pod-node-a-r.yaml
pod/podnodea created
「pod-node-a-r.yaml」
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: podnodea
name: podnodea
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: podnodea
resources: {}
affinity:
nodeAffinity: #主機親和性
preferredDuringSchedulingIgnoredDuringExecution: # 軟策略
- weight: 2
preference:
matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- vms85.liruilongs.github.io
- vms84.liruilongs.github.io
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
「檢查一下,調(diào)度OK」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
podnodea 1/1 Running 0 28s 10.244.70.62 vms83.liruilongs.github.io <none> <none>
常見的標簽運算符
運算符 描述
In 包含自, 比如上面的硬親和就包含env_role=dev、env_role=test兩種標簽
NotIn 和上面相反,凡是包含該標簽的節(jié)點都不會匹配到
Exists 存在里面和In比較類似,凡是有某個標簽的機器都會被選擇出來。使用Exists的operator的話,values里面就不能寫東西了。
Gt greater than的意思,表示凡是某個value大于設(shè)定的值的機器則會被選擇出來。
Lt less than的意思,表示凡是某個value小于設(shè)定的值的機器則會被選擇出來。
DoesNotExists 不存在該標簽的節(jié)點
節(jié)點的coedon與drain
「如果想把某個節(jié)點設(shè)置為不可用的話,可以對節(jié)點實施cordon或者drain」
如果一個node被標記為cordon,新創(chuàng)建的pod不會被調(diào)度到此node上,已經(jīng)調(diào)度上去的不會被移走,coedon用于節(jié)點的維護,當不希望再節(jié)點分配pod,那么可以使用coedon把節(jié)點標記為不可調(diào)度。
「這里我們?yōu)榱朔奖悖瑒?chuàng)建一個Deployment控制器用去用于演示,deploy擁有3個pod副本」
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl create deployment nginx --image=nginx --dry-run=client -o yaml >nginx-dep.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$vim nginx-dep.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl apply -f nginx-dep.yaml
deployment.apps/nginx created
「nginx-dep.yaml」
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
resources: {}
status: {}
可以看到pod調(diào)度到了兩個工作節(jié)點
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE
NOMINATED NODE READINESS GATES
nginx-7cf7d6dbc8-hx96s 1/1 Running 0 2m16s 10.244.171.167 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-wshxp 1/1 Running 0 2m16s 10.244.70.1 vms83.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-x78x4 1/1 Running 0 2m16s 10.244.70.63 vms83.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$
節(jié)點的coedon
基本命令
kubectl cordon vms83.liruilongs.github.io #標記不可用
kubectl uncordon vms83.liruilongs.github.io #取消標記
「通過cordon把vms83.liruilongs.github.io標記為不可調(diào)度」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl cordon vms83.liruilongs.github.io #通過cordon把83標記為不可調(diào)度
node/vms83.liruilongs.github.io cordoned
「查看節(jié)點狀態(tài),vms83.liruilongs.github.io變成SchedulingDisabled」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get nodes
NAME STATUS ROLES AGE VERSION
vms81.liruilongs.github.io Ready control-plane,master 48d v1.22.2
vms82.liruilongs.github.io Ready worker1 48d v1.22.2
vms83.liruilongs.github.io Ready,SchedulingDisabled worker2 48d v1.22.2
「修改deployment副本數(shù)量 --replicas=6 」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl scale deployment nginx --replicas=6
deployment.apps/nginx scaled
「新增的pod都調(diào)度到了vms82.liruilongs.github.io 節(jié)點」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7cf7d6dbc8-2nmsj 1/1 Running 0 64s 10.244.171.170 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-chsrn 1/1 Running 0 63s 10.244.171.168 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-hx96s 1/1 Running 0 7m30s 10.244.171.167 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-lppbp 1/1 Running 0 63s 10.244.171.169 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-wshxp 1/1 Running 0 7m30s 10.244.70.1 vms83.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-x78x4 1/1 Running 0 7m30s 10.244.70.63 vms83.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$
「把vms83.liruilongs.github.io節(jié)點上的pod都干掉,會發(fā)現(xiàn)新增pod都調(diào)度到了vms82.liruilongs.github.io」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl delete pod nginx-7cf7d6dbc8-wshxp
pod "nginx-7cf7d6dbc8-wshxp" deleted
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7cf7d6dbc8-2nmsj 1/1 Running 0 2m42s 10.244.171.170 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-5hnc7 1/1 Running 0 10s 10.244.171.171 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-chsrn 1/1 Running 0 2m41s 10.244.171.168 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-hx96s 1/1 Running 0 9m8s 10.244.171.167 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-lppbp 1/1 Running 0 2m41s 10.244.171.169 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-x78x4 1/1 Running 0 9m8s 10.244.70.63 vms83.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl delete pod nginx-7cf7d6dbc8-x78x4
pod "nginx-7cf7d6dbc8-x78x4" deleted
pod都位于正常的節(jié)點
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7cf7d6dbc8-2nmsj 1/1 Running 0 3m31s 10.244.171.170 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-5hnc7 1/1 Running 0 59s 10.244.171.171 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-chsrn 1/1 Running 0 3m30s 10.244.171.168 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-hx96s 1/1 Running 0 9m57s 10.244.171.167 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-lppbp 1/1 Running 0 3m30s 10.244.171.169 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-m8ltr 1/1 Running 0 30s 10.244.171.172 vms82.liruilongs.github.io <none> <none>
「通過 uncordon恢復(fù)節(jié)點vms83.liruilongs.github.io狀態(tài)」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl uncordon vms83.liruilongs.github.io #恢復(fù)節(jié)點狀態(tài)
node/vms83.liruilongs.github.io uncordoned
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get nodes
NAME STATUS ROLES AGE VERSION
vms81.liruilongs.github.io Ready control-plane,master 48d v1.22.2
vms82.liruilongs.github.io Ready worker1 48d v1.22.2
vms83.liruilongs.github.io Ready worker2 48d v1.22.2
「刪除所有的pod」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl scale deployment nginx --replicas=0
deployment.apps/nginx scaled
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -o wide
No resources found in liruilong-pod-create namespace.
節(jié)點的drain
「如果一個節(jié)點被設(shè)置為drain,則此節(jié)點不再被調(diào)度pod,且此節(jié)點上已經(jīng)運行的pod會被驅(qū)逐(evicted)到其他節(jié)點」
「drain包含兩種狀態(tài):cordon不可被調(diào)度,evicted驅(qū)逐當前節(jié)點所以pod」
kubectl drain vms83.liruilongs.github.io --ignore-daemonsets
kubectl uncordon vms83.liruilongs.github.io
「通過deployment添加4個nginx副本--replicas=4」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl scale deployment nginx --replicas=4
deployment.apps/nginx scaled
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -o wide --one-output
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7cf7d6dbc8-2clnb 1/1 Running 0 22s 10.244.171.174 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-9p6g2 1/1 Running 0 22s 10.244.70.2 vms83.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-ptqxm 1/1 Running 0 22s 10.244.171.173 vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-zmdqm 1/1 Running 0 22s 10.244.70.4 vms83.liruilongs.github.io <none> <none>
「添加一下drain 將節(jié)點vms82.liruilongs.github.io設(shè)置為drain」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl drain vms82.liruilongs.github.io --ignore-daemonsets --delete-emptydir-data
node/vms82.liruilongs.github.io cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-ntm7v, kube-system/kube-proxy-nzm24
evicting pod liruilong-pod-create/nginx-7cf7d6dbc8-ptqxm
evicting pod kube-system/metrics-server-bcfb98c76-wxv5l
evicting pod liruilong-pod-create/nginx-7cf7d6dbc8-2clnb
pod/nginx-7cf7d6dbc8-2clnb evicted
pod/nginx-7cf7d6dbc8-ptqxm evicted
pod/metrics-server-bcfb98c76-wxv5l evicted
node/vms82.liruilongs.github.io evicted
查看節(jié)點,狀態(tài)為不可被調(diào)度
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get nodes
NAME STATUS ROLES AGE VERSION
vms81.liruilongs.github.io Ready control-plane,master 48d v1.22.2
vms82.liruilongs.github.io Ready,SchedulingDisabled worker1 48d v1.22.2
vms83.liruilongs.github.io Ready worker2 48d v1.22.2
「等一會,查看節(jié)點調(diào)度,所有pod調(diào)度到了vms83.liruilongs.github.io這臺機器」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -o wide --one-output
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7cf7d6dbc8-9p6g2 1/1 Running 0 4m20s 10.244.70.2 vms83.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-hkflr 1/1 Running 0 25s 10.244.70.5 vms83.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-qt48k 1/1 Running 0 26s 10.244.70.7 vms83.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-zmdqm 1/1 Running 0 4m20s 10.244.70.4 vms83.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$
「取消drain:kubectl uncordon vms82.liruilongs.github.io」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl uncordon vms82.liruilongs.github.io
node/vms82.liruilongs.github.io uncordoned
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$
「有時候會報錯」
「將節(jié)點vms82.liruilongs.github.io設(shè)置為drain」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl drain vms82.liruilongs.github.io
node/vms82.liruilongs.github.io cordoned
DEPRECATED WARNING: Aborting the drain command in a list of nodes will be deprecated in v1.23.
The new behavior will make the drain command go through all nodes even if one or more nodes failed during the drain.
For now, users can try such experience via: --ignore-errors
error: unable to drain node "vms82.liruilongs.github.io", aborting command...
There are pending nodes to be drained:
vms82.liruilongs.github.io
cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): kube-system/calico-node-ntm7v, kube-system/kube-proxy-nzm24
cannot delete Pods with local storage (use --delete-emptydir-data to override): kube-system/metrics-server-bcfb98c76-wxv5l
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get nodes
NAME STATUS ROLES AGE VERSION
vms81.liruilongs.github.io Ready control-plane,master 48d v1.22.2
vms82.liruilongs.github.io Ready,SchedulingDisabled worker1 48d v1.22.2
vms83.liruilongs.github.io Ready worker2 48d v1.22.2
「uncordon掉剛才的節(jié)點」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl uncordon vms82.liruilongs.github.io
node/vms82.liruilongs.github.io uncordoned
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get nodes
NAME STATUS ROLES AGE VERSION
vms81.liruilongs.github.io Ready control-plane,master 48d v1.22.2
vms82.liruilongs.github.io Ready worker1 48d v1.22.2
vms83.liruilongs.github.io Ready worker2 48d v1.22.2
節(jié)點taint及pod的tolerations
默認情況下,pod是不會調(diào)度到有污點的節(jié)點,master節(jié)點從來沒有調(diào)度到pod,因為master節(jié)點設(shè)置了污點,如果想要在某個被設(shè)置了污點的機器調(diào)度pod,那么pod需要設(shè)置tolerations(容忍污點)才能夠被運行。
master節(jié)點的污點
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible master -m shell -a "kubectl describe nodes vms81.liruilongs.github.io | grep -E '(Roles|Taints)'"
192.168.26.81 | CHANGED | rc=0 >>
Roles: control-plane,master
Taints: node-role.kubernetes.io/master:NoSchedule
taint(污點)的設(shè)置和查看
查看節(jié)點角色,和是否設(shè)置污點
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl describe nodes vms82.liruilongs.github.io | grep -E '(Roles|Taints)'
Roles: worker1
Taints: <none>
給 vms83.liruilongs.github.io節(jié)點設(shè)置污點,指定key為key83
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl describe nodes vms83.liruilongs.github.io | grep -E '(Roles|Taints)'
Roles: worker2
Taints: <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl taint node vms83.liruilongs.github.io key83=:NoSchedule
node/vms83.liruilongs.github.io tainted
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl describe nodes vms83.liruilongs.github.io | grep -E '(Roles|Taints)' # 從新查看污點信息
Roles: worker2
Taints: key83:NoSchedule
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$
「重新通過deployment 創(chuàng)建pod,會發(fā)現(xiàn)pod都調(diào)度到82上面,因為83設(shè)置了污點」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl scale deployment nginx --replicas=0
deployment.apps/nginx scaled
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl scale deployment nginx --replicas=4
deployment.apps/nginx scaled
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -o wide --one-output
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7cf7d6dbc8-dhst5 0/1 ContainerCreating 0 12s <none> vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-j6g25 0/1 ContainerCreating 0 12s <none> vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-wpnhr 0/1 ContainerCreating 0 12s <none> vms82.liruilongs.github.io <none> <none>
nginx-7cf7d6dbc8-zkww8 0/1 ContainerCreating 0 11s <none> vms82.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl delete deployment nginx
deployment.apps "nginx" deleted
「取消污點設(shè)置」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl taint node vms83.liruilongs.github.io key83-
node/vms83.liruilongs.github.io untainted
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl describe nodes vms83.liruilongs.github.io | grep -E '(Roles|Taints)'
Roles: worker2
Taints: <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$
設(shè)置operator的值為Equal
「如果需要在有污點的節(jié)點上運行pod,那么需要在定義pod的時候指定toleration屬性」
給 vms82.liruilongs.github.io節(jié)點設(shè)置污點,指定key為key82,value為val82
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl taint nodes vms82.liruilongs.github.io key82=val82:NoSchedule
node/vms82.liruilongs.github.io tainted
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl describe nodes vms82.liruilongs.github.io | grep -E '(Roles|Taints)'
Roles: worker1
Taints: key82=val82:NoSchedule
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$
「在設(shè)置節(jié)點taint的時候,如果value的值不為空,在pod里的tolerations字段只能寫Equal,不能寫Exists,」
「修改yaml文件 pod-taint3.yaml」
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
nodeSelector:
disktype: node2
tolerations:
- key: "key82"
operator: "Equal"
value: "val82"
effect: "NoSchedule"
containers:
- image: nginx
name: pod1
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
創(chuàng)建pod后,執(zhí)行成功,容忍污點
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl apply -f pod-taint3.yaml
pod/pod1 created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 11s 10.244.171.180 vms82.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$
設(shè)置operator的值為Exists
「如果使用Exists的話,那么pod中不能寫value」
「設(shè)置 vms83.liruilongs.github.io 節(jié)點污點標記,value為空」
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl taint node vms83.liruilongs.github.io key83=:NoSchedule
node/vms83.liruilongs.github.io tainted
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl describe nodes vms83.liruilongs.github.io | grep -E '(Roles|Taints)'
Roles: worker2
Taints: key83:NoSchedule
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl apply -f pod-taint.yaml
pod/pod1 created
「pod-taint.yaml」
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
nodeSelector:
disktype: node2
tolerations:
- key: "key83"
operator: "Exists"
effect: "NoSchedule"
containers:
- image: nginx
name: pod1
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
「會發(fā)現(xiàn)節(jié)點調(diào)度到了有污點的vms83.liruilongs.github.io節(jié)點」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 3m4s 10.244.70.8 vms83.liruilongs.github.io <none> <none>
「當然,value沒有值也可以這樣使用Equal」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$cp pod-taint.yaml pod-taint2.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$vim pod-taint2.yaml
「pod-taint2.yaml」
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
nodeSelector:
disktype: node2
tolerations:
- key: "key83"
operator: "Equal"
value: ""
effect: "NoSchedule"
containers:
- image: nginx
name: pod1
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
「會發(fā)現(xiàn)節(jié)點還是調(diào)度到了有污點的vms83.liruilongs.github.io節(jié)點」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl delete -f pod-taint.yaml
pod "pod1" deleted
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl apply -f pod-taint2.yaml
pod/pod1 created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 0/1 ContainerCreating 0 8s <none> vms83.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl taint nodes vms83.liruilongs.github.io key83-
node/vms83.liruilongs.github.io untainted
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$
關(guān)于pod調(diào)度和小伙伴們分享到這里.生活加油 ^_^
作者:山河已無恙
歡迎關(guān)注微信公眾號 :山河已無恙