admin管理员组文章数量:1611903
1. Scheduling
- 为Pod找到一个合适的Node
2. Node定义
kubectl get node node-slave -o yaml > node-slave.yaml
apiVersion: v1
kind: Node
metadata:
labels:
kubernetes.io/arch: amd64
kubernetes.io/hostname: node-slave
kubernetes.io/os: linux
name: node-slave
status:
addresses:
- address: node-slave
type: Hostname
allocatable: # node可分配的资源配额
cpu: "2"
memory: 3564872Ki
pods: "110"
capacity:
cpu: "2"
memory: 3667272Ki
pods: "110"
conditions: {...}
daemonEndpoints:
kubeletEndpoint:
Port: 10250
images: : {...}
nodeInfo:
architecture: amd64
operatingSystem: linux
osImage: CentOS Linux 8
2.1. 调度资源配额
- capacity: node资源配额的系统能力
- allocatable: node可分配的资源配额--给业务用
2.2. Node资源的盒子模型
- 实际生产中,capacity 和 allocatable 这两个值有差异,要留出资源给系统和K8S使用,不能都分配给node
- 可以设置门槛,什么时候可以触发硬驱逐pod,保证k8s系统能正常运行
3. Pod定义
3.1. 查看pod完整的配置字段
kubectl explain pod.spec
3.2. 查看pod定义
kubectl get pod my-pod-1 -o yaml > my-pod-1.yaml
- spec
- 期望
- k8s调度后的结果
- pod的状态merge不需要关心,交给调度器
- 容器
- containers
- 1个pod里可以运行多个container
- 调度资源配额
- resources
- 生产中,根据不同的微服务,也要预先指定资源配额
- 调度器
-
schedulerName
-
在多调度器的情况下会用到
-
-
调度结果
-
nodeName
-
- 高级调度策略
- 根据node的属性决定pod的调度
-
nodeSelector
-
affinity
-
tolerations
-
- 根据node的属性决定pod的调度
apiVersion: v1
kind: Pod
metadata:
labels:
app: my-pod-1
name: my-pod-1
namespace: default
spec:
containers:
image: nginx
imagePullPolicy: IfNotPresent
name: my-pod-1
ports:
- containerPort: 3500
protocol: TCP
readinessProbe: {...}
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "500m"
schedulerName: default-scheduler
nodeName: node-slave
restartPolicy: Always
nodeSelector: {...}
affinity: {...}
tolerations: {...}
status: {...}
4. K8S调度器的资源分配机制
确保node的资源可以得到最优的利用,确保pod的资源需求可以得到充分的满足。
4.1. 基于Pod中容器resources.request资源“总和”调度
- resoureces.limits 影响pod的运行资源上限,不影响调度
- initContainer
- 启动container之前,做一些预处理,处理完就退出了
- 逐一执行initContainer
- initContainer 取最大值,container 取累加值,最后取大者, 即
Max( Max(initContainers.requests), Sum(containers.requests) )
- resoureces.request 未指定时, 按0资源需求进行调度
- 适合一些离线的任务
- 或者优先级不是很高,只是想夹缝的利用node上没有被分配的资源去做一些计算
- 如果有资源就利用起来,没资源就不运行
4.2. 基于资源声明量的调度,而非实际占用
- 不依赖监控,系统不会过于敏感
- pod的资源用超了,或者没有充分利用,调度器都不会感知
- 能否调度成功:
pod.request < node.allocatable - node.requested
4.3. 资源分配相关算法
- GeneralPredicates(主要是PodFitsResources)
- 检查CPU和内存、硬盘的余量,余量不满足要求,直接排除不满足要求的node,不参与调度
- LeastRequestedPriority
- 最少被调度pod的node,优先分配给pod
- 保证每个node上的pod个数均衡
- BalancedResourceAllocation,平衡cpu/mem的消耗比例
- 比较pod所需要cpu/mem的比例,是否和node的cpu/mem比例相近,相近的优先调度
- 保证node剩余的cpu和mem被后续的pod消费
5. 高级调度
5.1. nodeSelector:将 Pod 调度到特定的 Node 上
nodeSelector
diskType: ssd
node-flavor:node-slave
- 顺序板会默认给node打上label,也可以手动打label,不能重复
- 语法格式:map [string]:[string]
- 作用:匹配node.labels
- 排除不包含nodeSelector中指定label的所有node
- 匹配机制 —— 完全匹配(上述脚本,指定了两个selector,都要满足)
5.2. nodeAffinity:nodeSelector 升级版
nodeSelector的功能还是有限制的,所以引入新的feature。与nodeSelector关键差异
- 引入运算符:In,NotIn (labelselector语法)
- 支持枚举label可能的取值
- 如让pod调度到不同zone上的node中:zone in [zone1,zong2...]
- 如让pod调度到指定node上: node in [node-master, node-slave...]
- 支持硬性过滤和软性评分
- 硬性过滤规则
- 支持指定多 matchExpressions 条件之间的逻辑或运算
- 必须满足这些条件,如果没有满足硬性过滤条件的node,就应用软性评分条件
- requiredDuringSchedulingIgnoredDuringExecution:硬性过滤,排除不具备指定label的node
- 软性评分规则
- 支持设置条件权重值。
- 优先满足这些条件,如果不满足,也要调度成功
- preferredDuringSchedulingIgnoredDuringExecution:软性评分,不具备指定label的node打低分, 降低node被选中的几率
- 硬性过滤规则
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity: # 亲和
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-flavor
operator: In
values:
- node-master
- node-salve
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: node-flavor
operator: In
values:
- node-slave
containers:
- name: with-node-affinity
image: nginx
5.3. podAffinity:让某些 Pod 分布在同一组 Node 上
与nodeAffinity的关键差异
- 定义在PodSpec中,亲和与反亲和规则具有对称性
- labelSelector的匹配对象为Pod
- 对node分组,依据label-key = topologyKey,每个labelvalue取值为一组
- topologyKey:被调度的pod是在什么级别一致(zone、node、机架),可以自定义
- 硬性过滤规则
- 条件间只有逻辑与运算
- 如果没有满足硬性过滤条件的node,就应用软性评分条件
- requiredDuringSchedulingIgnoredDuringExecution:硬性过滤,排除不具备指定pod的node组
- 软性评分
- 优先满足这些条件,如果不满足,也要调度成功
- preferredDuringSchedulingIgnoredDuringExecution:软性评分,不具备指定pod的node组打低分, 降低该组node被选中的几率
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
podAffinity: # 亲和
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: topology.kubernetes.io/zone # 同一app的pod调度到同一个zone机房
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname # 同一app的pod调度到同一个node
weight: 100
containers:
- name: nginx
image: nginx
5.4. podAntiAffinity:避免某些 Pod 分布在同一组 Node 上
与podAffinity的差异
- 匹配过程相同
- 最终处理调度结果时取反
- podAffinity中可调度节点,在podAntiAffinity中为不可调 度
- podAffinity中高分节点,在podAntiAffinity中为低分
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
podAntiAffinity: # 反亲和
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: topology.kubernetes.io/zone # 同一app的pod不调度到同一个zone机房
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname # 同一app的pod不调度到同一个node
weight: 100
containers:
- name: nginx
image: nginx
6. 手动调动Pod
6.1. 适用场景
- 调度器不工作了,临时救急
- 或者不是按照你期望的方式调度。
- 手动直接指定Node name
- 自定义调度器,将node name为空的提出来,填上
- describe pod看不到自动调度的event
6.2. DaemonSet
- 每个node上部署一个相同的pod
- 通常用来部署集群中的agent,如果网络插件
- 避免动态计算node数量和扩容操作
- DaemonSet等价于配置了node级别反亲和的deployment,副本数量要和node数量相等
apiVersion: v1
kind: Pod
metadata:
labels:
name: weave-net
name: weave-net-jhcjh
namespace: kube-system
ownerReferences:
- apiVersion: apps/v1
controller: true
kind: DaemonSet
name: weave-net
7. Taints:避免 Pod 调度到特定 Node 上
- taints 污点排斥
7.1. taints 是带effect的特殊label,对Pod有排斥性
- 硬性排斥 NoSchedule
- 软性排斥 PreferNoSchedule
7.2. 系统创建的taint附带时间戳
- effect为NoExecute:不是调度器处理的,是NodeController用kubelet处理的
- 便于触发对Pod的超时驱逐
7.3. 典型用法
- 预留特殊节点做特殊用途
apiVersion: v1
kind: Node
metadata:
labels:
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
kubernetes.io/hostname: node-master
name: node-master
spec:
externalID: node-n1
taints:
- effect: NoSchedule
key: accelerator
timeAdded: null
value: gpu
status: {...}
7.4. 允许调度到master
kubectl taint node node-master node-role.kubernetes.io/master-
7.5. 禁止调度到master
kubectl taint node node-master node-role.kubernetes.io/master="":NoSchedule
8. Tolerations:允许 Pod 调度到有特定 taints 的 Node 上
-
Tolerations 容忍污点排斥,可以保证通过taints预留出来的node,有些pod可以调度上去
8.1. 完全匹配
- 例:<key>=<value>:<effect>
- Operator为Equal
- key和value,以及effect要完全相等
8.2. 匹配任意taint effect
- 例:<key>=<value>
- effect为空
- key和value相等就行了
8.3. 匹配任意taint value
- 例:<key>:<effect>
- Operator为Exists
- value为空
- key相等就行了
8.4. 例子
- 集群有一个node配置了gpu,不希望不消耗gpu的pod调度上去,避免消耗内存
- 污点排斥
apiVersion: v1
kind: Node
metadata:
labels:
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
kubernetes.io/hostname: node-gpu
name: node-gpu
spec:
externalID: node-gpu
taints:
- effect: NoSchedule
key: accelerator
timeAdded: null
value: gpu
status: {...}
- 容忍污点:将有gpu需求的pod调度的gpu node上
apiVersion: v1
kind: Pod
metadata:
labels:
run: my-pod
name: my-pod
namespace: default
spec:
containers:
- name: my-pod
image: nginx
tolerations:
- key: accelerator
operator: Equal
value: gpu
effect: NoSchedule
9. 调度失败原因分析
9.1. 查看调度结果
kubectl get pod [podname] –o wide
9.2. 查看调度失败原因
kubectl describe pod [podname]
- 可以看到调度失败的event
9.3. 调度失败错误列表
kubernetes/error.go at release-1.9 · kubernetes/kubernetes · GitHub
10. 多调度器
10.1. 适用场景
- 集群中存在多个调度器,分别处理不同类型的作业调度
10.2. 使用限制
- 建议对node做资源池划分,避免调度结果写入冲突,不同的调度器处理不同的node资源池
10.3. 给pod手动指定schedulerName
apiVersion: v1
kind: Pod
metadata:
labels:
run: my-pod
name: my-pod
namespace: default
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: my-pod
ports:
- containerPort: 80
protocol: TCP
schedulerName: my-custom-scheduler
10.4. 自定义调度器配置
- 查看更多调度器配置项
kube-scheduler --help
- --policy-config-file
- 自定义调度器加载的算法
- 或者调整排序算法权重
- 或者关闭不需要的算法,避免不必要的消耗
{
"kind": "Policy",
"apiVersion": "v1",
"predicates": [
{ "name": "PodFitsHostPorts" },
{ "name": "PodFitsResources" },
{ "name": "NoDiskConflict" },
{ "name": "NoVolumeZoneConflict" },
{ "name": "MatchNodeSelector" },
{ "name": "HostName" }
],
"priorities": [
{ "name": "LeastRequestedPriority", "weight": 1 },
{ "name": "BalancedResourceAllocation", "weight": 1 },
{ "name": "ServiceSpreadingPriority", "weight": 1 },
{ "name": "EqualPriority", "weight": 1 }
],
"hardPodAffinitySymmetricWeight": 10,
"alwaysCheckAllPredicates": false
}
版权声明:本文标题:K8S进阶-02-调度管理 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1728622402a1166519.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论