java系统找不到指定文件怎么解决
334
2022-09-13
Kubernetes Pod调度 Node亲和调度
Kubernetes Pod调度说明
简介
Scheduler 是 Kubernetes 的调度器,主要任务是把定义的Pod分配到集群的节点上,听起来非常简单,但要考虑需要方面的问题:
公平:如何保证每个节点都能被分配到资源资源高效利用:集群所有资源最大化被使用效率:调度性能要好,能够尽快的对大批量的Pod完成调度工作灵活:允许用户根据自己的需求控制调度的流程
Scheduler 是作为单独的服务运行的,启动之后会一直监听API Server,获取 podSpec.NodeName为空的Pod,对每个Pod都会创建一个binding,表明该Pod应该放在哪个节点上。
调度过程
调度流程:
首先过滤掉不满足条件的节点,这个过程称为predicate然后对通过的节点按照优先级的顺序,这个是priority最后从中选择优先级最高的节点。如果中间有任何一步报错,则直接返回错误信息。(对于调度过程分为两部分,一部分是预选,一部分是优选)
Predicate有一系列的算法可以使用:
PodFitsResources:节点上剩余的资源是否大于 Pod 请求的资源PodFitsHost:如果Pod指定了nodeName,检查节点名称是否和nodeName匹配PodFitsHostPort:节点上已经使用的port是否和Pod申请的port冲突PodSelectorMatches:过滤和Pod指定的 label 不匹配的节点NoDiskConflict:已经 mount 的 volume 和 Pod 指定的volume不冲突,除非他们都是只读
如果在predicate过程中没有适合的节点,Pod会一直处于Pending状态,不断重新调度,直到有节点满足条件,经过这个步骤,如果多个节点满足条件,就会进入priority过程:按照优先级大小对节点排序,优先级由一系列键值对组成,键是该优先级的名称,值是它的权重,这些优先级选项包括:
LeastRequestedPriority:通过计算CPU和Memory的使用率来决定权重,使用率越低权重越高,换句话说,这个优先级倾向于资源使用率低的节点BalanceResourceAllocation:节点上CPU和Memory使用率非常及接近,权重就越高,这个要和上边的一起使用,不可单独使用ImageLocalityPriority:倾向于已经要使用镜像的节点,镜像的总大小值越大,权重越高
通过算法对所有的优先级项目和权重进行计算,得出最终的结果
自定义调度器
除了Kubernetes自带的调度器,也可以编写自己的调度器,通过spec.schedulername参数指定调度器的名字,可以为Pod选择某个调度器进行调度,比如下边的Pod选择my-scheduler进行调度,而不是默认的default-scheduler。
apiVersion: v1kind: Podmetadata: name: scheduler-test labels: name: example-schedulerspec: schedulername: my-scheduler containers: - name: Pod-test image: nginx:v1
如何满足 Pod 与 Node 关系调度
Pod 与 Node 的关系调度又称之为 Node 亲和调度,主要给大家介绍两类使用方法。
NodeSelector
第一类是 NodeSelector,这是一类相对比较简单的玩法。比如说有个场景:必须要调度 Pod 到带了 k1: v1 标签的 Node 上,这时可以在 Pod 的 spec 中填写一个 nodeSelector 要求。
nodeSelector 其实是一个 map 结构,里面可以直接写上对 node 标签的要求,比如 k1: v1。这样我的 Pod 就会强制调度到带了 k1: v1 标签的 Node 上。
NodeAffinity
NodeSelector 是一个非常简单的玩法,但这个玩法有个问题:它是一个常规性调度,假如我想优先调度,就没法用 nodeSelector 来做。于是 Kubernetes 社区又新加了一个玩法,叫做 NodeAffinity。
它和 PodAffinity 有点类似,也提供了两类调度的策略:
第一类是 required,必须调度到某一类 Node 上;第二类是 preferred,就是优先调度到某一类 Node 上。
它的基本语法和上文中的 PodAffinity 以及 PodAntiAffinity 也是类似的。在 Operator 上,NodeAffinity 提供了比 PodAffinity 更丰富的 Operator 内容。增加了 Gt 和 Lt,数值比较的玩法。当使用 Gt 的时候,values 只能填写数字。
调度亲和性 节点(Node)亲和性
之前的nodeselector只能是等于某个标签,同时如果标签不匹配就会处于pending状态,这就需要软性的条件,上面是两块都加上了意味着pod只能放置在标签具有gpu的节点上,并且值为nvdlia-tesla,另外更加倾向于标签group的节点
这里的权重值代表更加期望。
pod.spec.affinity.nodeAffinity
preferredDuringSchedulingIgnoredDuringExecution:软策略
软策略是偏向于,更想落在某个节点上,但如果实在没有,落在其他节点也可以
requiredDuringSchedulingIgnoredDuringExecution:硬策略
硬策略是必须落在指定的节点上,如果不符合条件,则一直处于Pending状态
如果你还不太理解打个比方:
今天要分班了,我更加倾向于去张三老师的班级。这就是所谓的亲和性。如果我是Pod,张三老师所在的班级为Node,这就是所谓的节点亲和性。一种是必须要去张三老师带的班级(硬状态),还有一种是想去张三老师的班级但是不是必须的(软状态)。这就是一个软和硬的状态。软策略是想去,但是不去也可以,硬策略是非去不可。
requiredDuringSchedulingIgnoredDuringExecution硬策略
[root@k8s-master ~]# cat node-affinity-required.yaml apiVersion: v1kind: Podmetadata: name: affinity labels: app: node-affinity-podspec: containers: - name: with-node-affinity image: nginx imagePullPolicy: IfNotPresent affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname #键为节点名称 operator: NotIn #不是 values: - k8s-master #node节点名称 - key: kubernetes.io/hostname #键为节点名称 operator: NotIn #不是 values: - k8s-node1 #node节点名称[root@k8s-master ~]# kubectl apply -f node-affinity-required.yaml pod/affinity created、 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: #硬亲和 nodeSelectorTerms: - matchExpressions: - key: gpu operator: Exists
以上策略表示:此Pod不要落在node名称为k8s-master和k8s-node1的节点上。
可以看到每个节点上都有一个kubernetes.io/hostname=xxxx,这里就是典型的标签的键值和键值
[root@k8s-master ~]# kubectl get node --show-labelsNAME STATUS ROLES AGE VERSION LABELSk8s-master Ready
[root@k8s-master ~]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESaffinity 1/1 Running 0 3m46s 10.244.2.6 k8s-node2
可以看到这就是节点的硬策略,硬亲和性。
将yaml文件中,NotIn改为In
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8s-node3[root@k8s-master ~]# kubectl apply -f node-affinity-required.yaml pod/affinity created[root@k8s-master ~]# kubectl get podNAME READY STATUS RESTARTS AGEaffinity 0/1 Pending 0 14s[root@k8s-master ~]# kubectl describe pod affinityEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling
目前只有三个节点,一个master 一个node1一个node2,策略中表示此Pod在node3这个节点上,Pod创建之后,因为并不存在node3节点,所以一直处于Pending状态(因为这是一个硬策略,如果不满足就不运行了)。
preferredDuringSchedulingIgnoredDuringExecution软策略
[root@k8s-master ~]# cat node-affinity-preferred.yaml apiVersion: v1kind: Podmetadata: name: affinity-preferred labels: app: node-affinity-podspec: containers: - name: with-node-preferred image: nginx imagePullPolicy: IfNotPresent affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 #权重为100,软策略中权重越高匹配到的机会越大 preference: #更偏向于 matchExpressions: - key: kubernetes.io/hostname #node名称 operator: In #等于,为 values: - k8s-node1 #node真实名称[root@k8s-master ~]# kubectl apply -f node-affinity-preferred.yaml pod/affinity-preferred created affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: #软亲和 - weight: 60 preference: matchExpressions: #带gpu标签的加60权重 - key: gpu operator: Exists - weight: 30 preference: matchExpressions: #包含foo、bar标签的加30权重 - key: region operator: In values: ["foo","bar"]
- weight: 100这里给了权重,如果这里有多个软策略的话,软策略1和小红坐一起,那么这个权重为4 。策略2想和小丽做一起的权重为1。当有小红的情况下和小红坐一起的权重更高,所以选择小红,权重更大更加亲和,如果小红不在那么就选择小丽。
以上策略表示:此Pod更想落在node节点名称为k8s-node1的node中。
[root@k8s-master ~]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESaffinity-preferred 1/1 Running 0 55s 10.244.1.6 k8s-node1
以上正常落在node1节点下。
更改一下策略,将node节点名称随便更改为不存在的node名称,例如k8s-node3
affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8s-node3[root@k8s-master ~]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESaffinity-preferred 1/1 Running 0 4m25s 10.244.0.17 k8s-master
创建后,虽然它更想落在node3节点上,但因为没有这个节点,只好落在master节点中(软就是有我就去,没有也行,硬就是必须要有,没有就不去了)。
软硬策略合体
软硬可以在一起使用,先要满足硬策略以后才能去满足软策略。
apiVersion: v1kind: Podmetadata: name: affinity-node labels: app: node-affinity-podspec: containers: - name: with-affinity-node image: nginx:v1 imagePullPulicy: IfNotPresent affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: NotIn values: - k8s-node2 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: source operator: In values: - hello
软硬结合达到一个更为准确的node选择,以上文件意思为此Pod必须不存在k8s-node2节点中,其他的节点都可以,但最好落在label中source的值为hello的节点。
键值运算关系
In:label 的值在某个列表里NotIn:label 的值不在某个列表中Gt:label 的值大于某个值Lt:label 的值小于某个值Exists:某个 label 存在DoesNotExist:某个 label 不存在
如果nodeSelectorTerms下面有多个选项,满足任何一个条件就可以了;如果matchExpressions有多个选项,则必须满足这些条件才能正常调度软策略和硬策略的方法基本类似,只是添加了权重,表示更喜欢而已,也可以接受其他,在此就不再演示
亲和性/反亲和性调度策略比较如下:
调度策略 | 匹配标签 | 操作符 | 拓扑域支持 | 调度目标 |
nodeAffinity | 主机 | In,NotIn,Exists,DoesNotExists,Gt,Lt | 否 | 指定主机 |
podAffinity | Pod | In,NotIn,Exists,DoesNotExists,Gt,Lt | 是 | pod与指定pod在一拓扑域 |
podAnitAffinity | Pod | In,NotIn,Exists,DoesNotExists,Gt,Lt | 是 | pod与指定pod不在一拓扑域 |
[root@master ~]# kubectl label node node1 node-role.kubernetes.io/pg=node/node1 labeled[root@master ~]# kubectl get node NAME STATUS ROLES AGE VERSIONmaster Ready master 60d v1.19.8node1 Ready pg,worker 60d v1.19.8node2 Ready worker 60d v1.19.8[root@master ~]# kubectl label node node1 node-role.kubernetes.io/worker= node-role.kubernetes.io/worker=error: 'node-role.kubernetes.io/worker' already has a value (), and --overwrite is false
设置节点亲和性,先打标签
[root@bots-hrx-ksm1 kubectl]# kubectl get nodeNAME STATUS ROLES AGE VERSIONbots-hrx-ksw14 Ready pg,worker 15h v1.19.8bots-hrx-ksw15 Ready pg,worker 15h v1.19.8bots-hrx-ksw16 Ready pg,worker 15h v1.19.8node-role.kubernetes.io/pgnode-role.kubernetes.io/worker
最后调整将所有组件放在一起
spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/pg operator: In values: - '' tolerations: - key: node-role.kubernetes.io/pg operator: Exists
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~