響應(yīng)式布局網(wǎng)頁seo入門教程視頻
調(diào)度約束
Kubernetes 是通過 List-Watch ? ?**** 的機(jī)制進(jìn)行每個組件的協(xié)作,保持?jǐn)?shù)據(jù)同步的,每個組件之間的設(shè)計實現(xiàn)了解耦。
用戶是通過 kubectl 根據(jù)配置文件,向 APIServer 發(fā)送命令,在 Node 節(jié)點上面建立 Pod 和 Container。
APIServer 經(jīng)過 API 調(diào)用,權(quán)限控制,調(diào)用資源和存儲資源的過程,實際上還沒有真正開始部署應(yīng)用。這里?? ?需要 Controller Manager、Scheduler 和 kubelet 的協(xié)助才能完成整個部署過程。
在 Kubernetes 中,所有部署的信息都會寫到 etcd 中保存。實際上 etcd 在存儲部署信息的時候,會發(fā)送 Create 事件給 APIServer,而 APIServer 會通過監(jiān)聽(Watch)etcd 發(fā)過來的事件。其他組件也會監(jiān)聽(Watch)APIServer 發(fā)出來的事件。
Pod 是 Kubernetes 的基礎(chǔ)單元,Pod 啟動典型創(chuàng)建過程如下: ? ?工作機(jī)制 ****
(1)這里有三個 List-Watch,分別是 Controller Manager(運行在 Master),Scheduler(運行在 Master),kubelet(運行在 Node)。 他們在進(jìn)程已啟動就會監(jiān)聽(Watch)APIServer 發(fā)出來的事件。
(2)用戶通過 kubectl 或其他 API 客戶端提交請求給 APIServer 來建立一個 Pod 對象副本。
(3)APIServer 嘗試著將 Pod 對象的相關(guān)元信息存入 etcd 中,待寫入操作執(zhí)行完成,APIServer 即會返回確認(rèn)信息至客戶端。
(4)當(dāng) etcd 接受創(chuàng)建 Pod 信息以后,會發(fā)送一個 Create 事件給 APIServer。
(5)由于 Controller Manager 一直在監(jiān)聽(Watch,通過https的6443端口)APIServer 中的事件。此時 APIServer 接受到了 Create 事件,又會發(fā)送給 Controller Manager。
(6)Controller Manager 在接到 Create 事件以后,調(diào)用其中的 Replication Controller 來保證 Node 上面需要創(chuàng)建的副本數(shù)量。一旦副本數(shù)量少于 RC 中定義的數(shù)量,RC 會自動創(chuàng)建副本??傊潜WC副本數(shù)量的 Controller(PS:擴(kuò)容縮容的擔(dān)當(dāng))。
(7)在 Controller Manager 創(chuàng)建 Pod 副本以后,APIServer 會在 etcd 中記錄這個 Pod 的詳細(xì)信息。例如 Pod 的副本數(shù),Container 的內(nèi)容是什么。
(8)同樣的 etcd 會將創(chuàng)建 Pod 的信息通過事件發(fā)送給 APIServer。
(9)由于 Scheduler 在監(jiān)聽(Watch)APIServer,并且它在系統(tǒng)中起到了“承上啟下”的作用,“承上”是指它負(fù)責(zé)接收創(chuàng)建的 Pod 事件,為其安排 Node;“啟下”是指安置工作完成后,Node 上的 kubelet 進(jìn)程會接管后繼工作,負(fù)責(zé) Pod 生命周期中的“下半生”。 換句話說,Scheduler 的作用是將待調(diào)度的 Pod 按照調(diào)度算法和策略綁定到集群中 Node 上。
(10)Scheduler 調(diào)度完畢以后會更新 Pod 的信息,此時的信息更加豐富了。除了知道 Pod 的副本數(shù)量,副本內(nèi)容。還知道部署到哪個 Node 上面了。并將上面的 Pod 信息更新至 API Server,由 APIServer 更新至 etcd 中,保存起來。
(11)etcd 將更新成功的事件發(fā)送給 APIServer,APIServer 也開始反映此 Pod 對象的調(diào)度結(jié)果。
(12)kubelet 是在 Node 上面運行的進(jìn)程,它也通過 List-Watch 的方式監(jiān)聽(Watch,通過https的6443端口)APIServer 發(fā)送的 Pod 更新的事件。kubelet 會嘗試在當(dāng)前節(jié)點上調(diào)用 Docker 啟動容器,并將 Pod 以及容器的結(jié)果狀態(tài)回送至 APIServer。
(13)APIServer 將 Pod 狀態(tài)信息存入 etcd 中。在 etcd 確認(rèn)寫入操作成功完成后,APIServer將確認(rèn)信息發(fā)送至相關(guān)的 kubelet,事件將通過它被接受。
#注意:在創(chuàng)建 Pod 的工作就已經(jīng)完成了后,為什么 kubelet 還要一直監(jiān)聽呢?原因很簡單,假設(shè)這個時候 kubectl 發(fā)命令,要擴(kuò)充 Pod 副本數(shù)量,那么上面的流程又會觸發(fā)一遍,kubelet 會根據(jù)最新的 Pod 的部署情況調(diào)整 Node 的資源。又或者 Pod 副本數(shù)量沒有發(fā)生變化,但是其中的鏡像文件升級了,kubelet 也會自動獲取最新的鏡像文件并且加載。
//調(diào)度過程 ? ***
Scheduler 是 kubernetes 的調(diào)度器,主要的任務(wù)是把定義的 pod 分配到集群的節(jié)點上。其主要考慮的問題如下:
●公平:如何保證每個節(jié)點都能被分配資源
●資源高效利用:集群所有資源最大化被使用
●效率:調(diào)度的性能要好,能夠盡快地對大批量的 pod 完成調(diào)度工作
●靈活:允許用戶根據(jù)自己的需求控制調(diào)度的邏輯
Sheduler 是作為單獨的程序運行的,啟動之后會一直監(jiān)聽 APIServer,獲取 spec.nodeName 為空的 pod,對每個 pod 都會創(chuàng)建一個 binding,表明該 pod 應(yīng)該放到哪個節(jié)點上。
調(diào)度分為幾個部分:首先是過濾掉不滿足條件的節(jié)點,這個過程稱為預(yù)算策略(predicate);然后對通過的節(jié)點按照優(yōu)先級排序,這個是優(yōu)選策略(priorities);最后從中選擇優(yōu)先級最高的節(jié)點。如果中間任何一步驟有錯誤,就直接返回錯誤。
Predicate 有一系列的常見的算法可以使用: ? ? **
●PodFitsResources:節(jié)點上剩余的資源是否大于 pod 請求的資源nodeName,檢查節(jié)點名稱是否和 NodeName 匹配。。
●PodFitsHost:如果 pod 指定了 NodeName,檢查節(jié)點名稱是否和 NodeName 匹配。
●PodFitsHostPorts:節(jié)點上已經(jīng)使用的 port 是否和 pod 申請的 port 沖突。
●PodSelectorMatches:過濾掉和 pod 指定的 label 不匹配的節(jié)點。?
●NoDiskConflict:已經(jīng) mount 的 volume 和 pod 指定的 volume 不沖突,除非它們都是只讀。
如果在 predicate 過程中沒有合適的節(jié)點,pod 會一直在 pending 狀態(tài),不斷重試調(diào)度,直到有節(jié)點滿足條件。 經(jīng)過這個步驟,如果有多個節(jié)點滿足條件,就繼續(xù) priorities 過程:按照優(yōu)先級大小對節(jié)點排序。
優(yōu)先級由一系列鍵值對組成,鍵是該優(yōu)先級項的名稱,值是它的權(quán)重(該項的重要性)。有一系列的常見的優(yōu)先級選項包括:
●LeastRequestedPriority:通過計算CPU和Memory的使用率來決定權(quán)重,使用率越低權(quán)重越高。也就是說,這個優(yōu)先級指標(biāo)傾向于資源使用比例更低的節(jié)點。
●BalancedResourceAllocation:節(jié)點上 CPU 和 Memory 使用率越接近,權(quán)重越高。這個一般和上面的一起使用,不單獨使用。比如 node01 的 CPU 和 Memory 使用率 20:60,node02 的 CPU 和 Memory 使用率 50:50,雖然 node01 的總使用率比 node02 低,但 node02 的 CPU 和 Memory 使用率更接近,從而調(diào)度時會優(yōu)選 node02。
●ImageLocalityPriority:傾向于已經(jīng)有要使用鏡像的節(jié)點,鏡像總大小值越大,權(quán)重越高。
通過算法對所有的優(yōu)先級項目和權(quán)重進(jìn)行計算,得出最終的結(jié)果。
//指定調(diào)度節(jié)點:
●pod.spec.nodeName 將 Pod 直接調(diào)度到指定的 Node 節(jié)點上,會跳過 Scheduler 的調(diào)度策略,該匹配規(guī)則是強(qiáng)制匹配
vim myapp.yaml
apiVersion: apps/v1 ?
kind: Deployment ?
metadata:
? name: myapp
spec:
? replicas: 3
? selector:
? ? matchLabels:
? ? ? app: myapp
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: myapp
? ? spec:
? ? ? nodeName: node01
? ? ? containers:
? ? ? - name: myapp
? ? ? ? image: soscscs/myapp:v1
? ? ? ? ports:
? ? ? ? - containerPort: 80
?? ??? ?
kubectl apply -f myapp.yaml
kubectl 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>
//查看詳細(xì)事件(發(fā)現(xiàn)未經(jīng)過 scheduler 調(diào)度分配)
kubectl describe pod myapp-6bc58d7775-6wlpp
......
?Type ? ?Reason ? Age ? From ? ? ? ? ? ? Message
? ---- ? ?------ ? ---- ?---- ? ? ? ? ? ? -------
? Normal ?Pulled ? 95s ? kubelet, node01 ?Container image "soscscs/myapp:v1" already present on machine
? Normal ?Created ?99s ? kubelet, node01 ?Created container nginx
? Normal ?Started ?99s ? kubelet, node01 ?Started container nginx
●pod.spec.nodeSelector:通過 kubernetes 的 label-selector 機(jī)制選擇節(jié)點,由調(diào)度器調(diào)度策略匹配 label,然后調(diào)度 Pod 到目標(biāo)節(jié)點,該匹配規(guī)則屬于強(qiáng)制約束
//獲取標(biāo)簽幫助
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
//給對應(yīng)的 node 設(shè)置標(biāo)簽分別為 kgc=a 和 kgc=b
kubectl label nodes node01 kgc=a
kubectl label nodes node02 kgc=b
//查看標(biāo)簽
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 調(diào)度方式
vim myapp1.yaml
apiVersion: apps/v1
kind: Deployment ?
metadata:
? name: myapp1
spec:
? replicas: 3
? selector:
? ? matchLabels:
? ? ? app: myapp1
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: myapp1
? ? spec:
? ? ? nodeSelector:
?? ? ? ?kgc: a
? ? ? containers:
? ? ? - name: myapp1
? ? ? ? image: soscscs/myapp:v1
? ? ? ? ports:
? ? ? ? - containerPort: 80
kubectl 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>
//查看詳細(xì)事件(通過事件可以發(fā)現(xiàn)要先經(jīng)過 scheduler 調(diào)度分配)
kubectl describe pod myapp1-58cff4d75-52xm5
Events:
? Type ? ?Reason ? ? Age ? From ? ? ? ? ? ? ? Message
? ---- ? ?------ ? ? ---- ?---- ? ? ? ? ? ? ? -------
? Normal ?Scheduled ?57s ? default-scheduler ?Successfully assigned default/myapp1-58cff4d75-52xm5 to node01
? Normal ?Pulled ? ? 57s ? kubelet, node01 ? ?Container image "soscscs/myapp:v1" already present on machine
? Normal ?Created ? ?56s ? kubelet, node01 ? ?Created container myapp1
? Normal ?Started ? ?56s ? kubelet, node01 ? ?Started container myapp1
//修改一個 label 的值,需要加上 --overwrite 參數(shù)
kubectl label nodes node02 kgc=a --overwrite
//刪除一個 label,只需在命令行最后指定 label 的 key 名并與一個減號相連即可:
kubectl label nodes node02 kgc-
//指定標(biāo)簽查詢 node 節(jié)點
kubectl get node -l kgc=a