正文
Kubernetes 自帶了一個默認調度器kube-scheduler,其內置了很多節點預選和優選的調度算法,一般調度場景下可以滿足要求。但是在一些特殊場景下,默認調度器不能滿足我們復雜的調度需求。我們就需要對調度器進行擴展,以達到調度適合業務場景的目的。
背景
中間件redis容器化后,需要兩主不能在同一個節點上,一對主從不能在同一節點上;elasticsearch容器化后,兩個data實例不能在同一節點上。在這類場景下,默認調度器內置的預選、優選算法不能滿足需求,我們有以下三種選擇:
-
將新的調度算法添加到默認調度程序中,並重新編譯鏡像,最終該鏡像運行的實例作為kubernetes集群調度器;
-
參考kube-scheduler實現滿足自己業務場景的調度程序,並編譯鏡像,將該程序作為獨立的調度器運行到kubernetes集群內,需要用該調度器調度的pod實例,在spec.schedulerName里指定該調度器;
-
實現“調度擴展程序“:默認調度器kube-scheduler在進行預選時會調用該擴展程序進行過濾節點;在優選時會調用該擴展程序進行給節點打分,或者在bind操作時,調用該擴展器進行bind操作。
對上述三種方式進行評估:
第一種:將自己的調度算法添加到默認調度器kube-scheduler中,對原生代碼侵入性較高,而且隨着kubernetes版本升級,維護成本也較高;
第二種:默認調度器里內置了很多優秀調度算法,如:檢查節點資源是否充足;端口是否占用;volume是否被其他pod掛載;親和性;均衡節點資源利用等,如果完全使用自己開發的調度器程序,可能在達到了實際場景調度需求同時,失去更佳的調度方案,除非集成默認調度器中的算法到自己獨立調度程序中,但這無疑是不現實的;
第三種:通過啟動參數的policy配置,選用某些默認調度器中的預選、優選調度算法的同時,也可以調用外部擴展調度程序的算法,計算得到最優的調度節點,無需修改kube-scheduler代碼,只需要在啟動參數中增加配置文件即可將默認調度程序和擴展調度程序相互關聯。
可以參考:
故采用第三種:實現擴展調度程序的方案。
整體架構
kube-scheduler在調度pod實例時,首先獲取到Node1、Node2、Node3三個節點信息,進行默認的預選階段,篩選滿足要求的節點,其次再調用擴展程序中的預選算法,選出剩下的節點,假設預選階段Node3上資源不足被過濾掉,預選結束后只剩Node1和Node2;Node1和Node2進入kube-scheduler默認的優選階段進行節點打分,其次再調用擴展調度程序中的優選算法進行打分,kube-scheduler會將所有算法的打分結果進行加權求和,獲得分數最高的節點作為pod最終bind節點,然后kube-scheduler調用apiserver進行bind操作。
實現步驟
實現擴展調度程序代碼
編寫擴展調度器程序代碼,根據實際業務調度場景編寫預選邏輯、優選邏輯:
實現預選接口,入參為schedulerapi.ExtenderArgs,出參為schedulerapi.ExtenderFilterResult:
實現優選接口,入參為schedulerapi.ExtenderArgs,出參為schedulerapi.HostPriorityList:
暴露http接口:
參考:
https://github.com/ll837448792/k8s-scheduler-extender-example
默認調度器部署
由於kubernetes集群內已經有了一個名為default-scheduler的默認調度器,為了不影響集群正常調度功能,下面會創建一個名為my-kube-scheduler的調度器,這個調度器和default-scheduler除了啟動參數不一樣外,鏡像無差別。
1、創建一個名為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
}
2、在my-kube-scheduler yaml文件中將configmaps:my-scheduler-config以文件的形式掛載到容器內/my-scheduler目錄下,並在啟動參數中指定--config=/my-scheduler/config.yaml,使用和默認調度器一樣的鏡像。
增加掛載:
擴展調度器鏡像制作和部署
1、編譯擴展調度程序my-scheduler-extender鏡像,以下為Dockerfile:
推送my-scheduler-extender鏡像到harbor:
2、創建外部擴展程序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日志打印的入參、出參:
從而可以通過編寫擴展調度程序,對默認調度器的預選和優選算法進行擴展。
https://github.com/ll837448792/k8s-scheduler-extender-example
本公眾號免費提供csdn下載服務,海量IT學習資源,如果你准備入IT坑,勵志成為優秀的程序猿,那么這些資源很適合你,包括但不限於java、go、python、springcloud、elk、嵌入式 、大數據、面試資料、前端 等資源。同時我們組建了一個技術交流群,里面有很多大佬,會不定時分享技術文章,如果你想來一起學習提高,可以公眾號后台回復【2】,免費邀請加技術交流群互相學習提高,會不定期分享編程IT相關資源。
掃碼關注,精彩內容第一時間推給你