找人幫你做PPT的網(wǎng)站網(wǎng)站關鍵詞搜索
基本概念
Pod是K8S中非常重要的概念之一,是整個K8S架構的基礎和核心。Pod是K8S調度的最小單位,是一個不可拆分的獨立個體,K8S將多個業(yè)務上相關聯(lián)的容器(Docker容器)合并到一起,組合成一個Pod,這些業(yè)務上相關的容器共享Pod中的網(wǎng)絡和存儲等資源。每個Pod都有一個唯一的IP地址,Pod中的所有容器都共享此IP地址。每個Pod在創(chuàng)建的時候K8S都會為其先創(chuàng)建一個根容器,即Sandbox容器或Pause容器,這個容器非常簡單,就是一個主要包含for代碼的死循環(huán),起一個占位的作用。K8S先會為Pause容器分配網(wǎng)絡命名空間,存儲資源等,當在創(chuàng)建其它用戶容器時,K8S只需要將這些用戶容器加入到Pause容器即可,這樣就實現(xiàn)了網(wǎng)絡和存儲資源的共享。
Pod分為普通Pod和靜態(tài)Pod,如果沒有特別說明,我們通常都使用普通Pod。靜態(tài)Pod不常使用,其僅存在于特定的Node上,由kubelet進程管理,也無法與Deployment,DaemonSet等進行關聯(lián),其作用可能只是為了在某個特定的Node上做一些特殊的事情。
雖然Pod是K8S的最小調度單元,但絕大多數(shù)情況我們都不會直接創(chuàng)建一個Pod,因為其不具備副本管理,滾動升級等高級特性。通常都通過控制器來創(chuàng)建,如Deployment,DaemonSet,Job等。
Pod中容器共享Volume
只需要在Pod級別的配置中設置Volumes,可以是hostPath,emptyDir等等,然后在容器級別的配置中為不同的容器mount此Volume即可。
ConfigMap
ConfigMap用于設置Pod內容器的參數(shù)信息,如容器中進程監(jiān)聽的端口號,進程的命令行參數(shù),對外依賴的服務名稱等,能夠實現(xiàn)應用和配置的有效分離。當然,這些配置信息都可以在Pod的yaml的定義中通過環(huán)境變量來指定,即給定一個環(huán)境變量名,然后寫上此環(huán)境變量的值。但是有一個問題,如果Pod已經(jīng)在運行,此時要修改Pod的某個配置參數(shù),這將非常麻煩。一種做法是先把已經(jīng)運行的Pod刪除,再在yaml中修改配置參數(shù),最后再apply此yaml。這個方法很粗暴,因為刪除Pod的時候會導致Pod無法提供服務。最好的做法是使用ConfigMap,本質上ConfigMap也是設置環(huán)境變量,不同的是該環(huán)境變量的值沒有hardcode,而是引用了某個ConfigMap。如果ConfigMap發(fā)生了改變,K8S會自動修改引用了該ConfigMap的Pod中對應的環(huán)境變量的值。
ConfigMap的使用很靈活,可以是key-value的形式,也可以是配置文件的形式,可以在定義ConfigMap的yaml中寫上配置文件的全部內容,也可以指定從某個路徑引用配置文件。
注意:如果要傳遞敏感配置,如密碼,key等,需要使用Secret,而不是ConfigMap。
Downward API
如果Pod中的容器需要知道自己所屬Pod的配置信息,如Pod名稱,命名空間,IP地址,注解,Label,CPU Limit,Memory Limit等,可以使用Downward API在Pod的yaml定義中,使用環(huán)境變量或Volume掛載的方式傳入到Pod的容器中。在很多場景下這些metadata數(shù)據(jù)都很有用,例如,在記錄log的時候,可以帶上pod名稱用于標識log來源。
生命周期和重啟策略
Pod的生命周期包含從Pod創(chuàng)建到Pod消亡的整個過程,通過Pod的狀態(tài)可以標識不同的生命周期階段。
Pending:API Server已經(jīng)創(chuàng)建了Pod,但是Pod中至少還有一個容器沒有被完全創(chuàng)建好,例如正在下載image。
Running:Pod中的所有容器都已創(chuàng)建,且正在運行。
Succeed:Pod中的容器都已經(jīng)成功運行且正常退出,不會再重啟。
Failed:Pod中的容器都已退出,但至少有一個的退出狀態(tài)為失敗。
Unknown:Pod狀態(tài)未知。
Pod的重啟策略包括Always,OnFailure和Never。
Always:當容器退出時(可能是正?;蚴⊥顺?#xff09;,由kubelet自動創(chuàng)建。
OnFailure:當容器以失敗的方式退出時,由kubelet自動創(chuàng)建。
Never:任何情況都不重啟。
重啟策略還和控制器類別有關,例如Deployment和DaemonSet,重啟策略只能是Always,因為這兩種控制器都要求容器不能退出,需要一直運行來提供服務。Job和CronJob可以是OnFailure或Never。
健康檢查和服務可用性檢查
可以使用三類探針來判斷某個容器是否正常,LivenessProbe,ReadinessProbe和StartupProbe。
LivenessProbe:用于判斷容器是否還存活(Running),如果容器被判定沒有存活,則K8S會kill此容器,并嘗試重啟。注意:這里是容器,不是Pod。
ReadinessProbe:用于判斷容器能否正常提供服務,如果不能提供服務,則不會把容器加入到Endpoints列表中。注意和LivenessProbe的區(qū)別,如果容器是Running的狀態(tài),則可能是Ready或者不是Ready,如果不是Running的狀態(tài),肯定就不是Ready了。
StartupProbe:用于在容器創(chuàng)建時可能會占用很長時間的場景,通過StartupProbe能判斷容器是否正常啟動,屬于“有且僅有一次”的長時間等待的檢查。
Pod控制器
通過Pod控制器可以實現(xiàn)Pod的自動調度,控制器包括Deployment,ReplicaSet,Replication Controller,DaemonSet,StatefulSet,Operator,Job,CronJob等,參考(Controller部分)https://blog.csdn.net/funnyrand/article/details/135759060
NodeSelector
NodeSelector屬于基于Node的定向調度,通過在Pod的yaml中設置nodeSelector,可以將Pod只調度到給定標簽的Node上。這是比較舊的一種方式,控制粒度粗,但簡單適用。
NodeAffinity/NodeAntiAffinity
在Node層面定義的一些規(guī)則,用于替換NodeSelector,可以很精確的控制將Pod調度到哪些Node上或者不調度到哪些Node上,有很靈活的匹配規(guī)則。
PodAffinity/PodAntiAffinity
在Pod層面定義的一些規(guī)則,用于控制Pod與Pod的親和性和反親和性,即希望哪些Pod能調度到一起,哪些Pod不能調度到一起。例如,在進行Server-Client的兩節(jié)點測試中,我們希望部署在Server上的Pod和部署到Client上的Pod不能部署到一起,而不管它們部署到Node1還是Node2,只要不同時部署到一起即可。
Taints和Tolerations
污點和容忍,如果對某個Node設置了Taints,默認情況下K8S不會把Pod調度到此節(jié)點上,可能的原因是該Node的磁盤已滿,內存不夠,網(wǎng)速很慢,系統(tǒng)出現(xiàn)故障,Node需要維護,系統(tǒng)需要升級等。如果想讓某個Pod被自動調度到Taints的Node上,需要在Pod的yaml中設置tolerations配置,標識此Pod能夠容忍對應的Taints。
優(yōu)先級調度
不同的Pod的優(yōu)先級可能不一樣,通過創(chuàng)建PriorityClass資源,并為Pod設置不同的PriorityClass可以控制Pod的優(yōu)先級,K8S會優(yōu)先調度高優(yōu)先級的Pod。如果在創(chuàng)建某個高優(yōu)先級的Pod時系統(tǒng)資源不夠,例如,CPU和內存無法滿足Limits的要求,此時K8S可能會驅逐(Evication)已經(jīng)存在的低優(yōu)先級的Pod。這里面的規(guī)則比較復雜,和QoS等配置也有關系。一般情況,讓K8S驅逐已經(jīng)存在的Pod是高風險操作,需要謹慎。
容災調度
對于一個很大的K8S集群,集群中的Node可能分布在不同的區(qū)域(Zone),為了容災的考慮,我們在創(chuàng)建某個Pod的時候希望在每個區(qū)域都能創(chuàng)建這個Pod,這里可以使用容災調度。通過設置Pod的topologySpreadConstraints屬性,并結合Node的topology.kubenetes.io/zone屬性能夠方便實現(xiàn)該需求。
自定義調度
如果K8S內置的調度策略無法滿足我們的需求,我們可以實現(xiàn)自己的調度器。調度器的作用就是給定某個Pod,通過自定義的調度器的運算能夠輸出一個Node的名字,然后調用K8S的API(http://$SERVER/aip/v1/namespaces/default/pods/$PODNAME/binding),將Pod綁定到選擇的Node上。自定義調度器可以用任何語言來實現(xiàn)。
初始化容器
初始化容器用于業(yè)務容器創(chuàng)建前的初始化工作,例如網(wǎng)絡連通性檢查,存儲資源的創(chuàng)建等。通過initContainers可以為Pod配置多個初始化容器,K8S會按順序執(zhí)行每個初始化容器,只有所有的初始化容器都成功退出后,K8S才會創(chuàng)建和執(zhí)行業(yè)務容器。
升級/回滾
Pod的升級/回滾通常針對Deployment控制器,如果直接創(chuàng)建Pod,則不具備此功能。
升級:如果某些Pod已經(jīng)部署且正常運行,現(xiàn)在需要對Pod的Image升級,有三種做法,1)通過kubelet set image命令指定新的Image。2)通過kubelet edit deployment/deployment-xxx命令修改Deployment。3)手動修改yaml文件,然后再apply。升級的基本原理是K8S會創(chuàng)建一個新的ReplicaSet,并將副本數(shù)量設置為1,然后將舊的ReplicaSet的數(shù)量減1,接著依次進行加1和減1,直到舊的ReplicaSet的數(shù)量為0。
回滾:如果在升級過程中發(fā)現(xiàn)Image的版本不正確(錯誤的版本或不存在的版本等),可以回滾Deployment。通過命令kubelet rollout status deployment/deployment-xxx查看Deployment當前部署狀態(tài),然后通過命令kubelet rollout history deployment/deployment-xxx查看這個Deployment的歷史記錄(這里會輸出Deployment的REVISION),最后通過命令kubelet rollout undo deployment/deployment-xxx --to-revision=N來指定回到某個Deployment的版本。
對于多個配置的修改,可以先暫定Deployment的升級執(zhí)行,等這些配置都全部修改完成后再一次性升級。相關命令:kubelet rollout pause deployment/deployment-xxx,kubelet rollout resume deployment/deployment-xxx。
DaemonSet和StatefulSet的升級與Deployment的升級稍有不同,其通過不同的策略來完成升級,這里不詳細說明。
擴容/縮容
分為手動和自動兩種模式,手動擴容/縮容可以通過命令kubelet scal命令完成,自動擴容/縮容通過HPA功能完成。
通過HPA(Horizontal Pod Autoscaler)我們可以方便的使Pod自動擴容/縮容,例如,在業(yè)務量很大的時候自動增加Pod數(shù)量,在業(yè)務量很少的時候自動減少Pod數(shù)量。業(yè)務量的大小可以通過CPU使用率,內存使用率,或者自定義的某個指標來判斷,自定義指標需要容器通過HTTP URL的形式返回給K8S。