亲和和反亲和,包含两种类型:“节点亲和”和“pod间亲和/反亲和”
为何要做node亲和
我们在日常工作中经常会遇到要在k8s环境下维护多条产品线,甚至在微服务架构中,又有前端、中台、底层之分,如何将关联密切的服务划分到一组服务器上,保持架构的相对独立,避免交叉部署带来的管理和故障诊断难题,就用到了node亲和;所谓node亲和,就是将一些关联密切的服务分到指定的带有特殊标签的一组或一台服务器上。
为何要做pod反亲和
所谓反亲和,就是不要在一起;假如一个服务有两个pod都在同一台机器上,那么这台机器一旦故障宕机,整个服务将不可用了。所以反亲和的目的,就是将相同服务的多个副本分散到不同的主机上。
添加节点
kubectl label nodes <node-name> <label-key>=<label-value>
显示节点
kubectl get nodes --show-labels
node节点亲和
pods/pod-with-node-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: with-node-affinity
image: k8s.gcr.io/pause:2.0
此节点亲和规则表示,pod 只能放置在具有标签键为 kubernetes.io/e2e-az-name 且 标签值为 e2e-az1 或 e2e-az2 的节点上。另外,在满足这些标准的节点中,具有标签键为 another-node-label-key 且标签值为 another-node-label-value 的节点应该优先使用。
说明:
- requiredDuringSchedulingIgnoredDuringExecution,这个是必须满足
- preferredDuringSchedulingIgnoredDuringExecution,这个是优先满足,如果实在不能满足的话,则允许一些pod在其它地方运行
- In,NotIn,Exists,DoesNotExist,Gt,Lt。你可以使用 NotIn 和 DoesNotExist 来实现节点反亲和行为,或者使用节点污点将 pod 从特定节点中驱逐。
- 如果你同时指定了 nodeSelector 和 nodeAffinity,两者必须都要满足,才能将 pod 调度到候选节点上。
- 如果你指定了多个与 nodeAffinity 类型关联的 nodeSelectorTerms,则如果其中一个 nodeSelectorTerms 满足的话,pod将可以调度到节点上。
- 如果你指定了多个与 nodeSelectorTerms 关联的 matchExpressions,则只有当所有 matchExpressions 满足的话,pod 才会可以调度到节点上。
pod亲和和反亲和
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
spec:
selector:
matchLabels:
app: web-store
replicas: 3
template:
metadata:
labels:
app: web-store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-store
topologyKey: "kubernetes.io/hostname"
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: web-app
image: nginx:1.12-alpine
说明:
- yaml 代码段中配置了 podAntiAffinity(反亲和) 和 podAffinity(亲和)。这将通知调度器将它的所有副本与具有 app=store 选择器标签的 pod 放置在一起。这还确保每个 web 服务器副本不会调度到单个节点上。
- topologyKey可以设置成如下几种类型
kubernetes.io/hostname #Node
failure-domain.beta.kubernetes.io/zone #Zone
failure-domain.beta.kubernetes.io/region #Region - 可以设置node上的label的值来表示node的name,zone,region等信息,pod的规则中指定topologykey的值表示指定topology范围内的node上运行的pod满足指定规则
生产环境配置示例
node硬亲和和pod软反亲和
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: abc.com/zhongtai
operator: In
values:
- standard
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 50
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: "kubernetes.io/hostname"
网友评论