k8s初級實戰12--pod 排程
- 1 簡介
- 2 基于 label 和 taints 控制排程
- 2.1 通過 label 配置設定 pod
- 2.2 通過 taints 控制 pod
- 3 注意事項
- 4 說明
1 簡介
随着k8s 變得越來越大、越來越多樣化,其排程管理就變得非常重要。k8s中通過kube-scheduler來進行調取,它通過topology-aware 算法來決定哪些節點可以運作一個pod。
Scheduler 會跟蹤叢集中一系列的節點,并基于多個判斷條件對節點進行過濾,然後通過優先級函數來決定每個pod應該被排程到哪個節點上。
k8s 中有多種控制 pod 排程的方式,包括label、taints、podAffinity 和 podAntiAffinity;本文對其中最常見的兩種(label 和 taints)進行介紹,并加以實驗測試。
2 基于 label 和 taints 控制排程
2.1 通過 label 配置設定 pod
k8s 中可以給node打标簽,然後pod中跟nodeSelector來确定排程到哪些節點上;本案例通過對節點打标簽來控制pod的配置設定。
- 檢視目前節點資訊
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kmaster Ready master 5h v1.19.4
knode01 Ready <none> 4h47m v1.19.4
knode02 Ready <none> 4h45m v1.19.4
knode03 Ready <none>
- 檢視節點标簽資訊
$ kubectl describe nodes|grep -A5 -i label
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=kmaster
kubernetes.io/os=linux
node-role.kubernetes.io/master=
--
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=knode01
kubernetes.io/os=linux
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
......
$ kubectl describe nodes|grep -i taint
Taints: node-role.kubernetes.io/master:NoSchedule
Taints: <none>
Taints: <none>
Taints: <none>
- 檢視各個節點上容器數量
$ docker ps -a|grep Up|wc
- 給節點設定标簽
$ kubectl label nodes knode01 status=vip
$ kubectl label nodes knode02 status=other
$ kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
kmaster Ready master 5h8m v1.19.4 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=kmaster,kubernetes.io/os=linux,node-role.kubernetes.io/master=
knode01 Ready <none> 4h55m v1.19.4 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=knode01,kubernetes.io/os=linux,status=vip
knode02 Ready <none> 4h53m v1.19.4 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=knode02,kubernetes.io/os=linux,status=other
knode03 Ready <none> 4h49m v1.19.4 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=knode03,kubernetes.io/os=linux
- 通過nodeSelector在vip節點上部署3個容器, 在other上部署2個容器
建立 vip pod
$ im vip.yaml
apiVersion: v1
kind: Pod
metadata:
name: vip
spec:
nodeSelector:
status: vip
containers:
- name: vip1
image: busybox:1.31
args:
- sleep
- "1000000"
- name: vip2
image: busybox:1.31
args:
- sleep
- "1000000"
- name: vip3
image: busybox:1.31
args:
- sleep
- "1000000"
$ kubectl apply -f vip.yaml
建立 other pod
$ vim other.yaml
apiVersion: v1
kind: Pod
metadata:
name: other
spec:
nodeSelector:
status: other
containers:
- name: other1
image: busybox:1.31
args:
- sleep
- "1000000"
- name: other2
image: busybox:1.31
args:
- sleep
- "1000000"
$ kubectl apply -f other.yaml
pod/other created
- 檢視各個節點上容器數量
$ docker ps -a|grep Up|wc -l
kmaster節點:20
knode01節點:12 (添加3個busybox+1個pause容器)
knode02節點:11 (添加2個busybox+1個pause容器)
2.2 通過 taints 控制 pod
k8s 目前支援 3 類taints, 分别為 NoSchedule ,PreferNoSchedule 和 NoExecute;下面分别對其進行實驗。
- 保留taints NoSchedule
$ kubectl delete -f vim.yaml
$ kubectl delete -f other.yaml
kmaster knode01 knode02 knode03 容器數量:20 8 8 8
$ vim common.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: common
name: common
spec:
replicas: 4
selector:
matchLabels:
app: common
template:
metadata:
labels:
app: common
spec:
containers:
- image: busybox:1.31
name: busybox
command: [sh, -c, 'sleep 10000']
$ kubectl apply -f common.yaml
deployment.apps/common created
此時 kmaster knode01 knode02 knode03 容器數量:20 10 10 12, kmaster 沒有配置設定pod,knode01|02|03 分别配置設定了1|1|2個pod;
- 去掉Taints NoSchedule
$ kubectl delete -f common.yaml
deployment.apps "common" deleted
$ kubectl taint node kmaster node-role.kubernetes.io/master:NoSchedule-
node/kmaster untainted
$ kubectl apply -f common.yaml
$ docker ps -a|grep Up|wc
- 恢複kmaster為不可排程
$ kubectl taint node kmaster node-role.kubernetes.io/master:NoSchedule
$ kubectl delete -f common.yaml
- 設定 vip 為 PreferNoSchedule
$ kubectl taint node knode01 status=vip:PreferNoSchedule
node/knode01 tainted
$ kubectl apply -f common.yaml
$ docker ps -a|grep Up|wc -l
此時 kmaster knode01 knode02 knode03 容器數量:20 10 10 12, knode01|02|03 分别配置設定1|1|2個pod;
除了master設定NoSchedule外,每個node節點配置設定1個,多餘的1個pod不優先配置設定給knode01;
$ kubectl scale deployment common --replicas=8
此時 kmaster knode01 knode02 knode03 容器數量:20 12 14 14, knode01|02|03 分别配置設定2|3|4個pod;
除了master設定NoSchedule外,每個node節點配置設定2個,多餘的2個pod不優先配置設定給knode01;
$ kubectl delete -f common.yaml
- 設定knode01 為 NoExcute
$ kubectl taint node knode01 status=vip:PreferNoSchedule-
node/knode01 untainted
$ kubectl taint node knode01 status=vip:NoExecute
node/knode01 tainted
- 測試knode01 檢視pod是否被移除;
$ kubectl apply -f common.yaml
deployment.apps/common created
$ docker ps -a|grep Up|wc -l
此時 kmaster knode01 knode02 knode03 容器數量:20 4 12 14,knode01減少了2個pod,knode02|03分别增加了1|3個pod;
knode01 上除了k8s_calico-node_calico-node 和 k8s_kube-proxy_kube-proxy 外,其它容器都被移除了;
- 恢複節點為正常狀态
$ kubectl taint node knode01 status=vip:NoExecute-
node/knode01 untainted
$ kubectl label nodes knode01 status-
$ kubectl label nodes knode02 status-
過一段時間後, 非核心的DaemonSets pod node-exporter再次排程到knode01上;
3 注意事項
待補充