本活動在微信公衆號【個人小碗湯】上舉行,有送書活動!這裏參與答題不能參與到送書活動哦!
經過命令行,使用nginx鏡像建立一個pod並手動調度到節點名爲node1121節點上,Pod的名稱爲cka-1121,答題最好附上,所用命令、建立Pod所需最精簡的yaml;若是評論有限制,請把注意點列出,主要需列出手動調度怎麼作?
注意:手動調度是指不須要通過kube-scheduler去調度。
將名稱爲cka-1121的Pod,調度到節點node1121:java
apiVersion: v1 kind: Pod metadata: name: cka-1121 labels: app: cka-1121 spec: containers: - name: cka-1121 image: busybox command: ['sh', '-c', 'echo Hello CKA! && sleep 3600'] nodeName: node1121
官網中調度器地址:
https://kubernetes.io/docs/co...
調度器命令行參數:
https://kubernetes.io/docs/re...node
調度器kube-scheduler分爲預選、優選、pod優先級搶佔、bind階段;nginx
預選:從podQueue的待調度隊列中彈出須要調度的pod,先進入預選階段,預選函數來判斷每一個節點是否適合被該Pod調度。golang
優選:從預選篩選出的知足的節點中選擇出最優的節點。docker
pod優先級搶佔:若是預選和優選調度失敗,則會嘗試將優先級低的pod剔除,讓優先級高的pod調度成功。shell
bind:上述步驟完成後,調度器會更新本地緩存,但最後須要將綁定結果提交到etcd中,須要調用Apiserver的Bind接口完成。segmentfault
如下k8s源碼版本爲1.13.2
咱們去查看kube-scheduler源碼,調度器經過list-watch機制,監聽集羣內Pod的新增、更新、刪除事件,調用回調函數。指定nodeName後將不會放入到未調度的podQueue隊列中,也就不會走上面這幾個階段。具體能夠來到pkgschedulerfactoryfactory.go源碼中的NewConfigFactory函數中:
其中在構建pod資源對象新增、更新、刪除的回調函數時,分已被調度的和未被調度的回調。api
已被調度的回調:
已被調度的pod根據FilterFunc中定義的邏輯過濾,nodeName不爲空,返回true時,將會走Handler中定義的AddFunc、UpdateFunc、DeleteFunc,這個其實最終不會加入到podQueue中,但須要加入到本地緩存中,由於調度器會維護一份節點上pod列表的緩存。緩存
// scheduled pod cache 已被調度的 args.PodInformer.Informer().AddEventHandler( cache.FilteringResourceEventHandler{ FilterFunc: func(obj interface{}) bool { switch t := obj.(type) { case *v1.Pod: //nodeName不爲空,返回true;且返回true時將被走AddFunc、UpdateFunc、DeleteFunc,這個其實最終不會加入到podQueue中 return assignedPod(t) case cache.DeletedFinalStateUnknown: if pod, ok := t.Obj.(*v1.Pod); ok { return assignedPod(pod) } runtime.HandleError(fmt.Errorf("unable to convert object %T to *v1.Pod in %T", obj, c)) return false default: runtime.HandleError(fmt.Errorf("unable to handle object in %T: %T", c, obj)) return false } }, Handler: cache.ResourceEventHandlerFuncs{ AddFunc: c.addPodToCache, UpdateFunc: c.updatePodInCache, DeleteFunc: c.deletePodFromCache, }, }, )
未被調度的回調:
未被調度的pod根據FilterFunc中定義的邏輯過濾,nodeName爲空且pod的SchedulerName和該調度器的名稱一致時返回true;返回true時,將會走Handler中定義的AddFunc、UpdateFunc、DeleteFunc,這個最終會加入到podQueue中。微信
// unscheduled pod queue 沒有被調度的 args.PodInformer.Informer().AddEventHandler( cache.FilteringResourceEventHandler{ FilterFunc: func(obj interface{}) bool { switch t := obj.(type) { case *v1.Pod: //nodeName爲空且pod的SchedulerName和該調度器的名稱一致時返回true;且返回true時將被加入到pod queue return !assignedPod(t) && responsibleForPod(t, args.SchedulerName) case cache.DeletedFinalStateUnknown: if pod, ok := t.Obj.(*v1.Pod); ok { return !assignedPod(pod) && responsibleForPod(pod, args.SchedulerName) } runtime.HandleError(fmt.Errorf("unable to convert object %T to *v1.Pod in %T", obj, c)) return false default: runtime.HandleError(fmt.Errorf("unable to handle object in %T: %T", c, obj)) return false } }, Handler: cache.ResourceEventHandlerFuncs{ AddFunc: c.addPodToSchedulingQueue, UpdateFunc: c.updatePodInSchedulingQueue, DeleteFunc: c.deletePodFromSchedulingQueue, }, }, )
手動調度適用場景:
擴展點:
昨天的留言中,有人提到static Pod,這種其實也屬於節點固定,但這種Pod侷限很大,好比:不能掛載configmaps和secrets等,這個由Admission Controllers控制。
下面簡單說一下靜態Pod:
靜態Pod官網說明:
https://kubernetes.io/docs/ta...
靜態 pod指在特定的節點上直接經過 kubelet守護進程進行管理,APIServer沒法管理。它沒有跟任何的控制器進行關聯,kubelet 守護進程對它進行監控,若是崩潰了,kubelet 守護進程會重啓它。Kubelet 經過APIServer爲每一個靜態 pod 建立 鏡像 pod,這些鏡像 pod 對於 APIServer是可見的(即kubectl能夠查詢到這些Pod),可是不受APIServer控制。
具體static pod yaml文件放到哪裏,須要在kubelet配置中指定,先找到kubelet配置文件:
systemctl status kubelet
找到config.yaml文件:
裏面指定了staticPodPath:
kubeadm安裝的集羣,master節點上的kube-apiserver、kube-scheduler、kube-controller-manager、etcd就是經過static Pod方式部署的:
經過命令行,建立兩個deployment。
- 須要集羣中有2個節點 ;
- 第1個deployment名稱爲cka-1122-01,使用nginx鏡像,有2個pod,並配置該deployment自身的pod之間在節點級別反親和;
- 第2個deployment名稱爲cka-1122-02,使用nginx鏡像,有2個pod,並配置該deployment的pod與第1個deployment的pod在節點級別親和;
最好提交最精簡的deployment yaml,若是評論被限制,請提交反親和性配置塊yaml,也可屢次評論提交
做者:小碗湯,一位熱愛、認真寫做的小夥,目前維護原創公衆號:『個人小碗湯』,專一於寫golang、docker、kubernetes等知識等提高硬實力的文章,期待你的關注。轉載說明:務必註明來源(註明:來源於公衆號:個人小碗湯, 做者:小碗湯)
做者:小碗湯,一位熱愛、認真寫做的小夥,目前維護原創公衆號:『個人小碗湯』,專一於寫go語言、docker、kubernetes、java等開發、運維知識等提高硬實力的文章,期待你的關注。轉載說明:務必註明來源(註明:來源於公衆號:個人小碗湯,做者:小碗湯)