kube-scheduler調度擴展

kube-scheduler調度擴展

Kubernetes 自帶了一個默認調度器kube-scheduler,其內置了不少節點預選和優選的調度算法,通常調度場景下能夠知足要求。可是在一些特殊場景下,默認調度器不能知足咱們複雜的調度需求。咱們就須要對調度器進行擴展,以達到調度適合業務場景的目的。node

背景

中間件redis容器化後,須要兩主不能在同一個節點上,一對主從不能在同一節點上;elasticsearch容器化後,兩個data實例不能在同一節點上。在這類場景下,默認調度器內置的預選、優選算法不能知足需求,咱們有如下三種選擇:nginx

  • 將新的調度算法添加到默認調度程序中,並從新編譯鏡像,最終該鏡像運行的實例做爲kubernetes集羣調度器;
  • 參考kube-scheduler實現知足本身業務場景的調度程序,並編譯鏡像,將該程序做爲獨立的調度器運行到kubernetes集羣內,須要用該調度器調度的pod實例,在spec.schedulerName裏指定該調度器;

  • 實現「調度擴展程序「:默認調度器kube-scheduler在進行預選時會調用該擴展程序進行過濾節點;在優選時會調用該擴展程序進行給節點打分,或者在bind操做時,調用該擴展器進行bind操做。

對上述三種方式進行評估:git

第一種:將本身的調度算法添加到默認調度器kube-scheduler中,對原生代碼侵入性較高,並且隨着kubernetes版本升級,維護成本也較高;github

第二種:默認調度器裏內置了不少優秀調度算法,如:檢查節點資源是否充足;端口是否佔用;volume是否被其餘pod掛載;親和性;均衡節點資源利用等,若是徹底使用本身開發的調度器程序,可能在達到了實際場景調度需求同時,失去更佳的調度方案,除非集成默認調度器中的算法到本身獨立調度程序中,但這無疑是不現實的;redis

第三種:經過啓動參數的policy配置,選用某些默認調度器中的預選、優選調度算法的同時,也能夠調用外部擴展調度程序的算法,計算獲得最優的調度節點,無需修改kube-scheduler代碼,只須要在啓動參數中增長配置文件便可將默認調度程序和擴展調度程序相互關聯。算法

能夠參考:api

https://github.com/kubernetes... 架構

故採用第三種:實現擴展調度程序的方案。app

總體架構

kube-scheduler在調度pod實例時,首先獲取到Node一、Node二、Node3三個節點信息,進行默認的預選階段,篩選知足要求的節點,其次再調用擴展程序中的預選算法,選出剩下的節點,假設預選階段Node3上資源不足被過濾掉,預選結束後只剩Node1和Node2;Node1和Node2進入kube-scheduler默認的優選階段進行節點打分,其次再調用擴展調度程序中的優選算法進行打分,kube-scheduler會將全部算法的打分結果進行加權求和,得到分數最高的節點做爲pod最終bind節點,而後kube-scheduler調用apiserver進行bind操做。elasticsearch

實現步驟

實現擴展調度程序代碼

編寫擴展調度器程序代碼,根據實際業務調度場景編寫預選邏輯、優選邏輯:

實現預選接口,入參爲schedulerapi.ExtenderArgs,出參爲schedulerapi.ExtenderFilterResult:

實現優選接口,入參爲schedulerapi.ExtenderArgs,出參爲schedulerapi.HostPriorityList:

暴露http接口:

參考:

https://github.com/ll83744879...

默認調度器部署

因爲kubernetes集羣內已經有了一個名爲default-scheduler的默認調度器,爲了避免影響集羣正常調度功能,下面會建立一個名爲my-kube-scheduler的調度器,這個調度器和default-scheduler除了啓動參數不同外,鏡像無差異。

一、建立一個名爲my-scheduler-config的configmaps,data下的config.yaml文件指定了調度器的一些參數,包括leader選舉,調度算法策略的選擇(指定另外一個configmaps),以及指定調度器的名稱爲my-kube-scheduler。

相應的建立一個my-scheduler-policy的configmaps,裏面指定了選擇哪些預選、優選策略,以及外部擴展調度程序的urlPrefix、擴展預選URI、擴展優選URI、擴展pod優先級搶佔URI、擴展bind URI、擴展優選算法的權重等。

以保證my-kube-scheduler和擴展調度程序的通訊。

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scheduler-config
  namespace: kube-system
data:
  config.yaml: |
    apiVersion: kubescheduler.config.k8s.io/v1alpha1
    kind: KubeSchedulerConfiguration
    schedulerName: my-kube-scheduler
    algorithmSource:
      policy:
        configMap:
          namespace: kube-system
          name: my-scheduler-policy
    leaderElection:
      leaderElect: false
      lockObjectName: my-kube-scheduler
      lockObjectNamespace: kube-system
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scheduler-policy
  namespace: kube-system
data:
 policy.cfg : |
  {
    "kind" : "Policy",
    "apiVersion" : "v1",
    "predicates" : [
      {"name" : "PodFitsHostPorts"},
      {"name" : "PodFitsResources"},
      {"name" : "NoDiskConflict"},
      {"name" : "MatchNodeSelector"},
      {"name" : "HostName"}
    ],
    "priorities" : [
      {"name" : "LeastRequestedPriority", "weight" : 1},
      {"name" : "BalancedResourceAllocation", "weight" : 1},
      {"name" : "ServiceSpreadingPriority", "weight" : 1},
      {"name" : "EqualPriority", "weight" : 1}
    ],
    "extenders" : [{
      "urlPrefix": "http://10.168.107.12:80/scheduler",
      "filterVerb": "predicates/always_true",
      "prioritizeVerb": "priorities/zero_score",
      "preemptVerb": "preemption",
      "bindVerb": "",
      "weight": 1,
      "enableHttps": false,
      "nodeCacheCapable": false
    }],
    "hardPodAffinitySymmetricWeight" : 10
  }

二、在my-kube-scheduler yaml文件中將configmaps:my-scheduler-config以文件的形式掛載到容器內/my-scheduler目錄下,並在啓動參數中指定--config=/my-scheduler/config.yaml,使用和默認調度器同樣的鏡像。

增長掛載:

擴展調度器鏡像製做和部署

一、編譯擴展調度程序my-scheduler-extender鏡像,如下爲Dockerfile:

推送my-scheduler-extender鏡像到harbor:

二、建立外部擴展程序my-scheduler-extender的deployment,以下爲yaml描述:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-scheduler-extender
  namespace: kube-system
  labels:
    app: my-scheduler-extender
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-scheduler-extender
  template:
    metadata:
      labels:
        app: my-scheduler-extender
    spec:
      containers:
      - name: my-scheduler-extender
        image: 192.168.26.46/k8s-deploy/my-scheduler-extender:v1.0
        imagePullPolicy: Always
        livenessProbe:
          httpGet:
            path: /version
            port: 80
        readinessProbe:
          httpGet:
            path: /version
            port: 80
        ports:
          - containerPort: 80

驗證

查看my-kube-scheduler pod日誌,加載到了policy裏的extender信息,獲取到了擴展調度器的接口地址:

建立一個nginx的pod,指定schedulerName爲my-kube-scheduler:

查看擴展調度器pod日誌,發現默認調度器會調用extender擴展調度器,以下爲extender日誌打印的入參、出參:

從而能夠經過編寫擴展調度程序,對默認調度器的預選和優選算法進行擴展。

相關文章
相關標籤/搜索