我們前面部署的pod排程取決於kube-scheduler,它會根據自己的演算法,叢集的狀態來選擇合適的node部署我們的pod。
下面我們來看下如何來根據我們自己的要求,來影響pod的排程。
定向node排程
有時候我們想將pod排程到某一些node上,比如csharp開發的程式,排程到某一些node,java開發的程式排程到另一些node,這時候我們可以選擇定向排程。
定向排程需要用到我們前面說的label,具體做法就是將node打上指定的label,然後在定義pod/deployment的時候根據nodeselector指定node
node1新增label
kubectl label nodes k8s-node1 language=csharp
指定nodeSelector欄位
apiVersion: apps/v1 kind: Deployment metadata: name: chesterdeployment namespace: chesterns labels: app: chesterapi spec: replicas: 1 selector: matchLabels: app: chesterapi template: metadata: labels: app: chesterapi spec: containers: - name: oneapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest ports: - containerPort: 5000 livenessProbe: httpGet: path: /test port: 5000 - name: twoapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest ports: - containerPort: 5001 livenessProbe: httpGet: path: /test/calloneapi port: 5001 nodeSelector: language: csharp
重新apply deployment即可發現pod已經排程到我們的node1上
kubectl delete -f deployment.yaml kubectl apply -f deployment.yaml kubectl describe pod -n chesterns
親和性
節點親和類似於nodeSelector,可以根據節點上的標籤來約束Pod可以排程到哪些節點。相比nodeSelector,親和性有以下特點:
-
匹配有更多的邏輯組合,不只是字串的完全相等
-
排程分為軟策略和硬策略,而不是硬性要求
-
required:必須滿足
-
preferred:嘗試滿足,但不保證
下面我們通過親和性來將pod,排程到node1上
apiVersion: apps/v1 kind: Deployment metadata: name: chesterdeployment namespace: chesterns labels: app: chesterapi spec: replicas: 1 selector: matchLabels: app: chesterapi template: metadata: labels: app: chesterapi spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: language operator: In values: - csharp - golang containers: - name: oneapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest ports: - containerPort: 5000 livenessProbe: httpGet: path: /test port: 5000 - name: twoapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest ports: - containerPort: 5001 livenessProbe: httpGet: path: /test/calloneapi port: 5001
可以通過kubectl apply來驗證結果。
親和性有In、NotIn、Exists、DoesNotExist、Gt、Lt操作符
親和性規則
-
如果同時定義了nodeSelector和nodeAffinity,那麼必須兩個條 件都得到滿足,Pod才能最終執行在指定的Node上。
-
如果nodeAffinity指定了多個nodeSelectorTerms,那麼其中一個 能夠匹配成功即可。
-
如果在nodeSelectorTerms中有多個matchExpressions,則一個節 點必須滿足所有matchExpressions才能執行該Pod。
刪除node上的label
kubectl label nodes k8s-node1 language-
資源開銷
容器的資源開銷同樣會影響pod的排程,在排程時,kube-scheduler會找到一臺與yaml中限制的資源匹配的node.
容器資源限制:
-
resources.limits.cpu
-
resources.limits.memory
容器使用的最小資源需求,作為容器排程時資源分配的依據:
-
resources.requests.cpu
-
resources.requests.memory
apiVersion: apps/v1 kind: Deployment metadata: name: chesterdeployment namespace: chesterns labels: app: chesterapi spec: replicas: 1 selector: matchLabels: app: chesterapi template: metadata: labels: app: chesterapi spec: containers: - name: oneapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest ports: - containerPort: 5000 livenessProbe: httpGet: path: /test port: 5000 resources: limits: cpu: 1000m memory: 2000Mi requests: cpu: 100m memory: 200Mi
這就是一個很常見的資源限制示例。
汙點Taint
NodeAffinity節點親和性,是在Pod上定義的一種屬性, 使得Pod能夠被排程到某些Node上執行(優先選擇或強制要求)。Taint 則正好相反,它讓Node拒絕Pod的執行。
設定汙點
#kubectl taint node [node] key=value:[effect]
kubectl taint node k8s-node1 language=csharp:NoExecute
其中[effect] 可取值:
-
NoSchedule :一定不能被排程。
-
PreferNoSchedule:儘量不要排程。
-
NoExecute:不僅不會排程,還會驅逐Node上已有的Pod。
apiVersion: apps/v1 kind: Deployment metadata: name: chesterdeployment namespace: chesterns labels: app: chesterapi spec: replicas: 1 selector: matchLabels: app: chesterapi template: metadata: labels: app: chesterapi spec: containers: - name: oneapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest ports: - containerPort: 5000 livenessProbe: httpGet: path: /test port: 5000 - name: twoapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest ports: - containerPort: 5001 livenessProbe: httpGet: path: /test/calloneapi port: 5001
可以通過kubectl apply來驗證結果。
Tolerations
在 Node上設定一個或多個Taint之後,除非Pod明確宣告能夠容忍這些汙點,否則無法在這些Node上執行。Toleration是Pod的屬性,讓Pod能夠 (注意,只是能夠,而非必須)執行在標註了Taint的Node上。
apiVersion: apps/v1 kind: Deployment metadata: name: chesterdeployment namespace: chesterns labels: app: chesterapi spec: replicas: 1 selector: matchLabels: app: chesterapi template: metadata: labels: app: chesterapi spec: tolerations: - key: "language" operator: "Equal" value: "csharp" effect: "NoExecute" containers: - name: oneapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest ports: - containerPort: 5000 livenessProbe: httpGet: path: /test port: 5000 - name: twoapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest ports: - containerPort: 5001 livenessProbe: httpGet: path: /test/calloneapi port: 5001
通過以下命令驗證
kubectl delete -f deployment.yaml kubectl apply -f deployment.yaml kubectl describe pod -n chesterns
去掉汙點
kubectl taint node [node] key:[effect]-