轉(zhuǎn)載請注明出處即可腔彰。
所使用源碼k8s源碼為release-1.18
如果對K8s的Scheduler不是很了解,可以先看下Kubernetes Scheduler簡介這篇文章
零、Scheduler擴展簡介
Scheduler的擴展有兩種方式孵构,一種是修改Scheduler的源碼恍飘,編寫調(diào)度和綁定兩個過程的插件。然后將插件注冊梯啤。
還有一種是通過Extender來進行擴展凛驮, 可以通過http請求調(diào)用自己編寫的extender項目來處理自定義調(diào)度。
第一種的話条辟,需要修改源碼黔夭,但可以修改的階段比較靈活,而第二種方法羽嫡,處理的階段比較寬泛本姥。
本文主要是通過第二種方式, 首先先構(gòu)建k8s集群,然后構(gòu)建一個用于模擬調(diào)度擴展的項目杭棵。
一溉浙、環(huán)境準(zhǔn)備
需要準(zhǔn)備一個多節(jié)點的k8s集群,如果手上沒有現(xiàn)成的測試集群或者云服務(wù)籍琳。那么可以看kubernetes部署-基于vmware+centos7虛擬機3個節(jié)點這篇文章來搭建一個簡單的集群哩盲。
需要注意的是,本文使用的k8s版本為1.18滓侍,之前那篇文章上為1.17.4蒋川,需要升級。
需要多節(jié)點的原因如上圖撩笆,僅僅是一個節(jié)點的話捺球,也就無需考慮到底放到哪里了^_^
。
二夕冲、構(gòu)建項目
所使用的環(huán)境為 Go 1.14版本氮兵,并且配置了go mod。通過go mod來安裝相關(guān)包歹鱼∑唬框架主要使用gin,toml, k8s client等。
# 配置到.bash_profile中或者.zshrc中
export GOPROXY="https://goproxy.cn"
export GO111MODULE=on
因為考慮到大部分開發(fā)都在用Java南片,所以在這里多啰嗦幾句篙悯。
首先創(chuàng)建一個項目文件夾 scheduler-extender
然后進入到文件夾內(nèi)部執(zhí)行g(shù)o mod init scheduler-extender創(chuàng)建go.mod
然后安裝相關(guān)的包
go get github.com/BurntSushi/toml
go get github.com/gin-gonic/gin
go get k8s.io/kube-scheduler
如果安裝成功的話 go.mod如下圖所示,當(dāng)然版本可能會有所不同
然后簡單封裝下https://gitee.com/VincentWang/scheduler-extender铃绒,具體extender實現(xiàn)都在這個項目中
項目封裝后鸽照,在看下需要如何接收與返回參數(shù),然后在考慮如果編寫相關(guān)邏輯颠悬。
首先看下HTTPExtender的 send 方法, 發(fā)現(xiàn)使用的json格式矮燎,并且args參數(shù)會序列化成json后發(fā)送到自定義的extender服務(wù)中。
send方法有四處調(diào)用赔癌,分別對應(yīng)著诞外,
- Filter: 在調(diào)度過程中,過濾掉不部署pod的node
- Preempt: 在資源不足時候灾票,搶占低優(yōu)先級的pod資源峡谊,優(yōu)先保證高優(yōu)先級pod運行
- Prioritize: node排序,在資源充足時刊苍,選擇"最佳"的node
- Bind: 綁定階段
在看下具體調(diào)用send方法的地方既们,這里只看下Filter
其實在上面的四個擴展都有對應(yīng)的傳參和返回值(ExtenderArgs是filter和prioritize兩個階段在共用),在scheduler-extender項目實現(xiàn)時正什,需要分別進行處理啥纸。
我這里的nodes環(huán)境如下。
ip | host | node role |
---|---|---|
192.168.179.137 | ceph1 | master |
192.168.179.138 | ceph2 | master |
192.168.179.139 | ceph3 | master |
然后我們來模擬實現(xiàn)一個調(diào)度婴氮,filter階段過濾掉cehp3斯棒,prioritize階段, cehp1的優(yōu)先級高于ceph2, preempt, bind先不實現(xiàn)。實現(xiàn)后主经,理論上部署的pod會部署到ceph1中荣暮。
具體實現(xiàn)邏輯完成后,在ceph3中進行項目部署罩驻,生產(chǎn)環(huán)境中可以部署到k8s中穗酥。
三、Scheduler配置
首先先關(guān)注下如何進行配置鉴腻,才能讓Scheduler去調(diào)用scheduler-extender迷扇。
首先不穩(wěn)當(dāng)?shù)腶pi版本才會用
internal
百揭。
const (
// APIVersionInternal may be used if you are registering a type that should not
// be considered stable or serialized - it is a convention only and has no
// special behavior in this package.
APIVersionInternal = "__internal"
)
然后在看下v1alpha2版本的api爽哎,發(fā)現(xiàn)也可以使用Extenders配置。
保存以下配置到sched.yaml中, 這個配置可以參考源碼中的KubeSchedulerConfiguration struct器一,在官網(wǎng)沒有搜索到具體的配置項课锌,注意不要使用json的配置,k8s的這個api解析json有些bug。
apiVersion: kubescheduler.config.k8s.io/v1alpha2
kind: KubeSchedulerConfiguration
extenders:
- urlPrefix: http://192.168.179.139/scheduler-extender
filterVerb: filter
prioritizeVerb: prioritize
nodeCacheCapable: true
enableHttps: false
weight: 100000
leaderElection:
leaderElect: true
clientConnection:
kubeconfig: /etc/kubernetes/scheduler.conf
并將sched.yaml 放到/etc/kubernetesf中渺贤,然后修改/etc/kubernetes/manifests下的kube-scheduler.yaml文件
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: kube-scheduler
tier: control-plane
name: kube-scheduler
namespace: kube-system
spec:
containers:
- command:
- kube-scheduler
- --authentication-kubeconfig=/etc/kubernetes/scheduler.conf
- --authorization-kubeconfig=/etc/kubernetes/scheduler.conf
- --bind-address=127.0.0.1
- --kubeconfig=/etc/kubernetes/scheduler.conf
- --leader-elect=true
- --config=/etc/kubernetes/sched.yaml
image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.18.2
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 8
httpGet:
host: 127.0.0.1
path: /healthz
port: 10259
scheme: HTTPS
initialDelaySeconds: 15
timeoutSeconds: 15
name: kube-scheduler
resources:
requests:
cpu: 100m
volumeMounts:
- mountPath: /etc/kubernetes/scheduler.conf
name: kubeconfig
readOnly: true
- mountPath: /etc/kubernetes/sched.yaml
name: schedconfig
readOnly: true
hostNetwork: true
priorityClassName: system-cluster-critical
volumes:
- hostPath:
path: /etc/kubernetes/scheduler.conf
type: FileOrCreate
name: kubeconfig
- hostPath:
path: /etc/kubernetes/sched.yaml
type: FileOrCreate
name: schedconfig
status: {}
主要增加了--config配置以及通過hostPath掛載sched.yaml
可以查看下是否存在配置錯誤
k logs -f kube-scheduler-ceph1 -n kube-system
修改過kube-scheduler.yaml后雏胃,k8s會自動重啟pod,但是
需要將3個節(jié)點的配置都修改下才行
志鞍。
四瞭亮、驗證自定義調(diào)度是否有效
上面小節(jié)的步驟都完成后,嘗試部署一個簡單的pod固棚。
在執(zhí)行指令前统翩,一定要確保scheduler-extender程序是在運行的。
kubectl run kubia --image=luksa/kubia --port=8080
在執(zhí)行后, 查看po的狀態(tài)
kubectl get po
這里我們也可以看到scheduler-extender也存在對應(yīng)的請求
最后看下是否部署到了ceph1節(jié)點
kubectl descibe po kubia
DONE此洲,大功告成厂汗。