目的:在一般業務場景,有些pod需要執行在特定的物理節點上,可以通過kubernetes的nodeSelector、nodeName安排pod到指定的節點上執行。
# 採用nodeselect節點選擇器的方法:
# 為 test-nodelete-2節點打上標籤。
$ kubectl label nodes test-nodelete-2 disk=ssd
node/test-nodelete-2 labeled
$ kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
test-nodelete-1 Ready <none> 14d v1.20.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ingress=ingress,kubernetes.io/arch=amd64,kubernetes.io/hostname=test-nodelete-1,kubernetes.io/os=linux
test-nodelete-2 Ready <none> 14d v1.20.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disk=ssd,ingress=ingress,kubernetes.io/arch=amd64,kubernetes.io/hostname=test-nodelete-2,kubernetes.io/os=linux
test-nodelete-3 Ready <none> 14d v1.20.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ingress=ingress,kubernetes.io/arch=amd64,kubernetes.io/hostname=test-nodelete-3,kubernetes.io/os=linux
$ cat > nodeschedule.yaml << EOF
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-select
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disk: ssd
EOF
# 採用nodeName的方法:
# 如果不用節點選擇器,直接用指定節點名,可以無視Taints,可以被排程。但會被NoExcute Taint影響, 如果節點存在NoExcute, 那將不能執行在該節點上。
$ cat > nodeName.yaml << EOF
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-app
spec:
nodeName: test-nodelete-2 # schedule pod to specific node
containers:
- name: nginx-web
image: nginx
imagePullPolicy: IfNotPresent
EOF
目的:Taints 是允許node節點排斥一組pod。Tolerations 允許程式排程pod到具有汙點的 node節點上。Tolerations 允許排程但不保證排程。taints和Tolerations一起工作,以確保 Pod 不會被排程到不合適的節點上。一個或多個taints應用於一個節點;這標誌著該節點不接受任何不容忍汙點的 pod。
NoSchedule: 設定為不排程到該節點
PreferNoSchedule: 設定為儘量不排程到該節點
NoExecute: 設定為不排程到該節點和驅逐原來該節點已有存量的pod
# 向節點新增汙點
$ kubectl taint nodes node1 key1=value1:NoSchedule
# 解釋:在 node1上設定一個汙點。汙點具有鍵key1、值value1和汙點效果NoSchedule。node1這意味著除非具有匹配的容限,否則任何 pod 都無法排程到node1節點。
# 去除節點汙點
$ kubectl taint nodes node1 key1=value1:NoSchedule-
# 節點加上taints為NoSchedule,pod資源是不會排程到node1節點。
$ kubectl taint nodes node1 key1=value1:NoSchedule
$ cat > taints.yaml << EOF
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-taints
labels:
env: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
EOF
# 為 pod 指定一個tolerations(容忍度)。以下兩個容忍「匹配」由kubectl taint上面的行建立的汙點(key1=value1:NoSchedule),因此具有容忍的 pod 都可以排程到node1節點。
$ cat > taints-and-tolerations.yaml << EOF
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-taints-tolerations
labels:
env: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "key1"
value: "value1"
operator: "Equal"
effect: "NoSchedule"
EOF
# 當operator為Equal時,key和value都要匹配到上述taints指定的key1=value1,key和value都滿足條件即可以容忍該汙點,pod執行在node1節點上。
# 當operator為Exists時,key或value其中一個匹配到上述taints指定的key1=value1,滿足條件即可以容忍該汙點,pod執行在node1節點上。
tolerations:
- key: "key1"
value: "value1"
operator: "Equal"
effect: "NoSchedule"
# 如果NoExecute被新增到一個節點,那麼任何不容忍該 taint 的 pod 將立即被驅逐,而容忍該 taint 的 pod 將永遠不會被驅逐。NoExecute效果的容忍可以指定一個可選`tolerationSeconds`欄位,該欄位指示在新增汙點後 pod 將保持繫結到節點的時間。
$ kubectl taint nodes node1 execute=yes:NoExecute
- key: "execute"
value: "yes"
effect: "NoExecute"
# tolerationSeconds: 3600
nodeSelector是將 Pod 約束到具有特定標籤的節點的最簡單方法。Affinity 和 anti-affinity 擴充套件了您可以定義的約束型別。如果同時指定nodeSelector和nodeAffinity,則必須同時滿足兩者才能將 Pod 排程到節點上。.
節點親和性(Node Affinity)在概念上類似於nodeSelector,允許您根據節點標籤限制您的 Pod 可以排程的節點。有兩種型別的節點親和性:
$ cat > nodeAffinity.yaml << EOF
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-nodeaffinity
labels:
env: nodeaffinity
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "test-nodelete-3"
operator: In
values:
- "yes"
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: "disk"
operator: In
values:
- "ssd"
tolerations:
- key: "active"
operator: "Exists"
effect: "NoSchedule"
EOF
# requiredDuringSchedulingIgnoredDuringExecution規則解釋:
# 該node節點必須具有帶有鍵的標籤為test-nodelete-3,並且該標籤的值必須是:yes
# preferredDuringSchedulingIgnoredDuringExecution規則解釋:
# 排程器嘗試尋找帶有鍵為disk,值為ssd的node節點。如果匹配的節點不可用,排程程式仍會繼續排程 Pod執行。
# tolerations(容忍)規則解釋:
# 容忍程式排程pod到具有汙點(taints)node節點上, 汙點鍵為active的node。
# operator欄位指定 Kubernetes 在解釋規則時使用的邏輯運運算元。您可以使用In、NotIn、Exists、DoesNotExist和 Gt、Lt。NotIn和DoesNotExist允許您定義節點反親和行為。
pod 親和性和反親和性根據節點上已經執行的 Pod 的標籤, 而不是根據node節點標籤來限制 pod排程到節點上。
注意:Pod 親和性和反親和性需要大量資源處理排程,這會在大型叢集中的減慢排程速度。不建議在超過數百個節點的叢集中使用它。
$ cat > pod-affinity.yaml << EOF
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-pod-affinity
spec:
replicas: 3
selector:
matchLabels:
podaffinity: app
template:
metadata:
labels:
podaffinity: app
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "env"
operator: In
values:
- "nginx"
topologyKey: "kubernetes.io/hostname"
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- "web"
topologyKey: "kubernetes.io/hostname"
tolerations:
- key: "active"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: nginx
image: nginx
ports:
- containerPort: 8088
EOF
# requiredDuringSchedulingIgnoredDuringExecution 親和性規則解釋:
# 當一個或多個node節點上的Pod 具有env=nginx標籤, 且pod都位於同一區域或同一類伺服器時,排程程式才能將 Pod 排程到節點上 。更準確地說,排程程式必須將 Pod 放置在具有 topologyKey="kubernetes.io/hostname"標籤的node節點上,且該區域node節點有一個或多個node節點 的Pod 具有env=nginx標籤。
# preferredDuringSchedulingIgnoredDuringExecution 反親和性解釋:
# 表示排程程式應儘量避免將 Pod 排程到一個或多個node節點上的Pod具有app=web標籤的node節點上,更準確地說,具有topologyKey="kubernetes.io/hostname"標籤的node節點上,排程程式必免將pod執行在該區域node節點的pod具有app=web標籤的節點上。
# tolerations(容忍)規則解釋:
# 容忍程式排程pod到具有汙點(taints)node節點上, 汙點鍵為active的node。
# Pod親和性(podAffinity)規則告訴排程程式將每個副本放置在具有app=web標籤的 Pod 的節點上。Pod 反親和性(podAntiAffinity)規則告訴排程器避免排程到具有env=nginx標籤的 Pod 的節點上。
$ cat > nginx-pod-affinity.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-web
spec:
selector:
matchLabels:
app: store
replicas: 3
template:
metadata:
labels:
app: store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: "kubernetes.io/hostname"
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: env
operator: In
values:
- nginx
topologyKey: "kubernetes.io/hostname"
containers:
- name: nginx-server
image: nginx
EOF