一、Kubernetes 中 Pod 排程的重要性
在 Kubernetes 的世界裡,Pod 排程就像是一個繁忙的交通指揮官,負責把小車(也就是我們的 Pod)送到最合適的停車位(節點)。排程不僅關乎資源的合理利用,還關乎應用的“生死存亡”,下面讓我們來看看為什麼排程這麼重要。
-
資源最佳化: 想象一下,如果每輛小車都隨意停放,那簡直是停車場的災難!排程器透過精確的“停車導航”,確保每個 Pod 找到合適的停車位,最大化利用資源,避免“擠得滿滿當當”。
-
故障恢復: 假設某個節點出故障了,就像一輛車突然拋錨。排程器會迅速反應,把出問題的 Pod 送到其他健康的節點,確保你的應用不至於“趴窩”。
-
負載均衡: 想象一下,如果所有車都停在同一邊,另一邊卻空蕩蕩的,那就會造成交通堵塞。排程器會聰明地把 Pod 分散到各個節點,保持負載均勻,就像一個和諧的舞蹈。
-
策略實施: Kubernetes 排程器可不止是個簡單的指揮官,它還有一套自己的“排程法則”。透過親和、反親和、汙點和容忍等機制,排程器確保每個 Pod 都能按照自己的“喜好”找到理想的駐地,確保萬無一失。
-
可擴充套件性: 當你的應用像氣球一樣迅速膨脹,排程器的靈活性就顯得尤為重要。它可以輕鬆應對負載的變化,動態擴充套件和收縮,確保一切運轉順利。
總之,Pod 排程在 Kubernetes 中就像是後臺默默工作的英雄,保證了應用的高效、安全和穩定。瞭解排程機制,能讓你在這個容器化的世界裡遊刃有餘,簡直是必備技能!
轉載請在文章開頭註明原文地址:https://www.cnblogs.com/Sunzz/p/18451805
二、Node Selector
定義與用法
Node Selector,就像是一位細心的“挑剔”朋友,專門幫你選擇最合適的聚會場地。在Kubernetes中,Node Selector用來告訴排程器,某個Pod需要在特定的節點上執行。透過這種方式,你可以確保你的應用在最合適的環境中“發光發熱”。
想象一下,你的應用是一位超級明星,它希望在擁有高效能顯示卡的節點上演出,而不是在一個配置較低的機器上“打醬油”。Node Selector正是為了滿足這種需求,讓你的Pod在適合它們的舞臺上展現才華。
示例
假設你有一個需要強大磁碟io能力的應用,想把它放在一個“磁碟大咖”的節點上。
給節點設定標籤
先來給node01設定一個disk=ssd的label
kubectl label nodes k8s-node01.local disktype=ssd
檢視一下標籤
kubectl get nodes -l disktype=ssd
NAME STATUS ROLES AGE VERSION
k8s-node01.local Ready <none> 161d v1.30.0
然後使用Node Selector來指定節點的標籤。例如:
# node-selector.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2 # 設定 Pod 副本數為 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80
nodeSelector:
disktype: ssd
建立deployment
kubectl apply -f node-selector.yaml
deployment.apps/nginx-deployment created
kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-56f59878c8-cgfsx 1/1 Running 0 8s 10.244.1.32 k8s-node01.local <none> <none>
nginx-deployment-56f59878c8-z64rz 1/1 Running 0 8s 10.244.1.31 k8s-node01.local <none> <none>
在這個例子中,Pod會被排程到一個標籤為 disktype: ssd
的節點上。這樣,你的超級明星就可以在最佳環境中大放異彩,而不是在普通的節點上苦苦掙扎!
所以,Node Selector就是你的“挑剔朋友”,幫助你的Pod找到最合適的“舞臺”,確保它們能夠充分發揮潛力。
三、親和與反親和
1. 親和(Affinity)
定義
親和,聽起來像個戀愛中的小年輕,其實它是 Kubernetes 中幫助你選擇 Pod 在哪個節點上“約會”的小助手。透過親和規則,Pod 可以被排程到具有特定標籤的節點上,就像在選擇一個合適的地方約會一樣!
型別
1. 節點親和(Node Affinity):
就像在大城市裡找適合自己的房子一樣,節點親和讓你可以將 Pod 排程到具有特定標籤的節點上。比如,你可能想把 Pod 安排在 SSD 硬碟的節點上,因為那兒的效能更好。
2. Pod 親和(Pod Affinity):
如果你想讓某些 Pod 在一起生活,互相照應,Pod 親和就派上用場了。它允許你把新的 Pod 排程到已經存在某個 Pod 的節點上,形成一個“溫暖的大家庭”。
示例
下面是一個部署 Nginx 的 YAML 檔案,使用節點親和來確保 Pod 在帶有 disktype=ssd
標籤的節點上執行:
# affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80
建立deployment
kubectl apply -f affinity.yaml
deployment.apps/nginx-deployment created
kubectl get pods -l app=nginx -o wide
可以看到都執行在node01的節點上。
反親和(Anti-affinity)
定義
反親和是 Kubernetes 中的另一種排程規則,它的目標是避免將 Pod 排程到與某些特定 Pod 相同的節點上。這就像在選擇朋友時,某些人你就是不想和他們一起住,即使他們的房子很漂亮。
用途
反親和通常用於提高應用程式的可用性和容錯性。比如,如果你有多個副本的 Pod,而它們都執行在同一個節點上,那麼這個節點出問題時,所有副本都會受到影響。反親和可以確保它們分佈在不同的節點上,就像把雞蛋放在不同的籃子裡,以免一籃子摔了,雞蛋全沒了。
示例
下面是一個使用反親和規則的 YAML 檔案,確保 Nginx Pod 不會與已經存在的 Nginx Pod 一起執行:
# anti-affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: "kubernetes.io/hostname"
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80
建立deployment
kubectl apply -f anti-affinity.yaml
建立後結果如下圖所示
kubectl get po -l app=nginx -o wide
可以看到已經有兩個pod在執行,分別以node01和node02上,另一個處於peding中。
檢視一下為何處於pending中
kubectl describe pod nginx-deployment-5675f7647f-vgkrl
kubectl describe pod nginx-deployment-5675f7647f-vgkrl
Name: nginx-deployment-5675f7647f-vgkrl
Namespace: default
Priority: 0
Service Account: default
Node: <none>
Labels: app=nginx
pod-template-hash=5675f7647f
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Controlled By: ReplicaSet/nginx-deployment-5675f7647f
Containers:
nginx-container:
Image: nginx:latest
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-qwjc2 (ro)
Conditions:
Type Status
PodScheduled False
Volumes:
kube-api-access-qwjc2:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 2m7s default-scheduler
0/3 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: },
2 node(s) didn't match pod anti-affinity rules.
preemption: 0/3 nodes are available: 1 Preemption is not helpful for scheduling,
2 No preemption victims found for incoming pod.
可以看到最後邊的資訊,說明沒有可用的節點。
轉載請在文章開頭註明原文地址:https://www.cnblogs.com/Sunzz/p/18451805
總結
透過親和與反親和,Kubernetes 可以根據你的需求,精確排程 Pod,就像一位優秀的派對策劃者,確保每個 Pod 在合適的節點上“社交”。這不僅提高了資源利用率,還增強了應用的穩定性。下次部署時,別忘了這些小秘密哦!
四、汙點與容忍:如何讓你的 Pod 不那麼“嬌氣”
汙點(Taints)
定義與用途
汙點,就像一塊“禁止進入”的牌子,告訴某些 Pod:“嘿,別過來,我不想跟你玩!” 它的作用就是讓 Kubernetes 中的節點標記出特殊要求,只有“合適”的 Pod 才能在那裡執行。
比如,你有一個超強的節點,需要做一些高強度的計算任務,那你就可以給這個節點加個“汙點”,這樣普通的 Pod 就不會誤闖進來佔用資源了。
示例
kubectl taint nodes k8s-node01.local key=value:NoSchedule
在這個例子中,我們給節點 k8s-node01.local
新增了一個叫做 key=value
的汙點,並設定為 NoSchedule
。這意味著,除非 Pod 具備容忍這個汙點的“超級能力”,否則 Kubernetes 不會排程任何 Pod 到這個節點上。
來建立deployment測試一下看還會不會排程到node01上去
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
建立deployment
kubectl apply -f deployment.yaml
檢視pod資訊
kubectl get pods -l app=nginx -o wide
可以看到pod都執行在node02上,符合預期,說明汙點生效了,預設是不會往node01去排程的。
容忍(Tolerations)
定義與用途
容忍就是 Pod 的“通行證”,讓它可以無視節點上的“禁止進入”標誌(汙點)。Pod 如果想進駐被“汙點”標記的節點,就必須帶上這個“通行證”才行。這就像是:有些節點很挑剔,但有的 Pod 很“寬容”,它說:“沒關係,我能忍。”
如何配合汙點使用
容忍的作用就是讓 Pod 在被打了汙點的節點上仍然能夠正常排程。這兩者就像是門衛和 VIP 卡的關係——門衛不讓隨便人進,但有 VIP 卡的 Pod 可以說:“我有容忍力,我能過!”
示例:
# tolerations-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
解釋:
- apiVersion:
apps/v1
表示我們建立的是Deployment
資源,Kubernetes 中的Deployment
用於管理應用的副本集(即多個 Pod)。 - replicas: 定義了我們希望建立的
nginx
Pod 的副本數量,這裡我們設定為2
,因此會有兩個nginx
Pod。 - selector:
matchLabels
透過app: nginx
標籤選擇需要管理的 Pod。 - template: 定義了要部署的 Pod 模板,包括容忍設定和容器規範。
- tolerations: 配置了這個
nginx
Deployment 的 Pod 可以容忍有特定key=value:NoSchedule
汙點的節點,允許它們被排程到帶有該汙點的節點上。 - containers: Pod 內的容器,這裡使用
nginx:latest
映象,並暴露埠 80。
這個配置部署了兩個 nginx
Pod,並且允許它們被排程到有特定汙點的節點上(根據配置的 tolerations
)。
建立deployment
kubectl get po -l app=nginx -o wide
這個示例 Pod 中的 tolerations
配置,允許它無視 key=value:NoSchedule
這樣的汙點,順利地跑到有“汙點”的節點上。
汙點與容忍,誰才是排程的老大?
總結一下,汙點是節點上的“門禁”,防止無關 Pod 來搗亂,而容忍就是 Pod 的“VIP 卡”,讓它無視門禁,照樣可以順利進駐。這兩者相輔相成,是 Kubernetes 排程機制中不可或缺的一部分。
有了這些設定,你就可以有效地控制哪些 Pod 能夠執行在哪些節點上。記住:帶上“通行證”,你就不怕節點的“臭脾氣”了!
轉載請在文章開頭註明原文地址:https://www.cnblogs.com/Sunzz/p/18451805
五、優先順序與搶佔:Kubernetes 的「大佬」排程策略
在 Kubernetes 世界中,Pod 不再是平等的。是的,Pod 也有「大佬」和「小透明」之分!這一切全靠優先順序(Priority)和搶佔(Preemption)來決定。讓我們一起看看這兩位神秘力量如何影響 Pod 的命運吧!
優先順序(Priority): 誰是大佬?
定義:
優先順序就是給 Pod 排座次的機制。Kubernetes 允許你給每個 Pod 設定一個「重要程度」,這個重要程度就決定了它在資源緊張時,是被優先照顧,還是默默無聞地排隊。
如何設定:
我們需要先定義一個 PriorityClass
,然後在 Nginx 的 Deployment
裡引用它。就像是給 Nginx 發了一張“貴賓卡”。
# priority.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false
description: "High priority for important Nginx pods."
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
priorityClassName: high-priority
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
解釋: 我們建立了一個名為 high-priority
的優先順序類,給它賦值 1000,然後用這個優先順序類部署了兩個 Nginx Pod。這意味著這些 Nginx Pod 在資源排程上會得到特別的優待,資源緊張時它們會優先被分配。
建立deployment
kubectl apply -f priority.yaml
檢視pod資訊
kubectl get po -l app=nginx -o wide
kubectl describe pod nginx-deployment-646cb6c499-6k864
搶佔(Preemption):Nginx 也能“趕人”?
定義: 搶佔就像給 Nginx 一個特權,告訴 Kubernetes 如果資源緊張,允許這個高優先順序的 Pod 搶佔低優先順序 Pod 的位置。這樣,Nginx 能在關鍵時刻優雅地“趕走”別人,自己穩穩上場。
示例:
# preemption.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: vip-priority
value: 2000
preemptionPolicy: PreemptLowerPriority
globalDefault: false
description: "VIP Nginx pods with preemption power."
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-vip
spec:
replicas: 2
selector:
matchLabels:
app: nginx-vip
template:
metadata:
labels:
app: nginx-vip
spec:
priorityClassName: vip-priority
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
解釋: 這裡,我們為 vip-priority
類的 Nginx Pod 賦予了“搶佔”特權。如果資源不足,系統會強制“請走”低優先順序的 Pod,讓 Nginx VIP 順利登場。
建立
kubectl apply -f preemption.yaml
檢視pod資訊
總結:
透過設定優先順序,我們可以讓某些重要的 Nginx Pod 享有排程特權,而透過搶佔,它們甚至能趕走低優先順序的 Pod,佔據寶貴的資源位。用這種方式,Nginx 不僅能在伺服器上跑得快,還能在排程策略上“先發制人”!
六、排程策略:誰來決定 Nginx Pod 住哪裡?
Kubernetes 的排程器就是負責給 Pod 找房子的“房屋中介”。它得看哪兒房源充足、住得舒服,同時還得考慮全域性平衡。Pod 會被分配到哪臺節點上執行,背後其實有一套策略。下面我們來深挖幾種常見的排程策略,看看 Nginx Pod 是怎麼找到“新家”的。
輪詢排程(Round Robin):大家輪著來,公平第一!
通俗解釋:
就像大家吃火鍋的時候,食材一輪輪下鍋,誰都不會落下。輪詢排程按順序遍歷節點,把 Pod 均勻地分配到每個節點上。節點A、B、C都分到活兒,不會讓某個節點忙死,而其他節點閒得發黴。
舉個例子:
Nginx Pod 1 給節點A,Pod 2 給節點B,Pod 3 給節點C,下一個再輪到A。
優點:簡單公平,特別適合資源相對均衡的情況,能避免某個節點過載。
缺點:輪著來不等於“聰明地來”,有可能會給那些快要爆滿的節點安排更多工,徒增壓力。
七、Volume Affinity:Pod 和儲存卷的“宿命連結”!
定義與用途:
你知道 Pod 和 Volume 之間的關係嗎?它們的默契就像“靈魂伴侶”。在 Kubernetes 世界裡,Volume Affinity 就是確保 Pod 能和它最需要的儲存卷待在一起,不分離、不斷電。這個機制會讓儲存卷和 Pod 彼此靠得更近,就像給你的 Pod 安裝了“GPS”,確保它們的儲存資料觸手可及。
舉個通俗例子:
想象一下,你的 Pod 就像一個咖啡師,而儲存卷就是它的咖啡豆倉庫。Volume Affinity 確保咖啡師不會跑到一個沒有咖啡豆的地方開店,簡直是開店之前先定好倉庫的節奏!這讓 Pod 不用擔心去取遠在天邊的儲存資料,一切就近服務,方便又高效。
例子:Nginx 和它的專屬“儲存豆倉”
我們再用熟悉的 Nginx 舉個例子。假設我們想要 Nginx Pod 和它的儲存卷靠得近一些,Volume Affinity 會幫忙安排這個“親密關係”。
# volume-affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: nginx-storage
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-storage
persistentVolumeClaim:
claimName: nginx-pvc
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: "kubernetes.io/hostname"
總結:排程機制,Kubernetes 的“資源排程大師”!