k8s親和性和反親和性的理解


https://www.kancloud.cn/pshizhsysu/kubernetes/2511356

 

 

 

topologyKey用於指定調度時作用域,例如:
如果指定為kubernetes.io/hostname,那就是以Node節點為區分范圍
如果指定為beta.kubernetes.io/os,則以Node節點的操作系統類型來區分

kubernetes.io/hostname不用的節點名稱就是不同的調度區域

我們來看下面的一個案例


**PodAffinity**

PodAffinity主要實現以運行的Pod為參照,實現讓新創建的Pod跟參照pod在一個區域的功能。

首先來看一下`PodAffinity`的可配置項:

~~~markdown
pod.spec.affinity.podAffinity
requiredDuringSchedulingIgnoredDuringExecution 硬限制
namespaces 指定參照pod的namespace
topologyKey 指定調度作用域
labelSelector 標簽選擇器
matchExpressions 按節點標簽列出的節點選擇器要求列表(推薦)
key 鍵
values 值
operator 關系符 支持In, NotIn, Exists, DoesNotExist.
matchLabels 指多個matchExpressions映射的內容
preferredDuringSchedulingIgnoredDuringExecution 軟限制
podAffinityTerm 選項
namespaces
topologyKey
labelSelector
matchExpressions
key 鍵
values 值
operator
matchLabels
weight 傾向權重,在范圍1-100
~~~

~~~markdown
topologyKey用於指定調度時作用域,例如:
如果指定為kubernetes.io/hostname,那就是以Node節點為區分范圍
如果指定為beta.kubernetes.io/os,則以Node節點的操作系統類型來區分
~~~

接下來,演示下`requiredDuringSchedulingIgnoredDuringExecution`,

1)首先創建一個參照Pod,pod-podaffinity-target.yaml:

~~~yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-podaffinity-target
namespace: dev
labels:
podenv: pro #設置標簽
spec:
containers:
- name: nginx
image: nginx:1.17.1
nodeName: node1 # 將目標pod名確指定到node1上
~~~

~~~powershell
# 啟動目標pod
[root@master ~]# kubectl create -f pod-podaffinity-target.yaml
pod/pod-podaffinity-target created

# 查看pod狀況
[root@master ~]# kubectl get pods pod-podaffinity-target -n dev
NAME READY STATUS RESTARTS AGE
pod-podaffinity-target 1/1 Running 0 4s
~~~

2)創建pod-podaffinity-required.yaml,內容如下:

~~~yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-podaffinity-required
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity: #親和性設置
podAffinity: #設置pod親和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
- labelSelector:
matchExpressions: # 匹配env的值在["xxx","yyy"]中的標簽
- key: podenv
operator: In
values: ["xxx","yyy"]
topologyKey: kubernetes.io/hostname
~~~

上面配置表達的意思是:新Pod必須要與擁有標簽nodeenv=xxx或者nodeenv=yyy的pod在同一Node上,顯然現在沒有這樣pod,接下來,運行測試一下。

~~~powershell
# 啟動pod
[root@master ~]# kubectl create -f pod-podaffinity-required.yaml
pod/pod-podaffinity-required created

# 查看pod狀態,發現未運行
[root@master ~]# kubectl get pods pod-podaffinity-required -n dev
NAME READY STATUS RESTARTS AGE
pod-podaffinity-required 0/1 Pending 0 9s

# 查看詳細信息
[root@master ~]# kubectl describe pods pod-podaffinity-required -n dev
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling <unknown> default-scheduler 0/3 nodes are available: 2 node(s) didn't match pod affinity rules, 1 node(s) had taints that the pod didn't tolerate.

# 接下來修改 values: ["xxx","yyy"]----->values:["pro","yyy"]
# 意思是:新Pod必須要與擁有標簽nodeenv=xxx或者nodeenv=yyy的pod在同一Node上
[root@master ~]# vim pod-podaffinity-required.yaml

# 然后重新創建pod,查看效果
[root@master ~]# kubectl delete -f pod-podaffinity-required.yaml
pod "pod-podaffinity-required" deleted
[root@master ~]# kubectl create -f pod-podaffinity-required.yaml
pod/pod-podaffinity-required created

# 發現此時Pod運行正常
[root@master ~]# kubectl get pods pod-podaffinity-required -n dev
NAME READY STATUS RESTARTS AGE LABELS
pod-podaffinity-required 1/1 Running 0 6s <none>
~~~

關於`PodAffinity`的 `preferredDuringSchedulingIgnoredDuringExecution`,這里不再演示。

 

piVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx-affinity-test
  namespace: dev
spec:
  serviceName: nginx-service
  replicas: 2
  selector:
    matchLabels:
      service: nginx
  template:
    metadata:
      name: nginx222
      labels:
        service: nginx
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: service
                operator: In
                values:
                - nginx
            topologyKey: zone
      containers:
      - name: nginx
        image: nginx:1.17.1
        command:
        - sleep
        - "360000000"

 

例子:

需求:當前有兩個機房( beijing,shanghai),需要部署一個nginx產品,副本為兩個,為了保證機房容災高可用場景,需要在兩個機房分別部署一個副本

 

 我們給兩個主機打上標簽

 

 

解釋:兩個node上分別有zone標簽,來標注自己屬於哪個機房,topologyKey定義為zone,pod所以在調度的時候,會根據node上zone標簽來區分拓撲域,當前用的上 反親和性調度 根據拓撲緯度調度,beijing機房調度完一個pod后,然后控制器判斷beijing 拓撲域已經有server=nginx標簽的pod,就在下一個拓撲域的node上調度了,所以兩個niginx pod 分別部署在node1和node2兩個節點上面

 

 




 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM