天天看點

k8s初級實戰12--pod 排程

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的配置設定。

  1. 檢視目前節點資訊
$ 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>      
  1. 檢視節點标簽資訊
$ 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>      
  1. 檢視各個節點上容器數量
$ docker ps -a|grep Up|wc      
  1. 給節點設定标簽
$ 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      
  1. 通過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      
  1. 檢視各個節點上容器數量
$ 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;下面分别對其進行實驗。

  1. 保留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;      
  1. 去掉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      
  1. 恢複kmaster為不可排程
$ kubectl taint node kmaster node-role.kubernetes.io/master:NoSchedule
$ kubectl delete -f common.yaml      
  1. 設定 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      
  1. 設定knode01 為 NoExcute
$ kubectl taint node knode01 status=vip:PreferNoSchedule-
node/knode01 untainted
$ kubectl taint node knode01 status=vip:NoExecute
node/knode01 tainted      
  1. 測試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 外,其它容器都被移除了;      
  1. 恢複節點為正常狀态
$ 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 注意事項

待補充

4 說明

繼續閱讀