5.6、k8s亲和性反亲和性调度策略⽐较、资源调度器和安全认证
第⼀节集群调度介绍
1.1 调度器-调度简介
Scheduler是kubernetes中的调度器组件,主要的任务是把定义的pod分配到集群的节点上。听起来⾮常简单,但有很多要考虑的问题:· 公平: 如何保证每个节点都能被分配
四级考试
· 资源资源⾼效利⽤: 集群所有资源最⼤化被使⽤
· 效率: 调度的性能要好,能够尽快地对⼤批量的pod完成调度⼯作
· 灵活: 允许⽤户根据⾃⼰的需求控制调度的逻辑
heduler是作为单独的程序运⾏的,启动之后会⼀直监听APIServer,获取PodSpec.NodeName为空的pod,对每个pod都会创建⼀个binding,表明该 pod 应该放到哪个节点上。
这⾥的PodSpec.NodeName不为空的pod,说明我们⼿动指定了这个pod应该部署在哪个node上,所以这种情况Sheduler就不需要参与进来了.
1.2 调度器-调度过程
调度过程分为两部分,如果中间任何⼀步骤有错误,直接返回错误:
· predicate(预选): ⾸先是过滤掉不满⾜条件的节点
· priority(优选): 然后从中选择优先级最⾼的节点
**Predicate(预选)**有⼀系列的算法可以使⽤:
· PodFitsResources: 节点上剩余的资源是否⼤于pod请求的资源
· Podfitshost: 如果pod指定了NodeName,检查节点名称是否和NodeName相匹配
· PodFfitsHostPorts: 节点上已经使⽤的port是否和 pod申请的port冲突
· PodSelectorMatches: 过滤掉和 pod指定的label不匹配的节点
· NoDiskConflict: 已经mount的volume和 pod指定的volume不冲突,除⾮它们都是只读
注意:如果在predicate过程中没有合适的节点。pod会⼀直在pending状态,不断重试调度,直到有节点满⾜条件。经过这个步骤,如果有多个节点满⾜条件,就继续priorities过程
**Priorities(优选)**是按照优先级⼤⼩对节点排序
优先级由⼀系列键值对组成,键是该优先级项的名称,值是它的权重(该项的重要性)。这些优先级选项包括:
· LeastRequestedPriority:通过计算CPU和 Memory的使⽤率来决定权重,使⽤率越低权重越⾼。换句话说,这个优先级指标倾向于资源使⽤⽐例更低的节点
· BalancedResourceA1location:节点上CPU和Memory 使⽤率越接近,权重越⾼。这个应该和上⾯的⼀起使⽤,不应该单独使⽤
· ImageLocalityPriority:倾向于已经有要使⽤镜像的节点,镜像总⼤⼩值越⼤,权重越⾼
通过算法对所有的优先级项⽬和权重进⾏计算,得出最终的结果。上⾯只是常见的算法,还有很多算法可以到官⽹查阅。
第⼆节调度的亲和性
2.1 节点亲和性
1. node节点亲和性: 简单来理解就是,指定调度到的node,nodeAffinity分为两种deAffinity:
· preferredDuringSchedulinglgnoredDuringExecution:软策略【我想要去这个节点】
· requiredDuringschedulinglgnoredDuringExecution:硬策略【我⼀定要去这个节点】
2. node节点亲和性硬策略⽰例:requiredDuringSchedulingIgnoredDuringExecution
· kubectl get pod -o wide
apiVersion: v1
kind:Pod metadata:
name: affinity
labels:
app:node-affinity-pod spec:
containers:
-name: with-node-affinity
image: /library/myapp:v1
affinity:
# 指定亲和性为node亲和性
nodeAffinity:
# 指定为硬策略
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
# key就是node的label
# 这句话代表当前pod⼀定不能分配到k8s-node02节点上
-matchExpressions:
-
key: kubernetes.io/hostname # 标签的键名kubectl get node --show-labels查看
operator: NotIn
values:
- k8s-node2
1. node亲和性软策略⽰例:preferredDuringSchedulingIgnoredDuringExecution。
· kubectl get pod -o wide
apiVersion: v1
kind:Pod metadata:
ruf
name: affinity
labels:
app:node-affinity-pod spec:
containers:
-name: with-node-affinity
image: /library/myapp:v1
affinity:
# 声明节点亲和性为软策略
nodeAffinity:
revision
preferredDuringSchedulingIgnoredDuringExecution:
# 当前策略权重为1
-weight:1
preference:
# [最好]能分配到label为source=k8s-node03的节点上
外交斡旋
matchExpressions:
-key: source
operator: In
values:
- k8s-node03
1. 若软策略和硬策略同时存在。要先满⾜我们的硬策略在满⾜软策略才⾏。
2. 键值运算关系
· In: label的值在某个列表中
· Notin: label 的值不在某个列表中
· Gt: label的值⼤于某个值
· Lt: label的值⼩于某个值
·
Exists:某个label存在
· DoesNotExist: 某个label不存在
2.2 Pod亲和性
3. pod亲和性主要解决pod可以和哪些pod部署在同⼀个拓扑域中的问题
4. 拓扑域: ⽤主机标签实现,可以是单个主机,或者具有同个label的多个主机,也可以是多个主机组成的 cluster、zone 等等
5. 所以简单来说: ⽐如⼀个 pod 在⼀个节点上了,那么我这个也得在这个节点,或者你这个 pod 在节点上了,那么我就不想和你待在
同⼀个节点上
6. pod亲和性/反亲和性⼜分为两种:pod.spec.affinity.podAffinity/podAntiAffinity:
· preferredDuringSchedulinglgnoredDuringExecution:软策略
· requiredDuringSchedulinglgnoredDuringExecution:硬策略
apiVersion: v1
最新世界大学排名
kind:Pod metadata:
name: pod-3
labels:
app:pod-3 spec:
containers:
-name: pod-3
image: /library/myapp:v1
affinity:
# 配置⼀条pod亲和性策略
podAffinity:
# 配置为硬策略 kubectl get pod --show-labels labels是app=pod1的pod同⼀拓扑域
qatarrequiredDuringSchedulingIgnoredDuringExecution:
-labelSelector:
matchExpressions:
-key: app
operator: In
values:
- pod-1
topologyKey: kubernetes.io/hostname
# 配置⼀条pod反亲和性策略
podAntiAffinity:
# 配置为软策略
preferredDuringSchedulingIgnoredDuringExecution:
-weight:1
podAffinityTerm:
labelSelector:
matchExpressions:
-key: app
operator: In
values:
the same to you- pod-2
topologyKey: kubernetes.io/hostname马达加斯加3插曲
亲和性/反亲和性调度策略⽐较
调度策略 匹配标签 操作符 拓扑域⽀持 调度⽬标
nodeAffinity 主机 IN, NotIn, Exists, DoesNotExist, Gt, Lt 否 指定主机
podAffinity POD IN, NotIn, Exists, DoesNotExist 是 POD与指定POD同⼀拓扑域
podAntiAffinity POD IN, NotIn, Exists, DoesNotExist 是 POD与指定POD不在同⼀拓扑域
2.3 Taint(污点)介绍
1. 节点亲和性是pod的⼀种属性(偏好或硬性要求),它使pod被吸引到⼀类特定的节点。Taint则相反,它使节点能够排斥⼀类特定的
pod。
2. Taint和toleration相互配合,可以⽤来避免pod被分配到不合适的节点上。每个节点上都可以应⽤⼀个或多个taint,这表⽰对于那些
不能容忍这些taint的pod,是不会被该节点接受的。如果将toleration 应⽤于pod上,则表⽰这些pod 可以(但不要求)被调度到具有匹配 taint 的节点上。
diehard
3. 如果没有特别配置toleration,默认是不容忍所有污点的
4. 使⽤kubectl taint 命令可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在了⼀种相斥的关系,可以让Node
拒绝Pod的调度执⾏,甚⾄将Node已经存在的Pod驱逐出去
5. 污点的value是可选项,即污点有两种组成形式:
key=value:effect
key:effect
6. 每个污点有⼀个key和value作为污点的标签,其中value可以为空,effect 描述污点的作⽤。当前taint effect⽀持如下三个选项:
· NoSchedule:表⽰k8s将不会将Pod调度到具有该污点的Node上
· PreferNoschedulel: 表⽰k8s将尽量避免将Pod调度到具有该污点的Node上
· NoExecute: 表⽰k8s将不会将Pod调度到具有该污点的Node上,同时会将Node上已经存在的Pod驱逐出去
7. kubectl describe node k8s-master 主节点上本⾝就有⼀个NoSchedule的污点,默认不在上⾯创建Pod。
# 设置污点
kubectl taint nodes node1 key1=value1:NoSchedule# 例⼦
kubectl taint nodes k8s-node1 check=qnhyn:NoExecute# 节点说明中,查找Taints字段
kubectl describe pod pod-name# 去除污点通过describe查看污点,然后把污点复制出来,按照如下格式在最后加⼀个-就好了
kubectl taint nodes node1 key1:NoSchedule-# 例⼦:
kubectl taint nodes k8s-node1 check=qnhyn:NoExecute-
2.4 Toleration(容忍)的介绍
1. 设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute 和 Pod之间产⽣互斥的关系,Pod将在⼀
定程度上不会被调度到Node上
2. 但我们可以在Pod上设置容忍(Toleration)。意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上
3. 可以被调度不代表⼀定会被调度,只是保存了可能性
4. Toleration的资源清单配置:
tolerations:# 容忍key1-value1:NoSchedule的污点
# 且需要被驱逐时,可以再呆3600秒- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
# ⽤于描述当Pod需要被驱逐时可以在 Pod上继续保留运⾏的时间
tolerationSeconds: 3600
# 容忍key1-value1:NoExecute的污点- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
# 容忍key2:NoSchedule的污点- key:"key2"
operator: "Exists"
effect: "NoSchedule"
1. 注意点
· key,value, effect要与Node上设置的 taint保持⼀致
header什么意思· operator的值为Exists将会忽略value值,如不指定operator,则默认为equal
· tolerationSeconds⽤于描述当Pod需要被驱逐时可以在 Pod上继续保留运⾏的时间
2. 当不指定key值时,表⽰容忍所有的污点key
tolerations:- operator: “Exists”
3. 当不指定effect时,表⽰容忍所有的污点作⽤
tolerations:- key: “key”
operator: “Exists”
4. 有多个Master存在时,防⽌资源浪费,可以如下设置(尽可能不在master上运⾏)
kubectl taint nodes Node-Name node-role.kubernetes.io/master=:PreferNoSchedule
2.5 指定调度节点
5. 通过指定deName将Pod直接调度到指定的Node节点上(根据节点的名称选择)
· 会跳过Scheduler的调度策略
· 该匹配规则是强制匹配
apiVersion: apps/v1
kind:Deployment metadata:
name:myweb spec:
replicas:7
lector:
matchLabels:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
# 直接指定node名称七个Pod全在k8s-node1上
nodeName: k8s-node1
containers:
-name: myweb
image: /library/myapp:v1
ports:
-containerPort:80
1. deSplector: 通过kubernetes的label-lector机制选择节点,由调度器调度策略
匹配label,⽽后调度Pod到⽬标节点,该匹配规则属于强制约束(根据标签选择)
· kubectl label node k8s-node1 disk=ssd 给节点打个标签