十八、K8S-亲和性和反亲和性

2024-02-05 18:52
文章标签 云原生 k8s 十八 亲和性

本文主要是介绍十八、K8S-亲和性和反亲和性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

k8s中亲和性和反亲和性

一、固定节点调度 

1、nodeSelector(通过标签选择方式调度)

2、nodeName调度(通过指定节点名称的方式)

二、node亲和性

1、node 硬亲和性

2、node软亲和性

三、pod亲和性

1、pod硬亲和性

2、pod软亲和性

3、pod反亲和性

四、亲和性和反亲和性详细yaml文件

五、topology拓扑域的概念

 1、服务拓扑


k8s中亲和性和反亲和性

        kubernetes的默认调度以预选、优选、选定机制完成将每个新的Pod资源绑定至为其选出的目标节点上,不过,它只是pod对象的默认调度器,默认情况下调度器考虑的是资源足够,并且负载尽量平均。

        在使用中,可以自定义调度器插件,并在定义pod资源配置清单时通过spec.schedulerName指定即可

Affinity:

  1. nodeAffinity: 节点亲和力
    1. requiredDuringSchedulingIgnoredDuringExecution:硬亲和性,强制的,即支持必须部署在指定的节点上,也支持必须不部署在指定节点上,
    2. preferredDuringSchedulingIgnoredDuringExecution:软亲和性,尽量部署在满足条件的节点上,或者尽量不部署在满足条件的节点上
  2. podAffinity:pod亲和力
    1. requiredDuringSchedulingIgnoredDuringExecution:硬亲和性,强制的,将A应用和B 应用部署在一起
    2. preferredDuringSchedulingIgnoredDuringExecution:软亲和性,尽量将A应用和B 应用部署在一起
  3. podAntiAffinity:pod反亲和力
    1. requiredDuringSchedulingIgnoredDuringExecution:不要将A和B部署在一起
    2. preferredDuringSchedulingIgnoredDuringExecution:尽量不要将A和B部署在一起

一、固定节点调度 

1、nodeSelector(通过标签选择方式调度)

        对于最初k8s实现pod指定node调度时使用nodeSelector来实现的,主要是通过定义node以及pod标签进行选择,具体实现如下

1、给节点添加label标签
[root@k8s-master-1 diaodu]# kubectl label node k8s-node-2 ds=true
[root@k8s-master-1 diaodu]# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: taint-testlabels:ds: "true"
spec:replicas: 5selector:matchLabels:ds: "true"template:metadata:labels:ds: "true"spec:nodeSelector: #选择标签ds: "true"containers:- image: nginx:1.17.1name: nginx
[root@k8s-master-1 diaodu]# kubectl apply -f deployment.yaml 
deployment.apps/taint-test created
[root@k8s-master-1 diaodu]# 
[root@k8s-master-1 diaodu]# 
[root@k8s-master-1 diaodu]# kubectl get pod -owide
NAME                         READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
taint-test-cbf7b4fdd-jf2rc   1/1     Running   0          4s    10.244.1.69   k8s-node-2   <none>           <none>
taint-test-cbf7b4fdd-k6fmg   1/1     Running   0          4s    10.244.1.70   k8s-node-2   <none>           <none>
taint-test-cbf7b4fdd-r9pvn   1/1     Running   0          4s    10.244.1.73   k8s-node-2   <none>           <none>
taint-test-cbf7b4fdd-t8p56   1/1     Running   0          4s    10.244.1.71   k8s-node-2   <none>           <none>
taint-test-cbf7b4fdd-zcdsz   1/1     Running   0          4s    10.244.1.72   k8s-node-2   <none>           <none>

2、nodeName调度(通过指定节点名称的方式)


[root@k8s-master-1 diaodu]# vim test2.yaml apiVersion: apps/v1
kind: Deployment
metadata:name: test2labels:test: "server"
spec:replicas: 3selector:matchLabels:test: "server"template:metadata:labels:test: "server"spec:nodeName: k8s-node-2        containers:- image: nginx:1.17.1name: nginximagePullPolicy: IfNotPresent  
[root@k8s-master-1 diaodu]# kubectl get pod -owide
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
test2-68d7b6dc48-4bn9q   1/1     Running   0          6s    10.244.1.128   k8s-node-2   <none>           <none>
test2-68d7b6dc48-5t9lg   1/1     Running   0          6s    10.244.1.129   k8s-node-2   <none>           <none>
test2-68d7b6dc48-6stqv   1/1     Running   0          6s    10.244.1.130   k8s-node-2   <none>           <none>

二、node亲和性

        NodeAffinity 意为Node节点亲和性的调度策略,是用于替换NodeSelector的全新调度策略

        定义节点亲和性规则时有两种类型的节点亲和性规则:硬亲和性required和软亲和性perferred,硬亲和性实现的是强制性规则,它是Pod调度时必须要满足的规则,而在不存在满足规则的节点时,Pod对象会被置为Pending状态。而软亲和性规则实现的是一种柔性调度限制,它倾向于将pod对象运行与某类特定的节点上,而调度器也将尽量满足此需求,但在无法满足调度需求时它将退而求其次地选择一个不匹配规则的节点。

1、node 硬亲和性

        为pod对象使用nodeSelector属性可以基于节点标签匹配的方式将pod对象强制调度到某一类特定的节点上,不过它仅能基于简单的等值关系定义标签选择器,而nodeAffinity中支持使用matchExpressions属性构建更为复杂的标签选择机制.

        节点的亲和性是通过Pod.spec的affinity字段下的nodeAffinity字段进行指定的。

[root@k8s-master-1 diaodu]# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: taint-testlabels:ds: "true"
spec:replicas: 3selector:matchLabels:ds: "true"template:metadata:labels:ds: "true"spec:containers:- image: nginx:1.17.1name: nginximagePullPolicy: IfNotPresentaffinity:nodeAffinity:#作用域,Pod和Node之间requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: dsoperator: Invalues:- "true"
[root@k8s-master-1 diaodu]# kubectl apply -f deployment.yaml 
deployment.apps/taint-test created
[root@k8s-master-1 diaodu]# [root@k8s-master-1 diaodu]# kubectl get pod -owide
NAME                          READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
taint-test-6ffb5f4cc4-6wv4x   1/1     Running   0          5s    10.244.1.75   k8s-node-2   <none>           <none>
taint-test-6ffb5f4cc4-9mcjk   1/1     Running   0          5s    10.244.1.77   k8s-node-2   <none>           <none>
taint-test-6ffb5f4cc4-jjrkd   1/1     Running   0          5s    10.244.1.76   k8s-node-2   <none>           <none>

        在定义节点亲和性时,requiredDuringSchedulingIgnoredDuringExecution字段的值是一个对象列表,用于定义节点硬亲和性,它可由一个或者多个nodeSelectorTerm定义的对象组成,彼此间为“逻辑或”的关系,进行匹配度检查时,在多个nodeSelectorTerm之间只要满足其中之一即可。

        preferredDuringSchedulingIgnoredDuringExecution和requiredDuringSchedulingIgnoredDuringExecution名字中的后半段符串IgnoredDuringExecution隐含的意义所指,在Pod资源基于节点亲和性规则调度至某节点之后,节点标签发生了改变而不再符合此节点亲和性规则时 ,调度器不会将Pod对象从此节点上移出,因为,它仅对新建的Pod对象生效。

        nodeSelectorTerm用于定义节点选择器条目,其值为对象列表,它可由一个或多个matchExpressions对象定义的匹配规则组成,多个规则彼此之间为“逻辑与”的关系, 这就意味着某节点的标签需要完全匹配同一个nodeSelectorTerm下所有的matchExpression对象定义的规则才算成功通过节点选择器条目的检查。而matchExmpressions又可由 一到多 个标签选择器组成,多个标签选择器彼此间为“逻辑与”的关系 。

        注意事项

  • 如果同时指定了nodeSelector和nodeAffinity,两者必须都要满足,才能将Pod调度到候选节点上;
  • 如果指定了多个与nodeAffinity类型关联的nodeSelectorTerms,只要其中有一个nodeSelectorTerms满足的话,Pod就可以调度到指定节点上;
  • 如果指定了多个与nodeSelectorTerms关联的matchExpressions,则只有当所有的matchExpressions满足要求,Pod才会调度到指定节点上;
  • 如果我们修改或删除了Pod所调度到的节点的标签,Pod不会被删除;
  • 软策略中的weight属性是权重的意思,取值范围是1-100。如果存在多个软策略的话,对于亲和性规则而言,权重越大越亲和;对于反亲和性规则而言,权重越大越不亲和。
给node1打一个标签
[root@k8s-master-1 diaodu]# kubectl label node k8s-node-1 ds=server
node/k8s-node-1 labeledaffinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:    # 硬策略nodeSelectorTerms:- matchExpressions:- key: dsoperator: Invalues:- "true"- "server"
- - - 或者- - -affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:#逻辑或的关系,满足其一即可- matchExpressions:- key: dsoperator: Invalues:- "true"- matchExpressions:- key: dsoperator: Invalues:- "server"########启动pod,都会在node2和node1上调度
[root@k8s-master-1 diaodu]# kubectl get pod -owide
NAME                          READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
taint-test-68485fdf87-5fvz5   1/1     Running   0          4s    10.244.0.44   k8s-node-1   <none>           <none>
taint-test-68485fdf87-b644w   1/1     Running   0          4s    10.244.1.79   k8s-node-2   <none>           <none>
taint-test-68485fdf87-f4cfx   1/1     Running   0          4s    10.244.0.45   k8s-node-1   <none>           <none>
taint-test-68485fdf87-h7kp9   1/1     Running   0          4s    10.244.1.81   k8s-node-2   <none>           <none>
taint-test-68485fdf87-j2m8z   1/1     Running   0          4s    10.244.1.80   k8s-node-2   <none>           <none>- - -或者- - -
node1上原来标签删除,重新添加一个新的标签
[root@k8s-master-1 diaodu]# kubectl label node k8s-node-1 test=server
node/k8s-node-1 labeledaffinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: ds #逻辑与的关系,必须同时满足,此时创建pod状态为:Pending,operator: Invalues:- "true"- key: testoperator: Invalues:- "server"[root@k8s-master-1 diaodu]# kubectl get pod -owide
NAME                          READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
taint-test-57f98dd8c8-59kb7   0/1     Pending   0          4s    <none>   <none>   <none>           <none>
taint-test-57f98dd8c8-7sh6w   0/1     Pending   0          4s    <none>   <none>   <none>           <none>
taint-test-57f98dd8c8-8cxxr   0/1     Pending   0          4s    <none>   <none>   <none>           <none>
taint-test-57f98dd8c8-dwm9r   0/1     Pending   0          4s    <none>   <none>   <none>           <none>
taint-test-57f98dd8c8-mshmd   0/1     Pending   0          4s    <none>   <none>   <none>           <none>此时创建pod状态为:Pending,因为他是逻辑与的关系,两个条件必须同时满足 才能创建成功,我们在node1上添加标签[root@k8s-master-1 diaodu]# kubectl label node k8s-node-1 ds=true
node/k8s-node-1 labeled此时pod状态为:Running,因为只有node1满足条件,所以都被调度到node1上了。
[root@k8s-master-1 diaodu]# kubectl get pod -owide
NAME                          READY   STATUS    RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
taint-test-57f98dd8c8-59kb7   1/1     Running   0          104s   10.244.0.52   k8s-node-1   <none>           <none>
taint-test-57f98dd8c8-7sh6w   1/1     Running   0          104s   10.244.0.50   k8s-node-1   <none>           <none>
taint-test-57f98dd8c8-8cxxr   1/1     Running   0          104s   10.244.0.51   k8s-node-1   <none>           <none>
taint-test-57f98dd8c8-dwm9r   1/1     Running   0          104s   10.244.0.48   k8s-node-1   <none>           <none>
taint-test-57f98dd8c8-mshmd   1/1     Running   0          104s   10.244.0.49   k8s-node-1   <none>           <none>

构建标签选择器表达式中支持使用操作符有In、NotIn、Exists、DoesNotExist、Lt、和Gt等

  • In:label的值在某个列表中
  • NotIn:label的值不在某个列表中
  • Gt:label的值大于某个值
  • Lt:label的值小于某个值
  • Exists:某个label存在####value为任意值
  • DoesNoExist:某个label

2、node软亲和性

        节点软亲和性为节点选择机制提供了一种柔性控制逻辑,被调度的pod对象不再试“必须”而是“应该”,放置于某些特定的节点上,当条件不满足时它也能够接受被编排于其他不符合条件的节点之上,另外,它还为每种倾向性提供了weight属性便于用户定义其优先级,取值范围是1-100,数字越大优先级越高。

[root@k8s-master-1 diaodu]# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: taint-testlabels:ds: "true"
spec:replicas: 5selector:matchLabels:ds: "true"template:metadata:labels:ds: "true"spec:
#      nodeSelector:
#        ds: "true"containers:- image: nginx:1.17.1name: nginximagePullPolicy: IfNotPresentaffinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:  # 软策略- weight: 80    ###设置ds=true的权重为80preference:matchExpressions:- key: dsoperator: Invalues:- "true"- weight: 20    ###设置test=server的权重为20preference:matchExpressions:- key: testoperator: Invalues:- "server"
[root@k8s-master-1 diaodu]# kubectl get pod -owide
NAME                          READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
taint-test-7bf8b98c9d-492h2   1/1     Running   0          6s    10.244.1.91   k8s-node-2   <none>           <none>
taint-test-7bf8b98c9d-ff42s   1/1     Running   0          6s    10.244.1.90   k8s-node-2   <none>           <none>
taint-test-7bf8b98c9d-g9wqb   1/1     Running   0          6s    10.244.1.89   k8s-node-2   <none>           <none>
taint-test-7bf8b98c9d-grbqv   1/1     Running   0          6s    10.244.1.88   k8s-node-2   <none>           <none>
taint-test-7bf8b98c9d-hpbxr   1/1     Running   0          6s    10.244.0.55   k8s-node-1   <none>           <none>
#####启动pod如下,会发现大部分pod在ds=true的node上

三、pod亲和性

        Pod亲和性指的是满足特定条件的pod对象运行在同一个node上,而反亲和性调度则要求它们不能运行在同一个node上

1、pod硬亲和性

        Pod强制约束的亲和性调度也是用requiredDuringSchedulinglgnoredDuringExecution属性进行定义

查看有标签为ds=true的pod
[root@k8s-master-1 diaodu]# kubectl get pod -l ds=true -owide
NAME                          READY   STATUS    RESTARTS   AGE    IP             NODE         NOMINATED NODE   READINESS GATES
test-848f897788-vjlbv   1/1     Running   0          107s   10.244.1.105   k8s-node-2   <none>           <none>[root@k8s-master-1 diaodu]# vim deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: taint-testlabels:ds: "true"
spec:replicas: 5selector:matchLabels:ds: "true"template:metadata:labels:ds: "true"spec:containers:- image: nginx:1.17.1name: nginximagePullPolicy: IfNotPresentaffinity:podAffinity:#作用域,Pod和Pod之间requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: dsoperator: Invalues:- "true"namespaces:- kube-system                    topologyKey: kubernetes.io/hostname
[root@k8s-master-1 diaodu]# kubectl apply -f deployment.yaml 
deployment.apps/taint-test created
[root@k8s-master-1 diaodu]# [root@k8s-master-1 diaodu]# kubectl get pod -owide
NAME                          READY   STATUS    RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
taint-test-7c4f9995f6-4sj82   1/1     Running   0          8m54s   10.244.1.111   k8s-node-2   <none>           <none>
taint-test-7c4f9995f6-6crp6   1/1     Running   0          8m54s   10.244.1.113   k8s-node-2   <none>           <none>
taint-test-7c4f9995f6-skxk5   1/1     Running   0          8m54s   10.244.1.112   k8s-node-2   <none>           <none>
taint-test-7c4f9995f6-x6vp9   1/1     Running   0          8m54s   10.244.1.114   k8s-node-2   <none>           <none>
taint-test-7c4f9995f6-xkv5j   1/1     Running   0          8m54s   10.244.1.115   k8s-node-2   <none>           <none>
test-848f897788-tt6kj         1/1     Running   0          9m30s   10.244.1.110   k8s-node-2   <none>           <none>在调度示例中的Deployment控制器创建的Pod资源时,调度器首先会基于标签选择器 查询拥有标签ds=true的所有Pod资源,
接着获取到它们分别所属 的节点的zone标签值,接下来再查询拥有匹配这些标签值的所有节点,从而完成节点预选。
而后根据优选函数计算这些节点的优先级,从而挑选出运行新建Pod对象的节点。上面这个例子中的 pod 需要调度到某个指定的主机上,至少有一个节点上运行了这样的 pod:这个 pod 有一个ds=true的 label。
加入对应ds=true的label的pod在node2上,我们部署的5个 pod 副本也应该运行在 node02 节点namespaces:如果写了namespaces字段,但是值为空的话,它是匹配所有namespaces下指定label的Pod
如果写了namespaces,并且指定了该值,那么他就会筛选指定namespaces下的指定label的Pod.
如果没有写namespaces,就会匹配当前的namespaces
topologyKey: kubernetes.io/hostname  拓扑域,意思就是我们当前调度的 pod 要和目标的 pod 处于同一个主机上面,因为要处于同一个拓扑域下面,
为了说明这个问题,我们把拓扑域改成beta.kubernetes.io/os,同样的我们当前调度的 pod 要和目标的 pod 处于同一个拓扑域中,
目标的 pod 是不是拥有beta.kubernetes.io/os=linux的标签,而我们这里3个节点都有这样的标签,这也就意味着我们3个节点都在同一个拓扑域中,
所以我们这里的 pod 可能会被调度到任何一个节点:

2、pod软亲和性

        类似于节点亲和机制,Pod也支持使用preferredDuringSchedulinglgnoredDuringExecution属性定义柔性亲和机制,调度器会尽力确保满足亲和约束的调度逻辑,然而在约束条件不能得到满足时,他也允许将Pod对象调度值其他节点运行。下面是使用了Pod软亲和性调度机制的资源配置清单示例:

#Pod软亲和性
[root@k8s-master-1 diaodu]# kubectl get pod --show-labels
NAME                          READY   STATUS    RESTARTS   AGE     LABELStest-848f897788-tt6kj         1/1     Running   0          19m     ds=true,pod-template-hash=848f897788
test2-5897dbc444-8wdth        1/1     Running   0          6m37s   pod-template-hash=5897dbc444,test=server
[root@k8s-master-1 diaodu]# vim deployment.yaml spec:containers:- image: nginx:1.17.1name: nginximagePullPolicy: IfNotPresent
#Pod软亲和性affinity:podAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 90podAffinityTerm:labelSelector:matchExpressions:- key: testoperator: Invalues:- "server"topologyKey: kubernetes.io/hostname- weight: 5podAffinityTerm:labelSelector:matchExpressions:- key: dsoperator: Invalues:- "true"topologyKey: kubernetes.io/hostname
创建成功之后
pod软硬亲和性时针对pod而言的,是先判断该节点上存在不存在有标签为test=server的pod或者标签为ds=true的pod,
如果有则有90的权重会调度到test=server节点,5的权重会调度到ds=true节点
[root@k8s-master-1 diaodu]# kubectl get pod -owide
NAME                          READY   STATUS    RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
taint-test-77c94446f7-5scz7   1/1     Running   0          4s      10.244.0.74    k8s-node-1   <none>           <none>
taint-test-77c94446f7-gxzzz   1/1     Running   0          4s      10.244.1.122   k8s-node-2   <none>           <none>
taint-test-77c94446f7-n4kbx   1/1     Running   0          4s      10.244.0.75    k8s-node-1   <none>           <none>
taint-test-77c94446f7-n8qk2   1/1     Running   0          4s      10.244.0.76    k8s-node-1   <none>           <none>
taint-test-77c94446f7-vdsjj   1/1     Running   0          4s      10.244.0.77    k8s-node-1   <none>           <none>
test-848f897788-tt6kj         1/1     Running   0          18m     10.244.1.110   k8s-node-2   <none>           <none>
test2-5897dbc444-8wdth        1/1     Running   0          5m53s   10.244.0.64    k8s-node-1   <none>           <none>

3、pod反亲和性

        podAffinity用于定义Pod对象的亲和性约束,对应的,将其替换为podAntiAffinity即可用于定义Pod的反亲和约束。不过,反亲和性调度一般用于分散同一类应用的Pod对象等,也包括将不同安全级别的Pod对象调整至不同 的区域,机架或节点等,下面的资源配置清单中定义了由同一Deployment创建但彼此基于节点位置互斥的Pod对象:

[root@k8s-master-1 diaodu]# kubectl get pod -owide --show-labels
NAME                          READY   STATUS    RESTARTS   AGE    IP             NODE         NOMINATED NODE   READINESS GATES   LABELStest-848f897788-28qwn         1/1     Running   0          2m7s   10.244.1.125   k8s-node-2   <none>           <none>            ds=true,pod-template-hash=848f897788
test2-5897dbc444-2tp2g        1/1     Running   0          25s    10.244.0.80    k8s-node-1   <none>           <none>            pod-template-hash=5897dbc444,test=server
[root@k8s-master-1 diaodu]# vim deployment.yamlspec:containers:- image: nginx:1.17.1name: nginximagePullPolicy: IfNotPresent
#Pod反亲和性affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: testoperator: Invalues:- "server"topologyKey: kubernetes.io/hostname
[root@k8s-master-1 diaodu]# kubectl apply -f deployment.yaml 
deployment.apps/taint-test created
从上面的标签就可以看出来,pod标签为test=server的pod 在node1上,根据pod反亲和性的规则,创建的deploy声明了不让他调度到test=server的pod
所在的节点上。
[root@k8s-master-1 diaodu]# kubectl get pod -owide
NAME                          READY   STATUS    RESTARTS   AGE    IP             NODE         NOMINATED NODE   READINESS GATES
taint-test-78f8c5f9c6-7n7m2   1/1     Running   0          4s     10.244.1.126   k8s-node-2   <none>           <none>
taint-test-78f8c5f9c6-w24bj   1/1     Running   0          4s     10.244.1.127   k8s-node-2   <none>           <none>
test-848f897788-28qwn         1/1     Running   0          111s   10.244.1.125   k8s-node-2   <none>           <none>
test2-5897dbc444-2tp2g        1/1     Running   0          9s     10.244.0.80    k8s-node-1   <none>           <none>

四、亲和性和反亲和性详细yaml文件

[root@k8s-master-1 diaodu]# cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: taint-testlabels:ds: "true"
spec:replicas: 2selector:matchLabels:ds: "true"template:metadata:labels:ds: "true"spec:containers:- image: nginx:1.17.1name: nginximagePullPolicy: IfNotPresent
#Pod反亲和性affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: testoperator: Invalues:- "server"topologyKey: kubernetes.io/hostname#Pod软亲和性
#      affinity:
#        podAffinity:
#          preferredDuringSchedulingIgnoredDuringExecution:
#          - weight: 90
#            podAffinityTerm:
#              labelSelector:
#                matchExpressions:
#                - key: test
#                  operator: In
#                  values:
#                  - "server"
#              topologyKey: kubernetes.io/hostname
#          - weight: 5
#            podAffinityTerm:
#              labelSelector:
#                matchExpressions:
#                - key: ds
#                  operator: In
#                  values:
#                  - "true"
#              topologyKey: kubernetes.io/hostname#Pod 硬亲和性
#      affinity:
#        podAffinity:
#          requiredDuringSchedulingIgnoredDuringExecution:
#          - labelSelector:
#              matchExpressions:
#              - key: ds
#                operator: In
#                values:
#                - "true"
#            topologyKey: kubernetes.io/hostname#            
#node 软亲和性
#      affinity:
#        nodeAffinity:
#          preferredDuringSchedulingIgnoredDuringExecution:
#          - weight: 80
#            preference:
#              matchExpressions:
#              - key: ds
#                operator: In
#                values:
#                - "true"
#          - weight: 20
#            preference:
#              matchExpressions:
#              - key: test
#                operator: In
#                values:
#                - "server"#- - - - -               
# node硬亲和性
#      affinity:
#        nodeAffinity:
#          requiredDuringSchedulingIgnoredDuringExecution:
#            nodeSelectorTerms:
#            - matchExpressions:
#              - key: ds
#                operator: In
#                values:
#                - "true"
#              - key: test
#                operator: In
#                values:
#                - "server"

五、topology拓扑域的概念

如图所示:

北京是一个拓扑域

        朝阳是一个拓扑域

                大兴是一个拓扑域

上海是一个拓扑域

        上海机房是一个拓扑域

                机房中机柜A是一个拓扑域

                        机柜中主机A是一个拓扑域

                机房中机柜B是一个拓扑域

关于topologyKey属性的解释说明:

  • topologyKey:属性是用于表示一个拓扑域的,并不是表示一个节点,一个拓扑域可以包含多个节点;
  • topologyKey:后跟的是节点标签的key值,假设k8s集群中有A、B、C三个节点,它们都拥有名为env这个相同的key值的节点标签,但是标签的value值分别是dev、test、prod,那么这时候拓扑域和集群中的节点就是一对一的关系,这时候将Pod调度到拓扑域上就是指将Pod调度到k8s集群的某一节点上。如果A、B两个节点的标签的value值都是dev,而C节点的标签的value值是test的话,拓扑域和节点就是一对多的关系了,这时候A、B节点处于同一拓扑域,C节点处于另一个拓扑域;
  • Pod间的亲和性规则并不是说两个Pod一定会处于同一个节点上,只有当拓扑域和节点时一对一的关系的时候,才会被调度到同一个节点上,如果拓扑域中包含多个节点的haunt,配置了Pod间亲和性规则后,k8s只会该Pod调度到另一个Pod相同拓扑域中的某一个节点上,并不一定就和另一个Pod是同一个节点,但一定和这个Pod处于同一拓扑域;

 1、服务拓扑

        是实现基于Node 拓扑的流量路由,例如,将发送到某个服务的流量优先路由到与客户端相同的Node的Endpoint上,或者路由到与客户端相同点Zone的那些node的Endpoint上。

        服务括扑机制需要通过设置 kube-apiserver 和 kube-proxy 服务的启动参制--feature-gates="ServiceTopology=true,EndpointSlice=true"进行启用 (需要周时启mipointsSlice 功能),然后就可以在 Service 源对象上通过定义 topoloyKeys 字段来转制到Service 的流量路由了。

        topologyKeys 字段设置的是一组 Node 标签列表,按顺序匹配 Node完成流量的路由转发,流量会被转发到标签匹配成功的 Node 上。如果第 1 个标签找不到匹配的 Node.尝试匹配第 2 个标签,以此类推。如果全部标签都没有匹配的 Node,则请求将被拒绝。

        将 topologyKeys 配置为“*”表示任意拓扑,它只能作为配置列表中的最后一个才有效,如果完全不设置 topologyKeys 字段,或者将其值设置为空,就相当于没有启用服务拓扑功能。

        对于需要使用服务拓扑机制的集群,管理员需要为 Node 设置相应的拓扑标签,包括kubernetes.io/hostname、topology.kubernetes.io/zone 和 topology.kubernetes.io/region.

然后为 Service 设置 topologyKeys 的值,就可以实现如下流量路由策略:

  • 配置为["kubernetes.io/hostname”]:流量只会被路由到相同 Node 的 Endpoint 上,如果 Node 的 Endpoint 不存在,则将请求丢弃。
  • 配置为["kubernetes.io/hostname"、"topology.kubernetes.io/zone"、"topology.kubernetesio/region”]:流量优先被路由到相同 Node 的 Endpoint 上,如果 Node 没有 Endpoint,流量则被路由到相同 zone 的 Endpoint 上;如果在 one 中没有 Endpoint,流量则被路由到相同 region 的 Endpoint 上。
  • 配置为["topology.kubernetes.io/zone","*":流量优先被路由到同zone的Endpoint 上,如果zone中没有可用的Endpoint,流量则被路由到任意可用的Endpoint上

示例:

(1)只将流量路由到相同 Node 的 Endpoint 上,如果 Node 没有可用的 Endpoimt,将请求丢弃:
apiVersion: vl
kind: Service
metadata:name: webapp
spec:selector:app: webappports:- port:8080topologyKeys :- "kubernetes.io/hostname"
(2)优先将流量路由到相同 Node 的 Endpoint 上,如 Node 没有可用的 Endpoint,则将请求路由到任意可用的 Endpoint:
apiVersion: vl
kind: Service
metadata:name: webapp
spec:selector:app: webappports:- port:8080topologyKeys :- "kubernetes.io/hostname"- "*"
(3)只将流量路由到相同 zone或同 region 的 Endpoint 上,如没有可用的 Endpoint,将请求丢弃:
apiVersion: vl
kind: Service
metadata:name: webapp
spec:selector:app: webappports:- port:8080topologyKeys :- "topology.kubernetes.io/zone"- "topology.kubernetesio/region"
(4)按同Node 同zone 同 region 的优先级顺序路有流量,如果Node、zone、region都没有可用的Endpoint,则将请求路由到任意可用的 Endpoint:
apiVersion: vl
kind: Service
metadata:name: webapp
spec:selector:app: webappports:- port:8080topologyKeys :- "kubernetes.io/hostname"- "topology.kubernetes.io/zone"- "topology.kubernetesio/region"- "*"

这篇关于十八、K8S-亲和性和反亲和性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/681842

相关文章

90、k8s之secret+configMap

一、secret配置管理 配置管理: 加密配置:保存密码,token,其他敏感信息的k8s资源 应用配置:我们需要定制化的给应用进行配置,我们需要把定制好的配置文件同步到pod当中容器 1.1、加密配置: secret: [root@master01 ~]# kubectl get secrets ##查看加密配置[root@master01 ~]# kubectl get se

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群 华为云最近正在举办828 B2B企业节,Flexus X实例的促销力度非常大,特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求,一定不要错过这个机会。赶紧去看看吧! 什么是华为云Flexus X实例 华为云Flexus X实例云服务是新一代开箱即用、体

云原生之高性能web服务器学习(持续更新中)

高性能web服务器 1 Web服务器的基础介绍1.1 Web服务介绍1.1.1 Apache介绍1.1.2 Nginx-高性能的 Web 服务端 2 Nginx架构与安装2.1 Nginx概述2.1.1 Nginx 功能介绍2.1.2 基础特性2.1.3 Web 服务相关的功能 2.2 Nginx 架构和进程2.2.1 架构2.2.2 Ngnix进程结构 2.3 Nginx 模块介绍2.4

用Cri-O,Sealos CLI,Kubeadm方式部署K8s高可用集群

3.6 Cri-O方式部署K8s集群 注意:基于Kubernetes基础环境 3.6.1 所有节点安装配置cri-o [root@k8s-all ~]# VERSION=1.28[root@k8s-all ~]# curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensu

培训第九周(部署k8s基础环境)

一、前期系统环境准备 1、关闭防火墙与selinux  [root@k8s-master ~]# systemctl stop firewalld[root@k8s-master ~]# systemctl disable firewalldRemoved symlink /etc/systemd/system/multi-user.target.wants/firewalld.servi

k8s 存储(PV、PVC、SC、本地存储、NFS)

存储持久化相关三个概念: PersistentVolume (PV) 是对具体存储资源的描述,比如NFS、Ceph、GlusterFS等,通过PV可以访问到具体的存储资源;PersistentVolumeClaim (PVC) Pod想要使用具体的存储资源需要对接到PVC,PVC里会定义好Pod希望使用存储的属性,通过PVC再去申请合适的存储资源(PV),匹配到合适的资源后PVC和PV会进行绑定

CPU亲和性设置 代码示例 sched_setaffinity sched_getaffinity

视频教程在这: cpu亲和性设置,NCCL,sched_setaffinity sched_getaffinity,CPU_ZERO、SET、ISSET、linux_哔哩哔哩_bilibili 一、CPU亲和性简介 CPU亲和性(CPU Affinity)设置是操作系统中一个重要的性能优化手段,它允许程序或进程被绑定到特定的CPU核心上运行。这样做的好处包括减少缓存未命中、降低线程迁移(co

k8s调度(pod亲和、反亲和、污点、容忍度)

pod亲和性 针对对象为Pod,目的是实现,新建Pod和目标Pod调度到一起,在同一个Node上。 示例: apiVersion: v1kind: Podmetadata:name: testpod01labels:app: myapp01env: test1spec:containers:- name: testpod01image: nginx:1.23.2---apiVersio