目錄
概述
查看 podAffinity的詳細說明
示例1: podAffinity Pod硬親和
示例2: podAffinity 硬親和
示例3: podAntiAffinity 硬反親和
概述:
- 先來了解 topology key 字段
pod親和性調度需要各個相關的pod對象運行于"同一位置", 而反親和性調度則要求他們不能運行于"同一位置",
這里指定“同一位置” 是通過 topologyKey 來定義的,topologyKey 對應的值是 node 上的一個標簽名稱,比如各別節(jié)點zone=A標簽,各別節(jié)點有zone=B標簽,pod affinity topologyKey定義為zone,那么調度pod的時候就會圍繞著A拓撲,B拓撲來調度,而相同拓撲下的node就為“同一位置”。
顧名思義,topology 就是 拓撲的意思,這里指的是一個 拓撲域,是指一個范圍的概念,比如一個 Node、一個機柜、一個機房或者是一個地區(qū)(如杭州、上海)等,實際上對應的還是 Node 上的標簽。這里的 topologyKey 對應的是 Node 上的標簽的 Key(沒有Value),可以看出,其實 topologyKey 就是用于篩選 Node 的。通過這種方式,我們就可以將各個 Pod 進行跨集群、跨機房、跨地區(qū)的調度了。

查看 podAffinity的詳細說明
[root@k8s-master Scheduler]# kubectl explain pods.spec.affinity
KIND: Pod
VERSION: v1
RESOURCE: affinity <Object>
DESCRIPTION:
If specified, the pod's scheduling constraints
Affinity is a group of affinity scheduling rules.
FIELDS:
nodeAffinity <Object> #節(jié)點親和
Describes node affinity scheduling rules for the pod.
podAffinity <Object> #Pod親和
Describes pod affinity scheduling rules (e.g. co-locate this pod in the
same node, zone, etc. as some other pod(s)).
podAntiAffinity <Object> #Pod反親和
Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod
in the same node, zone, etc. as some other pod(s)).
#親和與反親和中又分硬親和 軟親和前一節(jié)提到的Node親和一樣不在累述
[root@k8s-master Scheduler]# kubectl explain pods.spec.affinity.podAffinity
FIELDS:
preferredDuringSchedulingIgnoredDuringExecution <[]Object>
...
requiredDuringSchedulingIgnoredDuringExecution <[]Object>
...
#Pod反親和
[root@k8s-master Scheduler]# kubectl explain pods.spec.affinity.podAntiAffinity
FIELDS:
preferredDuringSchedulingIgnoredDuringExecution <[]Object>
...ffinityTerm; the
node(s) with the highest sum are the most preferred.
requiredDuringSchedulingIgnoredDuringExecution <[]Object>
...
[root@k8s-master Scheduler]# kubectl explain pods.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution
labelSelector <Object>
A label query over a set of resources, in this case pods.
namespaces <[]string>
namespaces specifies which namespaces the labelSelector applies to (matches
against); null or empty list means "this pod's namespace"
topologyKey <string> -required- #拓撲標簽 使用哪一個標簽為位置標簽(必選字段)
This pod should be co-located (affinity) or not co-located (anti-affinity)
with the pods matching the labelSelector in the specified namespaces, where
co-located is defined as running on a node whose value of the label with
key topologyKey matches that of any node on which any of the selected pods
is running. Empty topologyKey is not allowed.
示例1: podAffinity Pod硬親和
requiredDuringSchedulingIgnoredDuringExecution
[root@k8s-master Scheduler]# cat pod-affinity-required-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1 #redis為有狀態(tài)應用 為了測試只運行1個副本
selector:
matchLabels:
app: redis
ctlr: redis
template:
metadata:
labels:
app: redis
ctlr: redis
spec:
containers:
- name: redis
image: redis:6.0-alpine
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-affinity-required
spec:
replicas: 5
selector:
matchLabels:
app: demoapp
ctlr: pod-affinity-required
template:
metadata:
labels:
app: demoapp
ctlr: pod-affinity-required
spec:
containers:
- name: demoapp
image: ikubernetes/demoapp:v1.0
affinity:
podAffinity: #Pod親和
requiredDuringSchedulingIgnoredDuringExecution: #硬親和
- labelSelector:
matchExpressions:
- {key: app, operator: In, values: ["redis"]} #復雜表示達匹配標簽 app=reids、ctlr=redis
- {key: ctlr, operator: In, values: ["redis"]} #兩個表達式為與關系 同時滿足
topologyKey: rack #節(jié)點標簽 位置標簽 rack可以理解為同一個機架上 與labelSelector同樣是與關系同時滿足
[root@k8s-master Scheduler]# kubectl apply -f pod-affinity-required-demo.yaml
deployment.apps/redis unchanged
deployment.apps/pod-affinity-required unchanged
[root@k8s-master Scheduler]# kubectl get pod -o wide #節(jié)點還沒有打上標簽pod-affinity掛機
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-affinity-required-5dd44f5d45-6vvhd 0/1 Pending 0 6m7s <none> <none> <none> <none>
pod-affinity-required-5dd44f5d45-c4hzl 0/1 Pending 0 6m7s <none> <none> <none> <none>
pod-affinity-required-5dd44f5d45-qm6zb 0/1 Pending 0 6m7s <none> <none> <none> <none>
pod-affinity-required-5dd44f5d45-t4mm5 0/1 Pending 0 6m7s <none> <none> <none> <none>
pod-affinity-required-5dd44f5d45-vs7dg 0/1 Pending 0 6m7s <none> <none> <none> <none>
redis-55f46d9795-r7pkz 1/1 Running 0 10m 192.168.51.23 k8s-node3 <none> <none>
- 模擬同一機架不同節(jié)點
[root@k8s-master Scheduler]# kubectl label node k8s-node1 rack=foo #為節(jié)點1把rack標簽
node/k8s-node1 labeled
[root@k8s-master Scheduler]# kubectl label node k8s-node2 rack=bar #為節(jié)點2把rack標簽
node/k8s-node2 labeled
[root@k8s-master Scheduler]# kubectl label node k8s-node3 rack=baz #為節(jié)點3把rack標簽
node/k8s-node3 labeled
- 硬親和與redis運行在相同節(jié)點 都運行在node3上
[root@k8s-master Scheduler]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-affinity-required-5dd44f5d45-6vvhd 1/1 Running 0 21m 192.168.51.28 k8s-node3 <none> <none>
pod-affinity-required-5dd44f5d45-c4hzl 1/1 Running 0 21m 192.168.51.26 k8s-node3 <none> <none>
pod-affinity-required-5dd44f5d45-qm6zb 1/1 Running 0 21m 192.168.51.24 k8s-node3 <none> <none>
pod-affinity-required-5dd44f5d45-t4mm5 1/1 Running 0 21m 192.168.51.25 k8s-node3 <none> <none>
pod-affinity-required-5dd44f5d45-vs7dg 1/1 Running 0 21m 192.168.51.27 k8s-node3 <none> <none>
redis-55f46d9795-r7pkz 1/1 Running 0 25m 192.168.51.23 k8s-node3 <none> <none>
示例2: podAffinity Pod軟親和
preferredDuringSchedulingIgnoredDuringExecution
[root@k8s-master Scheduler]# cat pod-affinity-preferred-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-preferred
spec:
replicas: 1
selector:
matchLabels:
app: redis
ctlr: redis-preferred
template:
metadata:
labels:
app: redis
ctlr: redis-preferred
spec:
containers:
- name: redis
image: redis:6.0-alpine
resources:
requests:
cpu: 200m
memory: 512Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-affinity-preferred
spec:
replicas: 4
selector:
matchLabels:
app: demoapp
ctlr: pod-affinity-preferred
template:
metadata:
labels:
app: demoapp
ctlr: pod-affinity-preferred
spec:
containers:
- name: demoapp
image: ikubernetes/demoapp:v1.0
resources:
requests:
cpu: 500m
memory: 100Mi
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution: #軟親和以不同權重計算分值重出最終的親和節(jié)點
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- {key: app, operator: In, values: ["redis"]}
- {key: ctlr, operator: In, values: ["redis-prefered"]} #Pod包含標簽為app=redis、ctlr=redis-prefered同時滿足
topologyKey: kubernetes.io/hostname #節(jié)點位置標簽 以不同節(jié)點為位置 表示在相同節(jié)點權重為100 所有同一節(jié)點權重最高
- weight: 50
podAffinityTerm:
labelSelector:
matchExpressions:
- {key: app, operator: In, values: ["redis"]}
- {key: ctlr, operator: In, values: ["redis-prefered"]}
topologyKey: rack #節(jié)點標簽 位置標簽 以機架為位置 表示在相同機架權重為50
[root@k8s-master Scheduler]# kubectl apply -f pod-affinity-preferred-demo.yaml
[root@k8s-master Scheduler]# kubectl get pod -o wide #運行在不同的節(jié)點
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-affinity-preferred-57d457968f-4lxvq 1/1 Running 0 5m6s 192.168.113.21 k8s-node1 <none> <none>
pod-affinity-preferred-57d457968f-krb2f 1/1 Running 0 5m6s 192.168.113.20 k8s-node1 <none> <none>
pod-affinity-preferred-57d457968f-mzckm 1/1 Running 0 5m6s 192.168.12.24 k8s-node2 <none> <none>
pod-affinity-preferred-57d457968f-v8n8g 1/1 Running 0 5m6s 192.168.51.37 k8s-node3 <none> <none>
redis-preferred-5d775df679-wtpgs 1/1 Running 0 5m6s 192.168.51.38 k8s-node3 <none> <none>
示例3: podAntiAffinity 硬反親和
requiredDuringSchedulingIgnoredDuringExecution
- Deployment 4個副本必須運行在不同的節(jié)點上 因為node節(jié)點只有3個所有會有個掛起 內部相斥
[root@k8s-master Scheduler]# cat pod-antiaffinity-required-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-antiaffinity-required
spec:
replicas: 4 #運行4個副本
selector:
matchLabels:
app: demoapp
ctlr: pod-antiaffinity-required
template:
metadata:
labels:
app: demoapp
ctlr: pod-antiaffinity-required
spec:
containers:
- name: demoapp
image: ikubernetes/demoapp:v1.0
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- {key: app, operator: In, values: ["demoapp"]}
- key: ctlr
operator: In
values: ["pod-antiaffinity-required"] #Pod包含標簽app=demoapp、ctlr=pod-antiaffinity-required 同時滿足
topologyKey: kubernetes.io/hostname #以節(jié)點為位置 表示每個節(jié)點只能運行1個Pod
[root@k8s-master Scheduler]# kubectl apply -f pod-antiaffinity-required-demo.yaml
[root@k8s-master Scheduler]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-antiaffinity-required-697f7d764d-hgkxj 1/1 Running 0 5m5s 192.168.113.34 k8s-node1 <none> <none>
pod-antiaffinity-required-697f7d764d-n4zt9 1/1 Running 0 5m5s 192.168.12.34 k8s-node2 <none> <none>
pod-antiaffinity-required-697f7d764d-psqfb 1/1 Running 0 5m5s 192.168.51.53 k8s-node3 <none> <none>
pod-antiaffinity-required-697f7d764d-q6t7m 0/1 Pending 0 5m5s <none> <none> <none> <none> #掛起 因為只有3個node節(jié)點