做者:Choerodon豬齒魚社區 鍾梓凌&黃顯東node
Kubernetes做爲一個容器編排調度引擎,資源調度是它的最基本也是最重要的功能。當開發者部署一個應用時它運行在哪一個節點?這個節點滿不知足開發的運行要求?Kubernetes又是如何進行資源調度的呢?nginx
▌經過本文可瞭解到如下信息:git
在Kubernetes中有一個kube-scheduler組件,該組件運行在master節點上,它主要負責pod的調度。Kube-scheduler監聽kube-apiserver中是否有還未調度到node上的pod(即Spec.NodeName爲空的Pod),再經過特定的算法爲pod指定分派node運行。若是分配失敗,則將該pod放置調度隊列尾部以從新調度。調度主要分爲幾個部分:首先是預選過程,過濾不知足Pod要求的節點。而後是優選過程,對經過要求的節點進行優先級排序,最後選擇優先級最高的節點分配,其中涉及到的兩個關鍵點是過濾和優先級評定的算法。調度器使用一組規則過濾不符合要求的節點,其中包括設置了資源的request和指定了Nodename或者其餘親和性設置等等。優先級評定將過濾獲得的節點列表進行打分,調度器考慮一些總體的優化策略,好比將Deployment控制的多個副本集分配到不一樣節點上等。github
在部署應用時,開發者會考慮到使這個應用運行起來須要多少的內存和CPU資源的使用量,這樣才能判斷應將他運行在哪一個節點上。在部署文件resource屬性中添加requests字段用於說明運行該容器所需的最少資源,當調度器開始調度該Pod時,調度程序確保對於每種資源類型,計劃容器的資源請求總和必須小於節點的容量才能分配該節點運行Pod,resource屬性中添加limits字段用於限制容器運行時所得到的最大資源。若是該容器超出其內存限制,則可能被終止。 若是該容器能夠從新啓動,kubelet會將它從新啓動。若是調度器找不到合適的節點運行Pod時,就會產生調度失敗事件,調度器會將Pod放置調度隊列以循環調度,直到調度完成。算法
在下面例子中,運行一個nginx Pod,資源請求了256Mi的內存和100m的CPU,調度器將判斷哪一個節點還剩餘這麼多的資源,尋找到了以後就會將這個Pod調度上去。同時也設置了512Mi的內存和300m的CPU的使用限制,若是該Pod運行以後超出了這一限制就將被重啓甚至被驅逐。api
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "512Mi" cpu: "300m"
參考文檔:微信
在部署應用後,可使用 kubectl describe 命令進行查看Pod的調度事件,下面是一個coredns被成功調度到node3運行的事件記錄。微服務
$ kubectl describe po coredns-5679d9cd77-d6jp6 -n kube-system ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 29s default-scheduler Successfully assigned kube-system/coredns-5679d9cd77-d6jp6 to node3 Normal Pulled 28s kubelet, node3 Container image "grc.io/kubernetes/coredns:1.2.2" already present on machine Normal Created 28s kubelet, node3 Created container Normal Started 28s kubelet, node3 Started container
下面是一個coredns被調度失敗的事件記錄,根據記錄顯示不可調度的緣由是沒有節點知足該Pod的內存請求。優化
$ kubectl describe po coredns-8447874846-5hpmz -n kube-system ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 22s (x3 over 24s) default-scheduler 0/3 nodes are available: 3 Insufficient memory.
例如開發者須要部署一個ES集羣,因爲ES對磁盤有較高的要求,而集羣中只有一部分節點有SSD磁盤,那麼就須要將標記一下帶有SSD磁盤的節點即給這些節點打上Lable,讓ES的pod只能運行在帶這些標記的節點上。命令行
Lable是附着在K8S對象(如Pod、Service等)上的鍵值對。它能夠在建立對象的時候指定,也能夠在對象建立後隨時指定。Kubernetes最終將對labels最終索引和反向索引用來優化查詢和watch,在UI和命令行中會對它們排序。通俗的說,就是爲K8S對象打上各類標籤,方便選擇和調度。
完整內容,可點擊此處查看:從0到1使用Kubernetes系列(五):Kubernetes Scheduling
Choerodon豬齒魚開源多雲集成平臺,基於開源技術Kubernetes,Istio,knative,Gitlab和Spring Cloud來實現本地和雲端環境的集成,實現企業多雲/混合雲應用環境的一致性。平臺經過提供精益敏捷、持續交付、容器環境、微服務、DevOps等能力來幫助組織團隊來完成軟件的生命週期管理,從而更快、更頻繁地交付更穩定的軟件。
你們也能夠經過如下社區途徑瞭解豬齒魚的最新動態、產品特性,以及參與社區貢獻: