系列目录

部署pod时,大多数情况下kubernetes的调度程序能将pod调度到集群中合适的节点上。但有些情况下用户需要对pod调度到哪个节点上施加更多控制,比如将特定pod部署到拥有SSD存储节点、将同一个服务的多个后端部署在不同的机器上提高安全性、将通信频繁的服务部署在同一个可用区域降低通信链路长度。用户对pod部署的节点施加控制都与"label selector"有关。

nodeSelector(节点选择器)

nodeSelector也是标签选择器,是最简单、最直接控制pod部署node的方法,在daemonset用nodeSelector过滤可部署节点,以下是其普通的应用示例。

步骤1:为节点添加标签

  • kubectl get nodes,返回集群中所有node。

  • kubectl node label =,为node选定的node添加标签。如kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd

  • 为pod configuration添加节点选择器:

apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd

当运行kubectl create -f https://k8s.io/examples/pods/pod-nginx.yaml命令创建pod时,节点选择器选中有上述节点,如果没有符合条件的node则调度失败,为pod输出调度失败事件并指明失败原因。pod一直处于pending状态,直到找到合适的节点。

运行kubectl get pods -o wide查看调度程序为pod选定的节点。

Interlude: built-in node labels(插曲:内置节点标签)

上例中使用用户自定义标签,也可以使用系统自动生成的内置节点标签。不同kubernetes版本、不同的基础设备供应商,默认添加的内置节点标签可能不同,需查询相关文档确认,以下是kubernetes1.4的内置节点标签:

  • kubernetes.io/hostname
  • failure-domain.beta.kubernetes.io/zone
  • failure-domain.beta.kubernetes.io/region
  • beta.kubernetes.io/instance-type
  • beta.kubernetes.io/os
  • beta.kubernetes.io/arch

亲和与反亲和(Affinity and anti-affinity)

nodeSelector只能基于节点标签控制pod部署node,并且选择器只支持“与”逻辑操作。亲和与反亲和特性目前处于测试阶段,相比于节点选择器,其更灵活,功能更强大,体现在以下三点:

  1. 不仅仅是“与”,支持更多的逻辑表达式。

  2. nodeSelector是硬性要求,亲和与反亲和支持软硬两种要求。

  3. 除了节点标签,亲和与反亲和支持根据节点上已经部署的pod进行节点选择,这一点很重要。比如不想将两种计算密集类型的pod部署在同一节点上,后部署pod可选择过滤。

细分成两种类型的选择器:"节点亲和"与"内部pod亲和、反亲和"。节点亲和与nodeSelector相似,具备上述1、2两条优点。内部pod亲和依赖的是节点上已有pod的标签而不是节点标签,兼俱上述三个优点。因为节点亲和能完成nodeSelector所工作并且具备额外的优点,因此nodeSelector虽然还能用,但已经不再维护,并且将来可能删除。

节点亲和(测试特性)

节点亲和与nodeSelector工作原理相同,都是其于node标签选择节点。有两点不同,第一是节点亲和支持软硬两种节点选择requiredDuringSchedulingIgnoredDuringExecution、preferredDuringSchedulingIgnoredDuringExecution。前者是硬性条件必需满足,后者是软性条件,属于偏好部署。第二点是在选择节点时,节点亲和比nodeSelector支持更多更灵活的表达式,示例如下:

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

符合条件的节点必需满足requiredDuringSchedulingIgnoredDuringExecution的条件,在此基础上,如果有节点满足

preferredDuringSchedulingIgnoredDuringExecution的条件,则更倾向部署在后者上。查询表达式中可以使用的操作符有:

In, NotIn, Exists, DoesNotExist, Gt, Lt等。

在requiredDuringSchedulingIgnoredDuringExecution中的matchExpressions可以包含多条选择表达式,相互之间是"逻辑与"的关系,必需同时满足。preferredDuringSchedulingIgnoredDuringExecution中的matchExpressions也可以有多条,因为它是软性条件,因为并非一定要全匹配,匹配的条目越多越符合条件。另外还可以为偏好中的表达式赋予不同的权重weight,可取的值在0-100之间,最后通过计算权重和决定那个节点更符合条件。

如果同时使用了nodeSelector与nodeAffinity,那么目标节点必需同时满足这两个选择器。

内部pod亲和与反亲和(测试特性)

内部pod亲和与反亲和特性由kubernetes1.4版本初次引入,其基于节点上已部署pod的标签计算亲和与反亲和,如实现将两种通信频繁pod部署在相同节点,将两种计算密集型pod部署在不同节点等。

提示:实现内部亲和与反亲和需要数量可观的计算步骤,会明显降低pod调度的速度,集群规模越大、节点越多降速越明显,呈指数级增长,需要在使用此特性时考虑对调度速度的影响。

在配置时,内部pod亲和用podAffinity字段表示,内部pod反亲和用podAntiAffinity字段表示,其它与节点亲和一样,也有软硬两种选择器,每种选择器可以多个过滤条件。

内部pod亲和示例:

apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: failure-domain.beta.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: kubernetes.io/hostname
containers:
- name: with-pod-affinity
image: k8s.gcr.io/pause:2.0

上例中的topologyKey用来缩小节点选择范围,其值可以是任何合法的节点标签,在大规模集群中,为此字段不指定或者指定错误值,可能引发巨大的性能、安全问题。因此,对其使用有如下限制:

  • 对于亲和与硬性反亲和,topologyKey字段值不能为空。

  • 对于硬性反亲和,topoloygKey只能是kubernetes.io/hostname,除非禁止LimitPodHardAntiAffinityTopology允入控制器或者修改其实现。

  • 对于软件反亲和,允许topoloygKey为空,表示对节点拓扑没有限制。

  • 以上情况外,topologyKey可以是任何合法标签。

示例1:用反亲和特性实现pod位置协商

假设集群有五个工作节点,部署一个web应用,假设其用redis作内存缓存,共需要三个副本,通过反亲和将三个redis副本分别部署在三个不同的节点上,提高可用性,Deployment配置如下:

apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-cache
spec:
selector:
matchLabels:
app: store
replicas: 3
template:
metadata:
labels:
app: store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: redis-server
image: redis:3.2-alpine

反亲和会阻止同相的redis副本部署在同一节点上。

现在部署三个nginx web前端,要求三个副本不对分别部署在不同的节点上,通过与上列相似的反亲和实现。同时需要将三个web前端部署在其上已经部署redis的节点上,降低通信成本,通过亲和实现,配置如下:

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

参考

Kubernetes调度之亲和与反亲和的更多相关文章

  1. Centos7中kubernetes-1.11.2基于配置亲和与反亲和

    1.题目 通过命令行,创建两个个deployment. – 需要集群中有2个节点 – 第1个deployment名称为<hwcka-002-app1>,使用nginx镜像,用有2个pod, ...

  2. Kubernetes中的亲和性与反亲和性

    通常情况下,Pod分配到哪些Node是不需要管理员操心的,这个过程会由scheduler自动实现.但有时,我们需要指定一些调度的限制,例如某些应用应该跑在具有SSD存储的节点上,有些应用应该跑在同一个 ...

  3. kubernetes调度之pod优先级和资源抢占

    系列目录 Pod可以拥有优先级.优先意味着相对于其它pod某个pod更为重要.如果重要的pod不能被调度,则kubernetes调度器会优先于(驱离)低优先级的pod来让处于pending状态的高优先 ...

  4. 从零开始入门 K8s | Kubernetes 调度和资源管理

    作者 | 子誉  蚂蚁金服高级技术专家 关注"阿里巴巴云原生"公众号,回复关键词"入门",即可下载从零入门 K8s 系列文章 PPT. Kubernetes 调 ...

  5. 第18 章 : Kubernetes 调度和资源管理

    Kubernetes 调度和资源管理 这节课主要讲三部分的内容: Kubernetes 的调度过程: Kubernetes 的基础调度能力(资源调度.关系调度): Kubernetes 高级调度能力( ...

  6. kubernetes 调度

    pod 分配给特定的node节点 目的:在一般业务场景,有些pod需要运行在特定的物理节点上,可以通过kubernetes的nodeSelector.nodeName安排pod到指定的节点上运行. # ...

  7. kubernetes 调度器

    调度器 kube-scheduler 是 kubernetes 的核心组件之一,主要负责整个集群资源的调度功能,根据特定的调度算法和策略,将 Pod 调度到最优的工作节点上面去,从而更加合理.更加充分 ...

  8. kubernetes调度之污点(taint)和容忍(toleration)

    系列目录 节点亲和性(affinity),是节点的一种属性,让符合条件的pod亲附于它(倾向于或者硬性要求).污点是一种相反的行为,它会使pod抗拒此节点(即pod调度的时候不被调度到此节点) 污点和 ...

  9. 图解kubernetes调度器ScheduleAlgorithm核心实现学习框架设计

    ScheduleAlgorithm是一个接口负责为pod选择一个合适的node节点,本节主要解析如何实现一个可扩展.可配置的通用算法框架来实现通用调度,如何进行算法的统一注册和构建,如何进行metad ...

随机推荐

  1. 【bzoj4184】shallot 线段树+高斯消元动态维护线性基

    题目描述 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且 让小葱从自己手中的小 ...

  2. POJ3671 Dining Cows

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8126   Accepted: 3441 Description The c ...

  3. 应用gulp工具构建个自动算rem布局的小例子

    因为最近可能需要做移动端rem布局,因为rem布局需要将px转化成rem,如果次都需要拿计算器算就太low了,所以就想到用less和gulp. 因为也是初学gulp,站点的文件结构还没想到太好,也只是 ...

  4. css3 背景图动画一

    一 实现背景图循环播放 @keyframes mlfly { 0%{ background-position:0 0; } 100%{ background-position:210px 0; } } ...

  5. spring的自动装配Bean与自动检测Bean

    spring可以通过编写XML来配置Bean,也可以通过使用spring的注解来装配Bean. 1.自动装配与自动检测: 自动装配:让spring自动识别如何装配bean的依赖关系,减少对<pr ...

  6. Feign详细使用-Spring Cloud学习第四天(非原创)

    文章大纲 一.Feign是什么二.Feign的基本实现三.Feign的继承特性四.Feign配置详解五.项目源码与参考资料下载六.参考文章   一.Feign是什么 前面几篇文章我们详细的介绍了Rib ...

  7. Deep learning with PyTorch: A 60 minute blitz _note(1) Tensors

    Tensors 1. construst matrix 2. addition 3. slice from __future__ import print_function import torch ...

  8. javascript 对象初探 (四)--- 内建对象之旅之Boolean

    var a = new Boolean() 我们要明白一点在这里的b是一个对象而不是一个基本数据类型的布尔值.如果想将b转化成基本数据类型的布尔值,我们可以调用她的valueof()方法(继承自Obj ...

  9. 【CSS】使用CSS控制文字过多自动省略号

    使用CSS可以设置一下样式: <style> u,small{ overflow: hidden; text-overflow: ellipsis; display: -webkit-bo ...

  10. cocos2d-x step by step(1) First Blood

    下了cocos2d-x 源码,开搞! 首先,笔者本身 1)      5年没有摸过c++了 2)     没用过cocos2d-x 3)      有强烈的求知欲望(这条每个简历个人介绍不都这么写么, ...