Kubernetes 的亲和性污点与容忍
Kubernetes 的亲和性污点与容忍
在Kubernetes 中,调度 是指将 Pod 部署到合适的节点(node)上。
k8s的默认调度器是kube-scheduler,它执行的是一个类似平均分配的原则,让同一个service管控下的pod尽量分散在不同的节点。
节点标签
节点标签关联的指令是kubectl label,标签是是一种键值对,可以用来标识和选择资源。例如:需要给某个节点打个标记以便后面用的上,这个标记就叫标签。
增加标签
kubectl label node docker-desktop restype=strong-cpu
这里增加了一个 restype=strong-cpu 的标签,表示这个节点cpu很强;
查看标签
kubectl get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELS docker-desktop Ready <none> 328d v1.22.5 disktype=ssd
删除标签
kubectl label node docker-desktop restype- nodeSelector-简单的节点选择器 nodeSelector:在部署pod的时候告诉集群,我要部署到符合我要求的节点; 前面已经看到我k8s的节点 docker-desktop ,已经打了 disktype=ssd 的标签,那我们来部署一个测试的pod看看
affinity: 亲和性
requiredDuringSchedulingIgnoredDuringExecution:硬策略
preferredDuringSchedulingIgnoredDuringExecution:软策略
nodeSelectorTerms:节点选择项,数组
matchExpressions:匹配表达式,数组
weight: preferredDuringSchedulingIgnoredDuringExecution 可设置的权重字段,值范围是 1 到 100。会计算到调度打分算法上,分数高的优先级高;
operator:逻辑操作符,比如这里的in表示包含,一共有以下逻辑运算符;
- In:label 的值在某个列表中
- NotIn:label 的值不在某个列表中
- Gt:label 的值大于某个值
- Lt:label 的值小于某个值
- Exists:某个 label 存在
- DoesNotExist:某个 label 不存在
#可用NotIn和DoesNotExist实现反亲和性;
匹配规则:
如果你同时指定了 nodeSelector 和 nodeAffinity , 两者必须都要满足, 才能将 Pod 调度到候选节点上。
如果你在与 nodeAffinity 类型关联的 nodeSelectorTerms 中指定多个条件, 只要其中一个 nodeSelectorTerms 满足,Pod 就可以被调度到节点上。
如果你在与 nodeSelectorTerms 的一个 matchExpressions 中写个表达式, 则只有当所有表达式都满足,Pod 才能被调度到节点上。
pod间的亲和反亲和性
前面的节点亲和性是通过pod和节点之间的标签进行匹配,选择的;
pod的亲和性和反亲和性调度指:通过已在运行中的pod标签进行选择调度部署的节点;
pod的亲和性调度:一个典型的使用场景就是在集群环境是有多数据中心的,那一个服务部署已经部署到广东了,那我跟他相关的需要大量通信的其他服务也尽量部署到广东,降低彼此间的通信延迟;
pod的反亲和性调度:一个典型的使用场景就是我的服务要尽可能分散到各个数据中心、区域,比如广东、西安、上海、北京,都要有我的服务,避免某个数据中心故障服务全部宕机;
案列:
podAffinity: #pod亲和性 requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: restype operator: In values: - strong-cpu topologyKey: topology.kubernetes.io/zone #topology.kubernetes.io/hostname 表示同一节点 podAntiAffinity: #pod间反亲和性 preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: disktype operator: In values: - ssd topologyKey: topology.kubernetes.io/zone
亲和性规则表示:当且仅当至少一个已运行且有 restype=strong-cpu 的标签的 Pod 处于同一区域时(topology.kubernetes.io/zone=GuangDong),才可以将该 Pod 调度到节点上。
反亲和性规则表示:如果节点处于 Pod 所在的同一可用区(也是看topology.kubernetes.io/zone)且至少一个 Pod 具有 disktype=ssd 标签,则该 Pod 不应被调度到该节点上。
亲和性调度
kubernetes亲和性调度(Affinity),它在NodeSelector的基础之上进行了扩展,可以通过配置的形式,实现优先选择满足条件的Node进行调度,如果没有,也可以调度到不满足条件的节点上,使调度更加灵活。
Affinity主要分为三类:
nodeAffinity(node亲和性): 以node为目标,解决pod可以调度到哪些node的问题
podAffinity(pod亲和性) : 以pod为目标,解决pod可以和哪些已存在的pod部署在同一个拓扑域中的问题
podAntiAffinity(pod反亲和性) : 以pod为目标,解决pod不能和哪些已存在pod部署在同一个拓扑域中的问题
关于亲和性(反亲和性)使用场景的说明:
亲和性:如果两个应用频繁交互,那就有必要利用亲和性让两个应用的尽可能的靠近,这样可以减少因网络通信而带来的性能损耗。
反亲和性:当应用的采用多副本部署时,有必要采用反亲和性让各个应用实例打散分布在各个node上,这样可以提高服务的高可用性。
NodeAffinity(节点亲和性)
首先来看一下NodeAffinity的可配置项:
pod.spec.affinity.nodeAffinity requiredDuringSchedulingIgnoredDuringExecution Node节点必须满足指定的所有规则才可以,相当于硬限制(找不到会调度失败) nodeSelectorTerms 节点选择列表 matchFields 按节点字段列出的节点选择器要求列表 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持Exists(存在), DoesNotExist(不存在), In(范围), NotIn(范围取反), Gt(大于), Lt(小于) preferredDuringSchedulingIgnoredDuringExecution 优先调度到满足指定的规则的Node,相当于软限制 (倾向,找不到不会调度失败) preference 一个节点选择器项,与相应的权重相关联 matchFields 按节点字段列出的节点选择器要求列表 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持In, NotIn, Exists, DoesNotExist, Gt, Lt weight 倾向权重,在范围1-100。 |
关系符operator的使用说明:
关系符的使用说明: - matchExpressions: - key: nodeenv # 匹配存在标签的key为nodeenv的节点,只匹配key就行 operator: Exists - key: nodeenv # 匹配标签的key为nodeenv,且value是"xxx"或"yyy"的节点,key和value都要匹配 operator: In values: ["xxx","yyy"] - key: nodeenv # 匹配标签的key为nodeenv,且value大于"xxx"的节点 operator: Gt values: "xxx"
硬限制演示
接下来首先演示一下requiredDuringSchedulingIgnoredDuringExecution(硬限制) ,
创建pod-nodeaffinity-required.yaml,内容如下:
apiVersion: v1 kind: Pod metadata: name: pod-nodeaffinity-required namespace: dev spec: containers: - name: nginx image: nginx:1.17.1 affinity: #亲和性设置 nodeAffinity: #设置node亲和性 requiredDuringSchedulingIgnoredDuringExecution: # 硬限制 nodeSelectorTerms: - matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签,实际没有设置此标签,所以会匹配失败 - key: nodeenv operator: In values: ["xxx","yyy"]
软限制演示
接下来再演示一下requiredDuringSchedulingIgnoredDuringExecution(软限制) ,
创建pod-nodeaffinity-preferred.yaml,内容如下:
apiVersion: v1 kind: Pod metadata: name: pod-nodeaffinity-preferred namespace: dev spec: containers: - name: nginx image: nginx:1.17.1 affinity: #亲和性设置 nodeAffinity: #设置node亲和性 preferredDuringSchedulingIgnoredDuringExecution: # 软限制 - weight: 1 preference: matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签(当前环境没有) - key: nodeenv operator: In values: ["xxx","yyy"]
PodAffinity(Pod亲和性)
PodAffinity主要实现以运行的Pod为参照,实现让新创建的Pod跟参照pod在一个区域的功能。
首先来看一下PodAffinity的可配置项:
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
topologyKey用于指定调度时作用域,例如:
如果指定为kubernetes.io/hostname,那就是以Node节点为区分范围
如果指定为beta.kubernetes.io/os,则以Node节点的操作系统类型来区分
关于weight权重的解释:
这里weight权重的作用是,一个pod节点可以有多个软策略,每个软策略可以有不同的权重,然后根据权重由高到选择不同软策略,直到选中符合条件的节点。如果设置了多个软策略,权重价值就体现出来了。比如张三节点权重为4,先看看三节点符不符合选中条件,不符合,再看权重为3的李四节点符不符合选中条件...直到找到符合选中条件的节点。
接下来,演示下requiredDuringSchedulingIgnoredDuringExecution,
(1)首先创建一个参照Pod,pod-podaffinity-target.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上
启动Pod:
kubectl create -f pod-podaffinity-target.yaml
kubectl get pods pod-podaffinity-target -n dev -o wide --show-labels
(2)、创建pod-podaffinity-required.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同一节点上
上面配置表达的意思是:新Pod必须要与拥有标签nodeenv=xxx或者nodeenv=yyy的pod在同一Node上,显然现在没有这样pod,接下来,运行测试一下:
kubectl create -f pod-podaffinity-required.yaml
#查看pod状态,发现未运行
kubectl get pods pod-podaffinity-required -n dev
查看详细信息:
kubectl describe pods pod-podaffinity-required -n dev
接下来修改 values: ["xxx","yyy"]----->values:["pro","yyy"]
意思是:新Pod必须要与拥有标签nodeenv=xxx或者nodeenv=yyy的pod在同一Node上
kubectl delete -f pod-podaffinity-required.yaml # 修改 values: ["xxx","yyy"]----->values:["pro","yyy"] vim pod-podaffinity-required.yaml kubectl create -f pod-podaffinity-required.yaml kubectl get pods pod-podaffinity-required -n dev
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!