Kubernetes-專案中pod排程使用法則
前言
kubernetes中部署的pod預設根據資源使用情況自動排程到某個節點。可在實際專案的使用場景中都會有更細粒度的排程需求,比如:某些pod排程到指定主機、某幾個相關的服務的pod最好排程到一個節點上、Master節點不允許某些pod排程等。使用kubernetes中的節點排程、節點親和性、pod親和性、汙點與容忍可以靈活的完成pod排程,從而滿足專案中較為複雜的排程需求。下面用一些專案中的使用場景聊聊pod排程使用法則。
原創作者:鍾亮
pod排程主要包含以下內容
- nodeSelector
- nodeAffinity
- podAffinityz
- Taints
指定節點排程
kubectl get nodes #獲取當前Kubernetes叢集全部節點 NAMESTATUSROLESAGEVERSION dev-10Ready<none>45dv1.8.6 dev-7Readymaster45dv1.8.6 dev-8Ready<none>45dv1.8.6 dev-9Ready<none>45dv1.8.6
nodeName
通過主機名指定pod排程到指定節點
spec: nodeName: dev-8 #設定要排程節點的名稱 containers: - image: nginx imagePullPolicy: Always name: my-nginx resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30
nodeSelector
kubernetes中常用label來管理叢集的資源,nodeSelector可通過標籤實現pod排程到指定節點上。
舉列:使用nodeSelector將pod排程到dev-9節點上
step1:給dev-9打標籤
kubectl label nodes dev-9 test=nginx #設定標籤 kubectl get nodes --show-labels |grep test=nginx #查詢標籤是否設定成功
setp2:nodeSelector設定對應標籤
spec: containers: - image: nginx imagePullPolicy: Always name: my-nginx resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst nodeSelector:#設定標籤 test: nginx restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30
查詢pod已經成功排程到dev-9節點
kcc get pods -o wide -n ns-team-1-env-1|grep my-nginx
my-nginx-556dcc8c5c-27f7k 1/1 Running 0 2m
10.244.2.238 dev-9
nodeAffinity
node 節點 Affinity ,從字面上很容易理解nodeAffinity就是節點親和性,Anti-Affinity也就是反親和性。節點親和性就是控制pod是否排程到指定節點,相對nodeSelector來說更為靈活,可以實現一些簡單的邏輯組合。
nodeAffinity策略
preferredDuringSchedulingIgnoredDuringExecution #軟策略,儘量滿足 requiredDuringSchedulingIgnoredDuringExecution#硬策略,必須滿足 根據具體一些常用場景感受下 場景1:必須部署到有 test=nginx 標籤的節點 spec: containers: - name: with-node-affinity image: nginx affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: test operator: In values: - nginx 場景2:最好部署到有test=nginx 標籤的節點 spec: containers: - name: with-node-affinity image: nginx affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: test operator: In values: - nginx 場景3:不能部署在dev-7,dev-8節點;最好部署到有test=nginx標籤的節點 spec: containers: - name: with-node-affinity image: nginx affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: NotIn values: - dev-7 - dev-8 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: test operator: In values: - nginx
通過以上場景可以看出使用節點親和性可靈活的控制pod排程到節點,實現一些有邏輯組合的排程
Kubernetes中的operator提供了下面幾種過濾條件:
- In:label 的值在某個列表中
- NotIn:label 的值不在某個列表中
- Gt:label 的值大於某個值
- Lt:label 的值小於某個值
- Exists:某個 label 存在
- DoesNotExist:某個 label 不存
podAffinity
nodeSelector和nodeAffinity 都是控制pod排程到節點的操作,在實際專案部署場景中,希望根據服務與服務之間的關係進行排程,也就是根據pod之間的關係進行排程,Kubernetes的podAffinity就可以實現這樣的場景,podAffinity的排程策略和nodeAffinity類似也有:
requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution
場景:希望my-nginx服務my-busybox服務 最好部署在同一個節點上
my-nginx基本資訊
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: my-nginx #標籤 app = my-nginx
name: my-nginx
namespace: ns-team-1-env-1
...
...
my-busybox基本資訊
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: my-busybox #標籤 app = my-busybox
name: my-busybox
namespace: ns-team-1-env-1
...
...
在my-busybox設定pod親和性
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-busybox
labels:
app: my-busybox
spec:
containers:
- name: my-busybox
image: nginx
affinity:
podAffinity: #my-busybox 新增pod親和性,與打了標籤app = my-nginx的pod靠近
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- my-nginx
topologyKey: kubernetes.io/hostname
以上例子表示,有一個pod在執行,並且這個pod有標籤是app=my-nginx,my-busybox這個pod就會
與其排程到同一個節點上,可預見因為上面我們的my-nginx已經排程到dev-9,因此my-nginx和
my-busybox都會在dev-9節點上查詢到
Taints & tolerations
Taints:汙點,tolerations:容忍。在實際專案實踐中有時候不希望某些服務排程到指定節點上,比如master節點只執行Kubernetes 元件,應用服務不希望排程到master上。這種場景只需要在master節點設定一個汙點。
#設定汙點 kubectl taint nodes dev-7 system=service:NoSchedule
設定了汙點就不能排程了麼?No 如果設定了汙點還是希望某些pod能夠排程上去,可以給pod針對汙點加容忍。
#新增容忍 tolerations: - key: "system" operator: "Equal" value: "service" effect: "NoSchedule"
添加了容忍system=service , 這樣就可以排程到節點設定了汙點:system=service:NoSchedule
的主機上,其他沒有新增容忍的服務就不會排程到打了汙點的節點上。
effect 有三種設定
- NoSchedule:pod不能排程到標記了taints的節點
- PreferNoSchedule:pod最好不要排程到標記了taints的節點
- NoExecute:設定了汙點,馬上踢出該節點中沒有設定對應汙點的Tolerate設定的pod
參考文件
ofollow,noindex" target="_blank">https://kubernetes.io/docs/con ... node/
https://kubernetes.io/docs/con ... tion/
關於睿雲智合
深圳睿雲智合科技有限公司成立於2012年,總部位於深圳,並分別在成都、深圳設立了研發中心,北京、上海設立了分支機構,核心骨幹人員全部為來自金融、科技行業知名企業資深業務專家、技術專家。早期專注於為中國金融保險等大型企業提供創新技術、電子商務、CRM等領域專業諮詢服務。
自2016年始,在率先將容器技術引進到中國保險行業客戶後,公司組建了專業的容器技術產品研發和實施服務團隊,旨在幫助中國金融行業客戶將容器創新技術應用於企業資訊科技支援業務發展的基礎能力改善與提升,成為中國金融保險行業容器技術服務領導品牌。
此外,憑藉多年來在呼叫中心領域的業務經驗與技術積累,睿雲智合率先在業界推出基於開源軟交換平臺FreeSwitch的微服務架構多媒體數字化業務平臺,將語音、視訊、webchat、微信、微博等多種客戶接觸渠道整合,實現客戶統一接入、精準識別、智慧路由的CRM策略,並以容器化治理來支援平臺的全應用生命週期管理,顯著提升了數字化業務處理的靈活、高效、彈性、穩定等特性,為幫助傳統企業向“以客戶為中心”的數字化業務轉型提供完美的一站式整體解決方案。