首页 > 其他分享 >pod调度:节点选择与亲和

pod调度:节点选择与亲和

时间:2023-05-22 19:35:40浏览次数:32  
标签:schedule 标签 调度 vmroot pod root 节点

0、简介
k8s对于pod的调度有如下几种:按node名称、按标签、节点亲和、pod亲和

1、使用nodeName指定节点
场景:
pod需要部署到指定节点。
方案:

[root@vmroot schedule-yamls]# cat schedule-deloyment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: scdl-d
spec:
selector:
matchLabels:
app: scdl-d
replicas: 3
template:
metadata:
labels:
app: scdl-d
spec:
nodeName: cloudk8sn1 #通过节点名称指定pod目标节点
containers:
- name: scdl-d
image: alpine:latest
command: ['sh', '-c', 'sleep 3600']
restartPolicy: Always
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
全部pod都已调度到指定节点


2、标签选择
与直接选择节点相比,标签名称更有意义,且标签选择类似群组的功能,可以对多个节点打相同标签,集群节点变更时方便修改,不需要修改pod的yaml。
场景:
节点cloudk8sn1是ssd硬盘,其它节点是机械硬盘
要求:应用调度到ssd节点上
方案:

[root@vmroot schedule-yamls]# kubectl label node cloudk8sn1 disktype=ssd #添加标签
[root@vmroot schedule-yamls]# kubectl label node cloudk8sn1 disktype- #移除标签
1
2


部署pod,选择含disktype=ssd标签的节点。

[root@vmroot schedule-yamls]# cat schedule-deloyment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: scdl-d
spec:
selector:
matchLabels:
app: scdl-d
replicas: 3
template:
metadata:
labels:
app: scdl-d
spec:
nodeSelector:
disktype: ssd #这里指定标签名称
containers:
- name: scdl-d
image: alpine:v1
command: ['sh', '-c', 'sleep 3600']
restartPolicy: Always
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
全部pod部署到了含disktype=ssd的节点上,如果有新ssd节点加入集群,只需为新节点打上disktype=ssd标签,不需要改yaml文件


3、亲和与反亲和
相对于节点标签选择,有以下优点:
● 支持多种匹配表达式,不只是全名称精确匹配
● 支持required必须满足和preferred倾向满足,不只是必须满足
● 匹配对象除了node标签还支持pod标签
● 分为亲和与反亲和

1–node亲和
属于节点标签选择的升级版,功能依旧是pod对打了标签node的一种选择决策
亲和性限制方式有以下两种:
①requiredDuringSchedulingIgnoredDuringExecution:必须满足(也叫硬亲和),效果与节点标签选择一样,pod不会调度到不满足条件的节点。且必须与nodeSelector同时满足
②preferredDuringSchedulingIgnoredDuringExecution:更倾向满足(也叫软亲和),pod如果没得选也会被调度到不满足条件的节点上(IgnoredDuringException表示忽略pod运行期间node标签变化导致亲和性不满足)

场景:
节点cloudk8sn1和cloudk8sn2都是固态硬盘,vmroot是机械硬盘,cloudk8sn2是ddr4的内存
要求1:应用必须部署到ssd硬盘的节点上(必须满足requiredDuringSchedulingIgnoredDuringExecution)
要求2:应用尽量部署到ddr4的节点上(倾向满足preferredDuringSchedulingIgnoredDuringExecution)
方案:

①为节点打标签
[root@vmroot schedule-yamls]# kubectl label nodes cloudk8sn1 disktype=ssd
[root@vmroot schedule-yamls]# kubectl label nodes cloudk8sn2 disktype=ssd
[root@vmroot schedule-yamls]# kubectl label nodes cloudk8sn2 memtype=ddr4
1
2
3
查看标签


②配置亲和性
[root@vmroot schedule-yamls]# cat schedule-deloyment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: scdl-d
spec:
selector:
matchLabels:
app: scdl-d
replicas: 10
template:
metadata:
labels:
app: scdl-d
spec:
affinity: #从里开始写亲和
nodeAffinity: #节点亲和(根据实际情况也可以配置反亲和)
requiredDuringSchedulingIgnoredDuringExecution: #必须满足的亲和
nodeSelectorTerms: #可以写多个nodeSelectorTerms,其中一个满足即可
- matchExpressions: #可以写多个matchExpressions,但必须全满足才行
- key: disktype #标签的key
operator: In #匹配方式,还有NotIn、Exists、DoesNotExist、Gt 和 Lt 可选
values:
- ssd #标签的value,可以匹配多个
preferredDuringSchedulingIgnoredDuringExecution: #倾向的亲和
- weight: 1 #取值范围1-100,当有多个倾向条件时按优先级匹配
preference:
matchExpressions:
- key: memtype
operator: In
values:
- ddr4
containers:
- name: scdl-d
image: alpine:v1
command: ['sh', '-c', 'sleep 3600']
restartPolicy: Always
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
如果你同时指定了 nodeSelector 和 nodeAffinity,两者 必须都要满足, 才能将 Pod 调度到候选节点上。
如果你指定了多个与 nodeAffinity 类型关联的 nodeSelectorTerms, 只要其中一个 nodeSelectorTerms 满足的话,Pod 就可以被调度到节点上。
如果你指定了多个与同一 nodeSelectorTerms 关联的 matchExpressions, 则只有当所有 matchExpressions 都满足时 Pod 才可以被调度到节点上。

可以看到,由于节点软亲和的存在,更多的pod调度到了cloudk8sn2节点

 

2–pod亲和
属于node亲和的升级版,不再是pod选择含标签的node,而是选择含标签pod所在的node,比较损耗性能,用于pod对pod的约束
名称分别是podAffinity 和 podAntiAffinity,其它和node亲和一样

①场景1:
有个项目名为zyz,由前端web和后端java两个服务组成,客户位于香港。当前集群节点vmroot 和cloudk8sn1 在香港,cloudk8sn2在哈尔滨
要求1:项目必须部署到位于香港的节点vmroot或cloudk8sn1(node硬亲和或节点标签选择)
要求2:后端必须调度到有前端的节点,减少通讯损耗(pod硬亲和)
要求3:后端尽量不要调度到cloudk8sn1,因为该节点运行着一个大型的应用(pod软反亲和)
场景模拟:
为节点打标签

[root@vmroot schedule-yamls]# kubectl label nodes vmroot zone=hongkong
[root@vmroot schedule-yamls]# kubectl label nodes cloudk8sn1 zone=hongkong
[root@vmroot schedule-yamls]# kubectl taint node vmroot node-role.kubernetes.io/master- #去除master污点
1
2
3
在cloudk8sn1节点部署一个含property=large标签的pod

方案:
1)写前端yaml,没用到亲和

[root@vmroot schedule-yamls]# cat zyz-web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: zyz-web
spec:
selector:
matchLabels:
appname: zyz-web
replicas: 2
template:
metadata:
labels:
appname: zyz-web #定义标签
spec:
nodeSelector:
zone: hongkong #节点标签选择
containers:
- name: zyz-web
image: alpine:v1
command: ['sh', '-c', 'sleep 3600']
restartPolicy: Always
[root@vmroot schedule-yamls]# kubectl apply -f zyz-web.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2)写后端yaml

[root@vmroot schedule-yamls]# cat zyz-java.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: zyz-java
spec:
selector:
matchLabels:
appname: zyz-java
replicas: 3
template:
metadata:
labels:
appname: zyz-java
spec:
affinity: #从里开始写亲和
podAffinity: #pod亲和
requiredDuringSchedulingIgnoredDuringExecution: #必须调度到含appname=zyz-web标签的pod的节点上(pod的标签)
- labelSelector:
matchExpressions:
- key: appname
operator: In
values:
- zyz-web
topologyKey: zone #topologyKey字段表示:被调度的节点必须含有key为zone的标签(node的标签)
podAntiAffinity: #pod反亲和
preferredDuringSchedulingIgnoredDuringExecution: #尽量不要调度到含有property=large标签的pod的节点上(pod标签)
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: property
operator: In
values:
- large
topologyKey: kubernetes.io/hostname #这个字段必须写,没什么写的就写hostname,因为每个节点都有hostname这个标签
containers:
- name: zyz-java
image: alpine:v1
command: ['sh', '-c', 'sleep 3600']
restartPolicy: Always
[root@vmroot schedule-yamls]# kubectl apply -f zyz-java.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
效果为:尽量调度到vmroot节点;绝不调度到couldk8sn2节点
注意:不能两个pod写相互硬亲和,这样pod都是pending状态

*对于topologyKey字段,经测试只要求节点含有指定的key,value可以为任意。官网示例的解释为“调度器必须将 Pod 调度到具有 topology.kubernetes.io/zone=V 标签的节点上”

②场景2:
对于场景①,可以把property=large这个标签打给cloudk8sn1然后用节点亲和,就不需要使用pod反亲和。接下来这个场景很好的体现了pod反亲和的用途
要求:
多个nginx部署到固态硬盘的节点上且尽量分散,达到高可用的效果
准备:
清除之前的环境(略),现在vmroot和cloudk8sn2有disk=ssd的标签
方案:

[root@vmroot schedule-yamls]# cat nginxha.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginxha
spec:
selector:
matchLabels:
appname: nginxha
replicas: 3
template:
metadata:
labels:
appname: nginxha
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disk #必须部署到ssd的node
operator: In
values:
- ssd
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: appname
operator: In
values:
- nginxha #用自己的label做pod反亲和,互相排斥,达到分散目的
topologyKey: kubernetes.io/hostname
containers:
- name: nginxha
image: alpine:v1
command: ['sh', '-c', 'sleep 3600']
restartPolicy: Always
[root@vmroot schedule-yamls]# kubectl apply -f nginxha.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41


pod尽量在分散部署,且不会部署到cloudk8sn1,如果节点多效果更清晰

4、参考:
https://www.jianshu.com/p/61725f179223
https://zhuanlan.zhihu.com/p/405150555
https://kubernetes.io/zh/docs/concepts/scheduling-eviction/assign-pod-node/
————————————————
版权声明:本文为CSDN博主「雪碧能喝多」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/seven_xu_/article/details/125268566

标签:schedule,标签,调度,vmroot,pod,root,节点
From: https://www.cnblogs.com/gaoyanbing/p/17421517.html

相关文章

  • 力扣---1080. 根到叶路径上的不足节点
    给你二叉树的根节点root和一个整数limit,请你同时删除树中所有不足节点,并返回最终二叉树的根节点。假如通过节点node的每种可能的“根-叶”路径上值的总和全都小于给定的limit,则该节点被称之为不足节点,需要被删除。叶子节点,就是没有子节点的节点。 示例1:输入:r......
  • 火山引擎DataLeap数据调度实例的 DAG 优化方案(三):技术实现
    在原始数据中,是以一个数组的形式返回节点信息及依赖关系。所以,需要对数据进行处理形成图所需要的数据,同时,利用多个map对数据进行存储,方便后续对数据进行检索,减少时间复杂度。实例节点的样式需要通过基础图形Text(文本)、Rect(矩形)、Icon(图标)进行组合,以达到我们的设计要求。......
  • 使用podman-compose快速部署应用
    我们对于docker-compose并不陌生,它是一个用于编排多个可能相互依赖的容器的工具。而PodmanCompose项目的目标是作为docker-ompose的替代品,而不需要对docker-compose.yaml文件进行任何修改。要想使用podman-compose需要先安装podman,然后安装podman-compose。Rocky8下安装po......
  • Kubernetes 初始化容器及静态Pod和Pod调度策略
    初始化容器kubernetes1.3版本引入了initcontainer初始化容器特性。主要用于在启动应用容器(appcontainer)前来启动一个或多个初始化容器,作为应用容器的一个基础。#查看要修改的内核参数[root@kmaster~]#sysctl-a|grepvm.overcommit_ratiovm.overcommit_ratio=50#输......
  • DolohinScheduler 分布式任务调度框架 代码流程分解
    一、DS-API模块-执行工作流 -定时任务执行 更新schedule参数 -/schedule新增schedule参数做了什么事? 将schedule参数用ScheduleParam类进行解析 有效性校验,而后解析保存到t_ds_schedules表内,更新t_ds_process_definition表 -/onlin......
  • pod 插件报错: LoadError - cannot load such file -- cocoapods/command/gen
    报错信息:LoadError-cannotloadsuchfile–cocoapods/command/gen解决方法:geminstallcocoapods-generate......
  • 节点流和处理流二
    1. 节点流和处理流接上 2. 处理流BufferedInputStream 和 BufferedOutputStream2.1 介绍BufferedInputStream   626BufferedInputStream是字节流在创建BufferedInputStream会创建一个内部缓冲区数组.2.2 介绍BufferedOutputStream  626BufferedOutputStream是字节流,实......
  • 使用 Async Rust 构建简单的 P2P 节点
    使用AsyncRust构建简单的P2P节点P2P简介P2P:peer-to-peerP2P是一种网络技术,可以在不同的计算机之间共享各种计算资源,如CPU、网络带宽和存储。P2P是当今用户在线共享文件(如音乐、图像和其他数字媒体)的一种非常常用的方法。Bittorrent和Gnutella是流行的文件共享......
  • 使用 Elasticsearch 的 REST API 来查询节点的内存使用情况
    curl-XGET'http://172.18.10.96:9200/_nodes/node-1/stats?pretty&human&filter_path=nodes.*.jvm.mem.heap_used_percent'{"nodes":{"WKECtNqYSuCKgHu-HNJTfg":{"jvm":{"mem":......
  • Linux进程调度-组调度及带宽控制
    1.概述组调度(task_group)是使用Linuxcgroup(controlgroup)的cpu子系统来实现的,可以将进程进行分组,按组来分配CPU资源等。比如,看一个实际的例子:A和B两个用户使用同一台机器,A用户16个进程,B用户2个进程,如果按照进程的个数来分配CPU资源,显然A用户会占据大量的CPU时间,这对于B用户......