【云原生】K8S集群

目錄

  • 一、調度約束
    • 1.1 POT的創建過程
    • 1.1調度過程
  • 二、指定節點調度
    • 2.1 通過標簽選擇節點
  • 三、親和性
    • 3.1requiredDuringSchedulingIgnoredDuringExecution:硬策略
    • 3.1 preferredDuringSchedulingIgnoredDuringExecution:軟策略
    • 3.3Pod親和性與反親和性
    • 3.4使用 Pod 反親和性調度
  • 四、污點和容忍
    • 4.1 污點(Taint)
    • 4.2容忍(Tolerations)
  • 五、Pod啟動階段(相位 phase)
    • 故障排除步驟:

一、調度約束

Kubernetes 是通過 List-Watch 的機制進行每個組件的協作,保持數據同步的,每個組件之間的設計實現了解耦。

1.1 POT的創建過程

在這里插入圖片描述

(1)這里有三個 List-Watch,分別是 Controller Manager(運行在 Master),Scheduler(運行在 Master),kubelet(運行在 Node)。 他們在進程已啟動就會監聽(Watch)APIServer 發出來的事件。

(2)用戶通過 kubectl 或其他 API 客戶端提交請求給 APIServer 來建立一個 Pod 對象副本。

(3)APIServer 嘗試著將 Pod 對象的相關元信息存入 etcd 中,待寫入操作執行完成,APIServer 即會返回確認信息至客戶端。

(4)當 etcd 接受創建 Pod 信息以后,會發送一個 Create 事件給 APIServer。

(5)由于 Controller Manager 一直在監聽(Watch,通過https的6443端口)APIServer 中的事件。此時 APIServer 接受到了 Create 事件,又會發送給 Controller Manager。

(6)Controller Manager 在接到 Create 事件以后,調用其中的 Replication Controller 來保證 Node 上面需要創建的副本數量。一旦副本數量少于 RC 中定義的數量,RC 會自動創建副本。總之它是保證副本數量的 Controller(PS:擴容縮容的擔當)。

(7)在 Controller Manager 創建 Pod 副本以后,APIServer 會在 etcd 中記錄這個 Pod 的詳細信息。例如 Pod 的副本數,Container 的內容是什么。

(8)同樣的 etcd 會將創建 Pod 的信息通過事件發送給 APIServer。

(9)由于 Scheduler 在監聽(Watch)APIServer,并且它在系統中起到了“承上啟下”的作用,“承上”是指它負責接收創建的 Pod 事件,為其安排 Node;“啟下”是指安置工作完成后,Node 上的 kubelet 進程會接管后繼工作,負責 Pod 生命周期中的“下半生”。 換句話說,Scheduler 的作用是將待調度的 Pod 按照調度算法和策略綁定到集群中 Node 上。

(10)Scheduler 調度完畢以后會更新 Pod 的信息,此時的信息更加豐富了。除了知道 Pod 的副本數量,副本內容。還知道部署到哪個 Node 上面了。并將上面的 Pod 信息更新至 API Server,由 APIServer 更新至 etcd 中,保存起來。

(11)etcd 將更新成功的事件發送給 APIServer,APIServer 也開始反映此 Pod 對象的調度結果。

(12)kubelet 是在 Node 上面運行的進程,它也通過 List-Watch 的方式監聽(Watch,通過https的6443端口)APIServer 發送的 Pod 更新的事件。kubelet 會嘗試在當前節點上調用 Docker 啟動容器,并將 Pod 以及容器的結果狀態回送至 APIServer。

(13)APIServer 將 Pod 狀態信息存入 etcd 中。在 etcd 確認寫入操作成功完成后,APIServer將確認信息發送至相關的 kubelet,事件將通過它被接受。

#注意:在創建 Pod 的工作就已經完成了后,為什么 kubelet 還要一直監聽呢?原因很簡單,假設這個時候 kubectl 發命令,要擴充 Pod 副本數量,那么上面的流程又會觸發一遍,kubelet 會根據最新的 Pod 的部署情況調整 Node 的資源。又或者 Pod 副本數量沒有發生變化,但是其中的鏡像文件升級了,kubelet 也會自動獲取最新的鏡像文件并且加載。

1.1調度過程

  • Scheduler 是 kubernetes 的調度器,主要的任務是把定義的 pod 分配到集群的節點上。其主要考慮的問題如下:

●公平:如何保證每個節點都能被分配資源
●資源高效利用:集群所有資源最大化被使用
●效率:調度的性能要好,能夠盡快地對大批量的 pod 完成調度工作
●靈活:允許用戶根據自己的需求控制調度的邏輯

  • Sheduler 是作為單獨的程序運行的,啟動之后會一直監聽 APIServer,獲取 spec.nodeName 為空的 pod,對每個 pod 都會創建一個 binding,表明該 pod 應該放到哪個節點上。

  • 調度分為幾個部分:首先是過濾掉不滿足條件的節點,這個過程稱為預算策略(predicate);然后對通過的節點按照優先級排序,這個是優選策略(priorities);最后從中選擇優先級最高的節點。如果中間任何一步驟有錯誤,就直接返回錯誤。

Predicate 有一系列的常見的算法可以使用

●PodFitsResources:節點上剩余的資源是否大于 pod 請求的資源。
●PodFitsHost:如果 pod 指定了 NodeName,檢查節點名稱是否和 NodeName 匹配。
●PodFitsHostPorts:節點上已經使用的 port 是否和 pod 申請的 port 沖突。
●PodSelectorMatches:過濾掉和 pod 指定的 label 不匹配的節點。
●NoDiskConflict:已經 mount 的 volume 和 pod 指定的 volume 不沖突,除非它們都是只讀。

  • 如果在 predicate 過程中沒有合適的節點,pod 會一直在 pending 狀態,不斷重試調度,直到有節點滿足條件。 經過這個步驟,如果有多個節點滿足條件,就繼續 priorities 過程:按照優先級大小對節點排序。

優先級由一系列鍵值對組成,鍵是該優先級項的名稱,值是它的權重(該項的重要性)。有一系列的常見的優先級選項包括:

●LeastRequestedPriority:通過計算CPU和Memory的使用率來決定權重,使用率越低權重越高。也就是說,這個優先級指標傾向于資源使用比例更低的節點。
●BalancedResourceAllocation:節點上 CPU 和 Memory 使用率越接近,權重越高。這個一般和上面的一起使用,不單獨使用。比如 node01 的 CPU 和 Memory 使用率 20:60,node02 的 CPU 和 Memory 使用率 50:50,雖然 node01 的總使用率比 node02 低,但 node02 的 CPU 和 Memory 使用率更接近,從而調度時會優選 node02。
●ImageLocalityPriority:傾向于已經有要使用鏡像的節點,鏡像總大小值越大,權重越高。

  • 通過算法對所有的優先級項目和權重進行計算,得出最終的結果。

二、指定節點調度

  • pod.spec.nodeName 將 Pod 直接調度到指定的 Node 節點上,會跳過 Scheduler 的調度策略,該匹配規則是強制匹配
vim myapp.yaml
apiVersion: apps/v1  
kind: Deployment  
metadata:name: myapp
spec:replicas: 3selector:matchLabels:app: myapptemplate:metadata:labels:app: myappspec:nodeName: node01containers:- name: myappimage: soscscs/myapp:v1ports:- containerPort: 80kubectl apply -f myapp.yamlkubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
myapp-6bc58d7775-6wlpp   1/1     Running   0          14s   10.244.1.25   node01   <none>           <none>
myapp-6bc58d7775-szcvp   1/1     Running   0          14s   10.244.1.26   node01   <none>           <none>
myapp-6bc58d7775-vnxlp   1/1     Running   0          14s   10.244.1.24   node01   <none>           <none>

在這里插入圖片描述
在這里插入圖片描述

查看詳細事件(發現未經過 scheduler 調度分配)

kubectl describe pod myapp-6bc58d7775-6wlpp
......Type    Reason   Age   From             Message----    ------   ----  ----             -------Normal  Pulled   95s   kubelet, node01  Container image "soscscs/myapp:v1" already present on machineNormal  Created  99s   kubelet, node01  Created container nginxNormal  Started  99s   kubelet, node01  Started container nginx

在這里插入圖片描述

2.1 通過標簽選擇節點

  • pod.spec.nodeSelector:通過 kubernetes 的 label-selector 機制選擇節點,由調度器調度策略匹配 label,然后調度 Pod 到目標節點,該匹配規則屬于強制約束
//獲取標簽幫助
kubectl label --help
Usage:kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version] [options]//需要獲取 node 上的 NAME 名稱
kubectl get node
NAME     STATUS   ROLES    AGE   VERSION
master   Ready    master   30h   v1.20.11
node01   Ready    <none>   30h   v1.20.11
node02   Ready    <none>   30h   v1.20.11//給對應的 node 設置標簽分別為 kgc=a 和 kgc=b
kubectl label nodes node01 kgc=akubectl label nodes node02 kgc=b//查看標簽
kubectl get nodes --show-labels
NAME     STATUS   ROLES    AGE   VERSION   LABELS
master   Ready    master   30h   v1.20.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/master=
node01   Ready    <none>   30h   v1.20.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kgc=a,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux
node02   Ready    <none>   30h   v1.20.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kgc=b,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux//修改成 nodeSelector 調度方式
vim myapp1.yaml
apiVersion: apps/v1
kind: Deployment  
metadata:name: myapp1
spec:replicas: 3selector:matchLabels:app: myapp1template:metadata:labels:app: myapp1spec:nodeSelector:kgc: acontainers:- name: myapp1image: soscscs/myapp:v1ports:- containerPort: 80kubectl apply -f myapp1.yaml kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
myapp1-58cff4d75-52xm5   1/1     Running   0          24s   10.244.1.29   node01   <none>           <none>
myapp1-58cff4d75-f747q   1/1     Running   0          24s   10.244.1.27   node01   <none>           <none>
myapp1-58cff4d75-kn8gk   1/1     Running   0          24s   10.244.1.28   node01   <none>           <none>//查看詳細事件(通過事件可以發現要先經過 scheduler 調度分配)
kubectl describe pod myapp1-58cff4d75-52xm5
Events:Type    Reason     Age   From               Message----    ------     ----  ----               -------Normal  Scheduled  57s   default-scheduler  Successfully assigned default/myapp1-58cff4d75-52xm5 to node01Normal  Pulled     57s   kubelet, node01    Container image "soscscs/myapp:v1" already present on machineNormal  Created    56s   kubelet, node01    Created container myapp1Normal  Started    56s   kubelet, node01    Started container myapp1

在這里插入圖片描述

在這里插入圖片描述

//修改一個 label 的值,需要加上 --overwrite 參數
kubectl label nodes node02 kgc=a --overwrite//刪除一個 label,只需在命令行最后指定 label 的 key 名并與一個減號相連即可:
kubectl label nodes node02 kgc-//指定標簽查詢 node 節點
kubectl get node -l kgc=a

三、親和性

https://kubernetes.io/zh/docs/concepts/scheduling-eviction/assign-pod-node/

(1)節點親和性

(1)節點親和性

pod.spec.nodeAffinity
●preferredDuringSchedulingIgnoredDuringExecution:軟策略
●requiredDuringSchedulingIgnoredDuringExecution:硬策略

(2)Pod 親和性

pod.spec.affinity.podAffinity/podAntiAffinity
●preferredDuringSchedulingIgnoredDuringExecution:軟策略
●requiredDuringSchedulingIgnoredDuringExecution:硬策略

可以把自己理解成一個Pod,當你報名來學云計算,如果你更傾向去zhangsan老師帶的班級,把不同老師帶的班級當作一個node的話,這個就是節點親和性。如果你是必須要去zhangsan老師帶的班級,這就是硬策略;而你說你想去并且最好能去zhangsan老師帶的班級,這就是軟策略。
如果你有一個很好的朋友叫lisi,你傾向和lisi同學在同一個班級,這個就是Pod親和性。如果你一定要去lisi同學在的班級,這就是硬策略;而你說你想去并且最好能去lisi同學在的班級,這就是軟策略。軟策略是不去也可以,硬策略則是不去就不行。

鍵值運算關系

●In:label 的值在某個列表中
●NotIn:label 的值不在某個列表中
●Gt:label 的值大于某個值
●Lt:label 的值小于某個值
●Exists:某個 label 存在
●DoesNotExist:某個 label 不存在

kubectl get nodes --show-labels
NAME     STATUS   ROLES    AGE   VERSION   LABELS
master   Ready    master   11d   v1.20.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/master=
node01   Ready    <none>   11d   v1.20.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux
node02   Ready    <none>   11d   v1.20.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux

3.1requiredDuringSchedulingIgnoredDuringExecution:硬策略

mkdir /opt/affinity
cd /opt/affinityvim pod1.yaml
apiVersion: v1
kind: Pod
metadata:name: affinitylabels:app: node-affinity-pod
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostname    #指定node的標簽operator: NotIn     #設置Pod安裝到kubernetes.io/hostname的標簽值不在values列表中的node上values:- node02kubectl apply -f pod1.yamlkubectl get pods -o wide
NAME       READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
affinity   1/1     Running   0          13s   10.244.1.30   node01   <none>           <none>kubectl delete pod --all && kubectl apply -f pod1.yaml && kubectl get pods -o wide#如果硬策略不滿足條件,Pod 狀態一直會處于 Pending 狀態。

3.1 preferredDuringSchedulingIgnoredDuringExecution:軟策略

vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:name: affinitylabels:app: node-affinity-pod
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1affinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1   #如果有多個軟策略選項的話,權重越大,優先級越高preference:matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- node03kubectl apply -f pod2.yamlkubectl get pods -o wide
NAME       READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
affinity   1/1     Running   0          5s    10.244.2.35   node02   <none>           <none>//把values:的值改成node01,則會優先在node01上創建Pod
kubectl delete pod --all && kubectl apply -f pod2.yaml && kubectl get pods -o wide//如果把硬策略和軟策略合在一起使用,則要先滿足硬策略之后才會滿足軟策略
//示例:
apiVersion: v1
kind: Pod
metadata:name: affinitylabels:app: node-affinity-pod
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:   #先滿足硬策略,排除有kubernetes.io/hostname=node02標簽的節點nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: NotInvalues:- node02preferredDuringSchedulingIgnoredDuringExecution:  #再滿足軟策略,優先選擇有kgc=a標簽的節點- weight: 1preference:matchExpressions:- key: kgcoperator: Invalues:- a

3.3Pod親和性與反親和性

調度策略匹配標簽操作符拓撲域支持調度目標
nodeAffinity主機In, NotIn, Exists,DoesNotExist, Gt, Lt指定主機
podAffinityPodIn, NotIn, Exists,DoesNotExistPod與指定Pod同一拓撲域
podAntiAffinityPodIn, NotIn, Exists,DoesNotExistPod與指定Pod不在同一拓撲域
kubectl label nodes node01 kgc=a
kubectl label nodes node02 kgc=a//創建一個標簽為 app=myapp01 的 Pod
vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp01labels:app: myapp01
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1kubectl apply -f pod3.yamlkubectl get pods --show-labels -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES   LABELS
myapp01   1/1     Running   0          37s   10.244.2.3   node01   <none>           <none>            app=myapp01//使用 Pod 親和性調度,創建多個 Pod 資源
vim pod4.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp02labels:app: myapp02
spec:containers:- name: myapp02image: soscscs/myapp:v1affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- myapp01topologyKey: kgc#僅當節點和至少一個已運行且有鍵為“app”且值為“myapp01”的標簽 的 Pod 處于同一拓撲域時,才可以將該 Pod 調度到節點上。 (更確切的說,如果節點 N 具有帶有鍵 kgc 和某個值 V 的標簽,則 Pod 有資格在節點 N 上運行,以便集群中至少有一個具有鍵 kgc 和值為 V 的節點正在運行具有鍵“app”和值 “myapp01”的標簽的 pod。)
#topologyKey 是節點標簽的鍵。如果兩個節點使用此鍵標記并且具有相同的標簽值,則調度器會將這兩個節點視為處于同一拓撲域中。 調度器試圖在每個拓撲域中放置數量均衡的 Pod。
#如果 kgc 對應的值不一樣就是不同的拓撲域。比如 Pod1 在 kgc=a 的 Node 上,Pod2 在 kgc=b 的 Node 上,Pod3 在 kgc=a 的 Node 上,則 Pod2 和 Pod1、Pod3 不在同一個拓撲域,而Pod1 和 Pod3在同一個拓撲域。kubectl apply -f pod4.yamlkubectl get pods --show-labels -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES   LABELS
myapp01   1/1     Running   0          15m   10.244.1.3   node01   <none>           <none>            app=myapp01
myapp02   1/1     Running   0          8s    10.244.1.4   node01   <none>           <none>            app=myapp02
myapp03   1/1     Running   0          52s   10.244.2.53  node02   <none>           <none>            app=myapp03
myapp04   1/1     Running   0          44s   10.244.1.51  node01   <none>           <none>            app=myapp03
myapp05   1/1     Running   0          38s   10.244.2.54  node02   <none>           <none>            app=myapp03
myapp06   1/1     Running   0          30s   10.244.1.52  node01   <none>           <none>            app=myapp03
myapp07   1/1     Running   0          24s   10.244.2.55  node02   <none>           <none>            app=myapp03

3.4使用 Pod 反親和性調度

示例1


vim pod5.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp10labels:app: myapp10
spec:containers:- name: myapp10image: soscscs/myapp:v1affinity:podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: Invalues:- myapp01topologyKey: kubernetes.io/hostname#如果節點處于 Pod 所在的同一拓撲域且具有鍵“app”和值“myapp01”的標簽, 則該 pod 不應將其調度到該節點上。 (如果 topologyKey 為 kubernetes.io/hostname,則意味著當節點和具有鍵 “app”和值“myapp01”的 Pod 處于相同的拓撲域,Pod 不能被調度到該節點上。)kubectl apply -f pod5.yamlkubectl get pods --show-labels -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES   LABELS
myapp01   1/1     Running   0          44m   10.244.1.3   node01   <none>           <none>            app=myapp01
myapp02   1/1     Running   0          29m   10.244.1.4   node01   <none>           <none>            app=myapp02
myapp10   1/1     Running   0          75s   10.244.2.4   node02   <none>           <none>            app=myapp03

示例2:

vim pod6.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp20labels:app: myapp20
spec:containers:- name: myapp20image: soscscs/myapp:v1affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- myapp01topologyKey: kgc//由于指定 Pod 所在的 node01 節點上具有帶有鍵 kgc 和標簽值 a 的標簽,node02 也有這個kgc=a的標簽,所以 node01 和 node02 是在一個拓撲域中,反親和要求新 Pod 與指定 Pod 不在同一拓撲域,所以新 Pod 沒有可用的 node 節點,即為 Pending 狀態。
kubectl get pod --show-labels -owide
NAME          READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES   LABELS
myapp01       1/1     Running   0          43s     10.244.1.68   node01   <none>           <none>            app=myapp01
myapp20       0/1     Pending   0          4s      <none>        <none>   <none>           <none>            app=myapp03kubectl label nodes node02 kgc=b --overwritekubectl get pod --show-labels -o wide
NAME          READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES   LABELS
myapp01       1/1     Running   0          7m40s   10.244.1.68   node01   <none>           <none>            app=myapp01
myapp21       1/1     Running   0          7m1s    10.244.2.65   node02   <none>           <none>            app=myapp03

四、污點和容忍

4.1 污點(Taint)

節點親和性,是Pod的一種屬性(偏好或硬性要求),它使Pod被吸引到一類特定的節點。Taint 則相反,它使節點能夠排斥一類特定的 Pod。
Taint 和 Toleration 相互配合,可以用來避免 Pod 被分配到不合適的節點上。每個節點上都可以應用一個或多個 taint ,這表示對于那些不能容忍這些 taint 的 Pod,是不會被該節點接受的。如果將 toleration 應用于 Pod 上,則表示這些 Pod 可以(但不一定)被調度到具有匹配 taint 的節點上。

使用 kubectl taint 命令可以給某個 Node 節點設置污點,Node 被設置上污點之后就和 Pod 之間存在了一種相斥的關系,可以讓 Node 拒絕 Pod 的調度執行,甚至將 Node 已經存在的 Pod 驅逐出去。

污點的組成格式如下:

key=value:effect

每個污點有一個 key 和 value 作為污點的標簽,其中 value 可以為空,effect 描述污點的作用。

當前 taint effect 支持如下三個選項:

●NoSchedule:表示 k8s 將不會將 Pod 調度到具有該污點的 Node 上
●PreferNoSchedule:表示 k8s 將盡量避免將 Pod 調度到具有該污點的 Node 上
●NoExecute:表示 k8s 將不會將 Pod 調度到具有該污點的 Node 上,同時會將 Node 上已經存在的 Pod 驅逐出去

kubectl get nodes
NAME     STATUS   ROLES    AGE   VERSION
master   Ready    master   11d   v1.20.11
node01   Ready    <none>   11d   v1.20.11
node02   Ready    <none>   11d   v1.20.11//master 就是因為有 NoSchedule 污點,k8s 才不會將 Pod 調度到 master 節點上
kubectl describe node master
......
Taints:             node-role.kubernetes.io/master:NoSchedule#設置污點
kubectl taint node node01 key1=value1:NoSchedule#節點說明中,查找 Taints 字段
kubectl describe node node-name  #去除污點
kubectl taint node node01 key1:NoSchedule-kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
myapp01   1/1     Running   0          4h28m   10.244.2.3   node02   <none>           <none>
myapp02   1/1     Running   0          4h13m   10.244.2.4   node02   <none>           <none>
myapp03   1/1     Running   0          3h45m   10.244.1.4   node01   <none>           <none>kubectl taint node node02 check=mycheck:NoExecute//查看 Pod 狀態,會發現 node02 上的 Pod 已經被全部驅逐(注:如果是 Deployment 或者 StatefulSet 資源類型,為了維持副本數量則會在別的 Node 上再創建新的 Pod)
kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
myapp03   1/1     Running   0          3h48m   10.244.1.4   node01   <none>           <none>

4.2容忍(Tolerations)

設置了污點的 Node 將根據 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute 和 Pod 之間產生互斥的關系,Pod 將在一定程度上不會被調度到 Node 上。但我們可以在 Pod 上設置容忍(Tolerations),意思是設置了容忍的 Pod 將可以容忍污點的存在,可以被調度到存在污點的 Node 上。

kubectl taint node node01 check=mycheck:NoExecutevim pod3.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp01labels:app: myapp01
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1kubectl apply -f pod3.yaml//在兩個 Node 上都設置了污點后,此時 Pod 將無法創建成功
kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
myapp01   0/1     Pending   0          17s   <none>   <none>   <none>           <none>vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp01labels:app: myapp01
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1tolerations:- key: "check"operator: "Equal"value: "mycheck"effect: "NoExecute"tolerationSeconds: 3600#其中的 key、vaule、effect 都要與 Node 上設置的 taint 保持一致
#operator 的值為 Exists 將會忽略 value 值,即存在即可
#tolerationSeconds 用于描述當 Pod 需要被驅逐時可以在 Node 上繼續保留運行的時間kubectl apply -f pod3.yaml//在設置了容忍之后,Pod 創建成功
kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
myapp01   1/1     Running   0          10m   10.244.1.5   node01   <none>           <none>//其它注意事項
(1)當不指定 key 值時,表示容忍所有的污點 keytolerations:- operator: "Exists"(2)當不指定 effect 值時,表示容忍所有的污點作用tolerations:- key: "key"operator: "Exists"(3)有多個 Master 存在時,防止資源浪費,可以如下設置
kubectl taint node Master-Name node-role.kubernetes.io/master=:PreferNoSchedule//如果某個 Node 更新升級系統組件,為了防止業務長時間中斷,可以先在該 Node 設置 NoExecute 污點,把該 Node 上的 Pod 都驅逐出去
kubectl taint node node01 check=mycheck:NoExecute//此時如果別的 Node 資源不夠用,可臨時給 Master 設置 PreferNoSchedule 污點,讓 Pod 可在 Master 上臨時創建
kubectl taint node master node-role.kubernetes.io/master=:PreferNoSchedule//待所有 Node 的更新操作都完成后,再去除污點
kubectl taint node node01 check=mycheck:NoExecute-//cordon 和 drain
##對節點執行維護操作:
kubectl get nodes//將 Node 標記為不可調度的狀態,這樣就不會讓新創建的 Pod 在此 Node 上運行
kubectl cordon <NODE_NAME> 		 #該node將會變為SchedulingDisabled狀態//kubectl drain 可以讓 Node 節點開始釋放所有 pod,并且不接收新的 pod 進程。drain 本意排水,意思是將出問題的 Node 下的 Pod 轉移到其它 Node 下運行
kubectl drain <NODE_NAME> --ignore-daemonsets --delete-emptydir-data --force--ignore-daemonsets:無視 DaemonSet 管理下的 Pod。
--delete-emptydir-data:如果有 mount local volume 的 pod,會強制殺掉該 pod。
--force:強制釋放不是控制器管理的 Pod。注:執行 drain 命令,會自動做了兩件事情:
(1)設定此 node 為不可調度狀態(cordon)
(2)evict(驅逐)了 Pod//kubectl uncordon 將 Node 標記為可調度的狀態
kubectl uncordon <NODE_NAME>

五、Pod啟動階段(相位 phase)

  • Pod 創建完之后,一直到持久運行起來,中間有很多步驟,也就有很多出錯的可能,因此會有很多不同的狀態。

一般來說,pod 這個過程包含以下幾個步驟:
(1)調度到某臺 node 上。kubernetes 根據一定的優先級算法選擇一臺 node 節點將其作為 Pod 運行的 node
(2)拉取鏡像
(3)掛載存儲配置等
(4)容器運行起來。如果有健康檢查,會根據檢查的結果來設置其狀態。

//phase 的可能狀態有:

●Pending:表示APIServer創建了Pod資源對象并已經存入了etcd中,但是它并未被調度完成(比如還沒有調度到某臺node上),或者仍然處于從倉庫下載鏡像的過程中。

●Running:Pod已經被調度到某節點之上,并且Pod中所有容器都已經被kubelet創建。至少有一個容器正在運行,或者正處于啟動或者重啟狀態(也就是說Running狀態下的Pod不一定能被正常訪問)。

●Succeeded:有些pod不是長久運行的,比如job、cronjob,一段時間后Pod中的所有容器都被成功終止,并且不會再重啟。需要反饋任務執行的結果。

●Failed:Pod中的所有容器都已終止了,并且至少有一個容器是因為失敗終止。也就是說,容器以非0狀態退出或者被系統終止,比如 command 寫的有問題。

●Unknown:表示無法讀取 Pod 狀態,通常是 kube-controller-manager 無法與 Pod 通信。Pod 所在的 Node 出了問題或失聯,從而導致 Pod 的狀態為 Unknow

如何刪除 Unknown 狀態的 Pod ?

●從集群中刪除有問題的 Node。使用公有云時,kube-controller-manager 會在 VM 刪除后自動刪除對應的 Node。 而在物理機部署的集群中,需要管理員手動刪除 Node(kubectl delete node <node_name>)。

●被動等待 Node 恢復正常,Kubelet 會重新跟 kube-apiserver 通信確認這些 Pod 的期待狀態,進而再決定刪除或者繼續運行這些 Pod。

●主動刪除 Pod,通過執行 kubectl delete pod <pod_name> --grace-period=0 --force 強制刪除 Pod。但是這里需要注意的是,除非明確知道 Pod 的確處于停止狀態(比如 Node 所在 VM 或物理機已經關機),否則不建議使用該方法。特別是 StatefulSet 管理的 Pod,強制刪除容易導致腦裂或者數據丟失等問題。

故障排除步驟:

//查看Pod事件
kubectl describe TYPE NAME_PREFIX  //查看Pod日志(Failed狀態下)
kubectl logs <POD_NAME> [-c Container_NAME]//進入Pod(狀態為running,但是服務沒有提供)
kubectl exec –it <POD_NAME> bash//查看集群信息
kubectl get nodes//發現集群狀態正常
kubectl cluster-info//查看kubelet日志發現
journalctl -xefu kubelet

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/36208.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36208.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36208.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

(2)原神角色數據分析-2

功能一&#xff1a; 得到某個屬性的全部角色&#xff0c;將其封裝在class中 """各元素角色信息&#xff1a;一對多""" from pandas import DataFrame, Series import pandas as pd import numpy as npclass FindType:# 自動執行&#xff0c;將…

山東布谷科技直播平臺搭建游戲開發技術分享:數據存儲的重要意義

在市場上的熱門的直播平臺中&#xff0c;有很多小程序為用戶提供各種各樣的功能&#xff0c;這其中就有很多游戲小程序&#xff0c;當今社會獨生子女眾多&#xff0c;很多作為獨生子女的用戶都會去選擇一個能夠社交互動的APP來填補內心的空虛&#xff0c;而直播平臺的實時互動的…

SAP 選擇屏幕組件名描述翻譯時字符長度不夠問題處理

問題&#xff1a;有時候我們在開發report程序的時候&#xff0c;要求程序顯示支持中英文&#xff0c;如果程序是在中文環境下開發的時候&#xff0c;需要進行翻譯處理&#xff0c;但是我們發現選擇屏幕上的組件的描述支持的默認長度是30位&#xff0c;如果超過該如何處理呢 解…

《路由與交換技術》讀書筆記

小小感悟 工作近3年&#xff0c;基本沒去看路由交換相關書籍&#xff0c;趁著搬家后&#xff0c;周末閑暇時間&#xff0c;快速看了一遍《路由與交換技術》&#xff0c;溫習了一遍&#xff0c;很有收獲&#xff0c;以后還是要多花時間看看其他類型的書。 讀書筆記 1.1 移動通…

構建一個LLM應用所需的所有信息

一、說明 您是否對大型語言模型&#xff08;LLM&#xff09;的潛力感興趣&#xff0c;并渴望創建您的第一個基于LLM的應用程序&#xff1f;或者&#xff0c;也許您是一位經驗豐富的開發人員&#xff0c;希望簡化工作流程&#xff1f;看看DemoGPT就是您的最佳選擇。該工具旨在簡…

【軟件測試】Linux環境下Docker搭建+Docker搭建MySQL服務(詳細)

目錄&#xff1a;導讀 前言 一、Python編程入門到精通二、接口自動化項目實戰三、Web自動化項目實戰四、App自動化項目實戰五、一線大廠簡歷六、測試開發DevOps體系七、常用自動化測試工具八、JMeter性能測試九、總結&#xff08;尾部小驚喜&#xff09; 前言 Linux之docker搭…

CDN(內容分發網絡)

CDN的全稱是 Content Delivery Network, 即內容分發網絡。CDN是構建在現有網絡基礎之上的智能虛擬網絡&#xff0c;依靠部署在各地的邊緣服務器&#xff0c;通過中心平臺的負載均衡、內容分發、調度等功能模塊&#xff0c;使用戶就近獲取所需內容&#xff0c;降低網絡擁塞&a…

詳談MongoDB的那些事

概念區分 什么是關系型數據庫 關系型數據庫&#xff08;Relational Database&#xff09;是一種基于關系模型的數據庫管理系統&#xff08;DBMS&#xff09;。在關系型數據庫中&#xff0c;數據以表格的形式存儲&#xff0c;表格由行和列組成&#xff0c;行表示數據記錄&…

神秘的ip地址8.8.8.8,到底是什么類型的DNS服務器?

下午好&#xff0c;我的網工朋友。 DNS&#xff0c;咱們網工配置網絡連接或者路由器時&#xff0c;高低得和這玩意兒打交道吧。 它是互聯網中用于將人類可讀的域名&#xff08;例如http://www.example.com&#xff09;轉換為計算機可理解的IP地址&#xff08;例如192.0.2.1&a…

元宇宙核能發電VR模擬仿真實訓教學為建設新型電力系統提供重要支撐

隨著“碳達峰、碳中和”目標與建設新型能源體系的提出&#xff0c;在元宇宙環境下建設電力系統是未來發展的趨勢。以物聯網、區塊鏈、數字孿生、混合現實等技術為主要代表的元宇宙技術體系及其在電力和能源系統中的應用&#xff0c;將會促進智能電網的發展&#xff0c;為建設新…

Oracle 知識篇+分區表上的索引由global改為local注意事項

★ 知識點 二、知識點 ?Local型索引有如下優點 1.Only one index partition must be rebuilt when a maintenance operation other than SPLIT PARTITION or ADD PARTITION is performed on an underlying table partition. 2.The duration of a partition maintenance opera…

【uniapp】使用Vs Code開發uniapp:

文章目錄 一、使用命令行創建uniapp項目&#xff1a;二、安裝插件與配置&#xff1a;三、編譯和運行:四、修改pinia&#xff1a; 一、使用命令行創建uniapp項目&#xff1a; 二、安裝插件與配置&#xff1a; 三、編譯和運行: 該項目下的dist》dev》mp-weixin文件導入微信開發者…

unity vscode 代碼關聯 跳轉 BUG

一早打開電腦發現代碼關聯失效了&#xff0c;目測可能跟昨天一些插件更新有關 結論 就這貨&#xff0c;開了就沒法提示代碼關聯&#xff0c;估計預覽版全是BUG。 另一個坑 同期有個unity插件也是預覽版&#xff0c;“非常好使”&#xff0c;當場去世。評論點開有好幾個人說用…

替代阿托斯DLKZOR-T/DLHZO-TES直動式伺服閥比例閥

DLKZOR-T/DLKZOR-TES直動式伺服閥比例閥結構&#xff1a; 1&#xff0c;LVDT傳感器 2&#xff0c;比例電磁鐵 3&#xff0c;閥體 4&#xff0c;閥套 5&#xff0c;閥芯 6&#xff0c;復位彈簧 7&#xff0c;集成數字放大器 8&#xff0c;七芯插頭 9&#xff0c;RS232通…

[保研/考研機試] 楊輝三角形 西北工業大學復試上機題 C++實現

題目描述 Time Limit: 1000 ms Memory Limit: 256 mb 輸入n值&#xff0c;使用遞歸函數&#xff0c;求楊輝三角形中各個位置上的值。 輸入描述: 一個大于等于2的整型數n 輸出描述: 題目可能有多組不同的測試數據&#xff0c;對于每組輸入數據&#xff0c; 按題目的要求輸…

15.3.2 【Linux】系統的配置文件:/etc/crontab,/etc/cron.d/*

這個“ crontab -e ”是針對使用者的 cron 來設計的&#xff0c;如果是“系統的例行性任務”時&#xff0c; 該怎么辦呢&#xff1f;是否還是需要以 crontab -e 來管理你的例行性工作調度呢&#xff1f;當然不需要&#xff0c;你只要編輯/etc/crontab 這個文件就可以。有一點需…

arcpy創建基本要素:點和多點

目錄 創建Point點要素步驟一&#xff1a;創建空間參考步驟二&#xff1a;創建要素類步驟三&#xff1a;創建字段步驟四&#xff1a;創建記錄并插入位置信息 創建Multipoint多點要素步驟一&#xff1a;創建空間參考&#xff08;同上&#xff09;步驟二&#xff1a;創建要素類步驟…

機器學習終極指南:特征工程(01/2) — 第 -2 部分

西姆蘭吉特辛格 一、介紹 歡迎來到“機器學習終極指南”的第二部分。在第一部分中&#xff0c;我們討論了探索性數據分析 &#xff08;EDA&#xff09;&#xff0c;這是機器學習管道中的關鍵步驟。在這一部分中&#xff0c;我們將深入研究特征工程&#xff0c;這是機器學習過程…

使用shift關鍵字,寫一個帶二級命令的腳本(如:docker run -a -b -c中的run)

省流&#xff1a;shift關鍵字 探索思路 最近有一個小小的需求&#xff0c;寫一個類似于docker run -a -b -c這樣的腳本&#xff0c;這個腳本名為doline&#xff0c;它本身可以執行&#xff08;doline -a -b -c&#xff09;&#xff0c;同時又帶有幾個如run、init、start這樣的…

Qt 之 QWidget QLabel

文章目錄 前言一、Qt 工程介紹二、窗口組件1. QWidget 組件2. QLabel組件 總結 前言 一、Qt 工程介紹 Qt Creator 以工程項目的方式對源碼進行管理一個Qt Creator工程包含不同類型的文件 。 .pro 項目描述文件.pro.user用戶配置描述文件- .h頭文件.cpp源文件.ui界面描述文件資…