天天看點

企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

企業運維實戰--k8s學習筆記9.k8s排程(上)

  • 前言--排程器簡介
  • k8s排程
    • NodeName
    • nodeSelector 親和
      • 節點親和
      • pod親和
      • Taints污點與容忍

前言–排程器簡介

排程器通過 kubernetes 的 watch 機制來發現叢集中新建立且尚未被排程到 Node 上的 Pod。排程器會将發現的每一個未排程的 Pod 排程到一個合适的 Node 上來運作。

kube-scheduler 是 Kubernetes 叢集的預設排程器,并且是叢集控制面的一部分。如果你真的希望或者有這方面的需求,kube-scheduler 在設計上是允許你自己寫一個排程元件并替換原有的 kube-scheduler。

在做排程決定時需要考慮的因素包括:單獨和整體的資源請求、硬體/軟體/政策限制、親和以及反親和要求、資料局域性、負載間的幹擾等等。

k8s排程

NodeName

NodeName 是節點選擇限制的最簡單方法,它優先于其他的節點選擇方法。換言之,NodeName都無法解決的排程需求,則其他排程方法也無法做到。

缺點與限制:

  • 如果指定的節點不存在。
  • 如果指定的節點沒有資源來容納 pod,則pod 排程失敗。
  • 雲環境中的節點名稱并非總是可預測或穩定的。

稍後實驗會對邊示範。

nodeSelector 親和

nodeSelector 是節點選擇限制的最簡單推薦形式。給選擇的節點添加标簽,通過标簽來進行排程。

親和與反親和

  • nodeSelector 提供了一種非常簡單的方法來将 pod

    限制到具有特定标簽的節點上。親和/反親和功能極大地擴充了你可以表達限制的類型。

  • 你可以發現規則是“軟”/“偏好”,而不是硬性要求,是以,如果排程器無法滿足該要求,仍然排程該 pod。
  • 你可以使用節點上的 pod 的标簽來限制,而不是使用節點本身的标簽,來允許哪些 pod 可以或者不可以被放置在一起。

節點親和

包含兩部分:

requiredDuringSchedulingIgnoredDuringExecution 必須滿足

preferredDuringSchedulingIgnoredDuringExecution 傾向滿足

示例:

建立工作目錄并進入,編寫資源清單

mkdir schedu
cd schedu/
vim pod.yaml
cat pod.yaml
           
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

拉起容器并檢視

kubectl apply -f pod.yaml
kubectl get pod
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

此時未給任何node節點添加标簽,pod節點處于Pending狀态,

稍後添加标簽後,pod将在被添加的node拉起

添加标簽後,檢視pod節點狀态

kubectl label nodes server3 disktype=ssd
kubectl get pod -o wide
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

删除标簽後不會消失,因為容器已經運作

kubectl label nodes server3 disktype-
kubectl get node --show-labels
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程
kubectl get pod
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

測試結束後删除節點pod

kubectl delete -f pod.yaml
           

節點親和性pod示例

vim pod1.yaml

apiVersion: v1
kind: Pod
metadata:
  name: node-affinity
spec:
  containers:
  - name: nginx
    image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution: #必須滿足
           nodeSelectorTerms:
           - matchExpressions:
             - key: kubernetes.io/hostname
               operator: In
               values:
               - server3
               - server4
      preferredDuringSchedulingIgnoredDuringExecution: #傾向滿足
      - weight: 1
        preference:
          matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd    
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

先注釋掉傾向滿足,發現親和到server4

kubectl apply -f pod1.yaml
kubectl get pod -o wide
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

打開傾向滿足,删除節點,重新拉起容器,還在server4

vim pod1.yaml
kubectl delete -f pod1.yaml
kubectl apply -f pod1.yaml
kubectl get pod -o wide
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

為server3添加标簽ssd,删除節點重新開機拉起容器,服務親和到server3

kubectl label nodes server3 disktype=ssd
kubectl delete -f pod1.yaml
kubectl apply -f pod1.yaml
kubectl get pod -o wide
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

pod親和

pod親和,mysql容器親和nginx pod

示例:

vim pod2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx

---
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  containers:
  - name: mysql
    image: mysql:5.7
    env:
     - name: "MYSQL_ROOT_PASSWORD"
       value: "westos"
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - nginx
        topologyKey: kubernetes.io/hostname

           
kubectl apply -f pod2.yaml
kubectl get pod -o wide
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

可以看到mysql與nginx在同一個node節點server4上部署,這不是巧合,而是資源清單的親和部署。

反親和:

vim pod2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx

---
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  containers:
  - name: mysql
    image: mysql:5.7
    env:
     - name: "MYSQL_ROOT_PASSWORD"
       value: "westos"
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - nginx
        topologyKey: kubernetes.io/hostname

           

與親和檔案的比較,不同之處

企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

重新拉起容器,檢視mysql節點并不在nginx服務的同個節點上,實作服務與資料分離。

kubectl delete -f pod2.yaml
kubectl apply -f pod2.yaml
kubectl get pod -o wide
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

Taints污點與容忍

NodeAffinity節點親和性,是Pod上定義的一種屬性,使Pod能夠按我們的要求排程到某個Node上,而Taints則恰恰相反,它可以讓Node拒絕運作Pod,甚至驅逐Pod。

Taints(污點)是Node的一個屬性,設定了Taints後,是以Kubernetes是不會将Pod排程到這個Node上的,于是Kubernetes就給Pod設定了個屬性Tolerations(容忍),隻要Pod能夠容忍Node上的污點,那麼Kubernetes就會忽略Node上的污點,就能夠(不是必須)把Pod排程過去。(可通過字面意思類比了解)

總結:

可以使用指令 kubectl taint 給節點增加一個 taint:

kubectl taint nodes node1 key=value:NoSchedule	#建立
kubectl describe nodes  server1 |grep Taints		#查詢
kubectl taint nodes node1 key:NoSchedule-		#删除
           

其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]

NoSchedule:POD 不會被排程到标記為 taints 節點。

PreferNoSchedule:NoSchedule 的軟政策版本。

NoExecute:該選項意味着一旦 Taint 生效,如該節點内正在運作的 POD 沒有對應 Tolerate 設定,會直接被逐出。

示例:

server2為k8smaster主機,預設會不加入叢集排程,

檢視server2污點

kubectl describe nodes server2|grep Taint
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

測試1:Nodename可以無視任何污點

編輯資源清單建立pod,采用nodename指定node節點

vim pod.yaml
cat pod.yaml
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

拉起容器

kubectl apply -f pod.yaml
kubectl get pod
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

檢視節點所在node

kubectl get pod -o wide
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

測試結果表明,雖然server2為master且設定了污點,但是nodename可以無視污點。

測試完成删除測試pod

kubectl delete -f pod.yaml
           

為server2設定标簽,使用标簽方式測試污點

kubectl label nodes server2 roles=master
kubectl get nodes --show-labels
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

編輯資源清單,使用标簽方式選擇node

vim pod.yaml
cat pod.yaml
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

拉起容器,發現pod節點不能成功running

kubectl apply -f pod.yaml
kubectl get pod -o wide
           

測試證明,标簽選擇無法覆寫污點。

添加容忍

vim pod.yaml
cat pod.yaml
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

添加容忍,NoSchedule:POD 不會被排程到标記為 taints 節點。

kubectl taint nodes server3 key=value:NoSchedule
           

此時server3是有污點的

kubectl describe nodes server3|grep Taint
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

首先注釋容忍,拉起容器,發現容器在server4端運作,說明污點生效。

vim pod.yaml
cat pod.yaml
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程
kubectl apply -f pod.yaml
kubectl get pod -o wide
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

删除pod節點,重新打開容忍,

kubectl delete -f pod.yaml
vim pod.yaml
cat pod.yaml
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

通過标簽選擇server3,

kubectl apply -f pod.yaml
kubectl get pod
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

測試完成後取消NoSchedule的值

NoExecute:該選項意味着一旦 Taint 生效,如該節點内正在運作的 POD 沒有對應 Tolerate 設定,會直接被逐出。被驅逐到其他node節點。

kubectl taint nodes server3 key=value:NoExecute
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

驅逐後 ,所有server3上再無pod,驅逐是一個過程,需要一定的時間。

kubectl get pod -o wide
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

測試完成,取消NoExecute的值

企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

關閉server3的所有排程

kubectl cordon server3
kubectl get node
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

重新開啟server3的排程

kubectl uncordon server3
kubectl get node
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

關閉server3的排程,但不關閉部分必要pod

kubectl drain server3
kubectl get node
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

删除node

kubectl delete node server3
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

node節點重新開機服務即可恢複node資訊

企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程
kubectl get node
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程

故,删除node步驟為:先驅逐pod,再删除node。

token資訊檢視和建立方法,隻有23h的儲存時間

kubeadm token list
kubeadm token create
kubeadm token list
           
企業運維實戰--k8s學習筆記9.k8s排程前言–排程器簡介k8s排程