Kubernetes 调度和资源管理 | 学习笔记

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 快速学习 Kubernetes 调度和资源管理

开发者学堂课程【企业级运维之云原生与 Kubernets 实战课程:Kubernetes 调度和资源管理 】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/913/detail/14505


Kubernetes 调度和资源管理


摘要:本小节主要内容为 Pod 调度和资源管理,包括 Pod 调度过程、资源源调度和关系调度、调度相关的配置和使用、K8s 组件控制器、SVC 创建及使用、Pod 生命周期管理及 Kubectl 常用命令和使用技巧。

 

目录

Ÿ Pod 调度过程

Ÿ 资源调度和关系调度

Ÿ 调度相关的配置和使用

Ÿ 优先调度

 

一、Pod 调度过程

调度过程是把 Pod 放到合适 Node 上:

Ÿ 满足 Pod 资源要求;

Ÿ 满足 Pod 的特殊关系要求;

Ÿ 满足 Node 限制条件要求;

Ÿ 做到集群资源合理利用;

Controllers 副本集控制器 Kube-Scheduler 调度组件,按照预定的调度策略,将Pod 调度到相应的机器上,Kubelet 负责维护容器的生命周期,同时也负责 Volume 和网络的管理。

image.png

使用 kubectl 或者在控制台创建 deployment 类型 Pod,向 Apiserver 发送请求,scheduler 监控到 Pod 调度请求后,如何调度呢?

Kubernetes 的默认调度过程

Ÿ 客户端向 api-server 发出控制器 ( deployment,statefulset,job,cronjob ) 创建请求,最终会转化为创建和调度 Pod;

Ÿ kube-scheduler 通过 api-server 获取还未调度的 Pod 列表,通过对应的筛选规则和算法循环遍历为每个 Pod 分配节点,筛选分为两阶段:

ž Predicate:过滤(预选)阶段,将所有节点混在一起,通过一定算法对匹配项进行匹配,将不合格的节点剔出去,留下合格的节点,如果此时没有筛选出合适的节点,则 Pod 会进入 pending 状态,不断重试调度,直到有合适节点为止;

ž Priority:优选阶段,对刚刚通过过滤阶段筛选出来的节点,通过权重和优先级进行计算得出一个最终得分,这个分值范围为(0-10),得分高的为最合适的调度节点。

Ÿ 选举得分最高的主机 binding,结果存储 etcd;

Ÿ 最终选举节点 kubelet 接收指令进行 Pod 的创建。

 

二、资源调度和关系调度

除了集群默认调度能力外,还有自定义调度,用户可以设置 Pod 的资源限额参数、亲和性、反亲和性、污点等,实现自定义调度策略,使 Pod 能够充分利用资源并且按照业务需求合理调度。

1. Kubernetes 基础调度能力

a. 资源调度:满足 Pod 资源要求

Ÿ Resources:CPU/Memory/Storage/GPU/FGPA (资源大小限制);

Ÿ QoS:Guaranteed/Burstable/BestEffort (服务质量要求);

Ÿ Resource Quota (配额限制);

b. 关系调度:满足 Pod/Node 的特殊关系/条件要求

Ÿ PodAffinity/PodAntiAffinity:Pod 和 Pod 间关系(亲和性和反亲和性);

Ÿ NodeSelector/NodeAffinity:由 Pod 决定适合自己的 Node (节点选择器);

Ÿ Taint/Tolerations:限制调度到某些 Node (污点限制);

如果未做过节点 nodeSelector,亲和性( node affinity ) 或 Pod 亲和、反亲和性  ( Pod affinity/anti-affinity ) 等 Pod 高级调度策略设置,则没有办法指定服务部署到指定节点上,可能会造成 CPU 或内存等密集型的 Pod 同时分配到相同 Node,造成资源竞争;另一方面,如果未对资源进行限制,一些关键的服务可能会因为资源竞争因 OOM (Out of Memory) 等原因被 kill 掉,或者被限制 CPU 使用。

a. Pod 的资源类型,可以对 cpu、内存、存储、gpu 资源的使用量进行限制

Ÿ Cpu

Ÿ Memory

Ÿ ephemeral-storage

Ÿ extended-resource:nvidia.com/gpu

b. 在应用的 container 标签下面增加 resource 标签,即可对 Pod 资源的使用量进行限制;

示例:

apiversion:v1

kind:Pod

metadata:

namespace:demo-ns

namedemo-pod

Spec:

containers:

- image:nginx:latest

name:demo-container

requests:

cpu:2

memory:1Gi

1imits:

cpu:2

memory:1Gi

如上 yaml 文件中,指明了容器信息及资源限制,requests 表示需要请求的资源大小,而 limits 表示容器限制资源的大小,如果容器内使用的内存超过了 limits 设置的内存大小,会发生 OOM(out of memory),导致容器重启;如果容器内 CPU使用超过了 limits 设置的 CPU 大小,并不会导致容器重启。

c. 如何判断请求的内存大小

Ÿ 通过执行命令 kubectl describe node xxx(xxx为节点名),查看资源使用情况及请求资源统计。

2.如何满足 Pod 资源要求

a. 什么是 PodQoS?

Ÿ Quality of Service

Kubernetes 为了实现资源被有效调度和分配的同时提高资源利用率,Kubernetes针对不同服务质量的预期,通过 QoS (Quality of Service)  来对 Pod 进行服务质量管理,提供了采用 requests 和 limits 两种类型对资源进行分配和使用限制。

b. QoS 的三种类型:

Ÿ Guaranteed-高,保障( CPU/Memory 必须 request==limit ,其余资源可不等);

Ÿ Burstable-中,弹性( CPU/Memory request 和 limit 不相等);

Ÿ BestEffort-低,尽力而为(所有资源 request/limit 必须都不填);

c. 资源回收策略

Ÿ 当 kubernetes 集群中,某个节点上可用资源比较小时,kubernetes 提供了资源回收策略保证被调度到该节点 pod 服务正常运行。当节点上的内存或者 CPU 资源耗尽时,可能会造成该节点上正在运行的 pod 服务不稳定。

Ÿ Kubernetes 通过 kubelet 来进行回收策略控制,保证节点上 Pod 在节点点资源比较小时可以稳定运行。

d. QoS Pods 被 kill 掉场景与顺序

Ÿ Best-effort 类型的 Pods:系统用完了全部内存时,该类型 pods 会最先被 kill 掉;

Ÿ Burstable 类型 Pods:系统用完了全部内存,且没有 Best-Effort container 可以被kill时,该类型 Pods 会被 kill 掉;

Ÿ Guaranteed Pods:系统用完了全部内存,且没有 Burstable 与 Best-Effort container 可以被 kill,该类型的 Pods 会被 kill 掉;

注:如果 Pod 进程因使用超过预先设定的 limites ,而非 Node 资源紧张情况,系统倾向于在其原所在的机器上重启该 container 或本机或其他重新创建一个Pod。

e. ResourceQuota

作用:限制每个 Namespace 资源用量,如对 Pod 内存和 CPU 限制。

用法:

-pernamespace

-Scope

Terminating/NotTerminating BestEffort/NotBestEffort priorityClass

当 Quota 超限后会禁止创建:

-forbidden:exceeded quota

一个 namespace 下面可以创建多个 ResourceQuota( ResourceQuota 本身也可以限制 ResourceQuota 的数量),常规的使用是把计算资源 quota( cpu、mem 等),存储资源 quota( storage、pvc 等),对象数量 quota( Pod、service 等)分别创建在不同的 ResourceQuota 下面,但是各个 ResourceQuota 中的限制项是可以重复的,这时会取最小的值。

如下示例 yaml 文件中,限制 demo-ns Namespace 下非 BestEffort QoS 的Quota ,cpu 只能使用 1000 个、memory 只能使用 200 Gi、Pods 只能创建10个:

kind:ResourceQuota

metadata:

name:demo-quota

namespace:demo-ns

Spec:

hard:

cpu:"1000"

memory:200Gi

pods:"10"

scopeSelector:#可以不填

matchExpressions:

- operator:Exists

scopeName: NotBestEffort

 

三. 调度相关的配置和使用

1. 如何满足 Pod 与 Pod 之间的关系要求?— Pod 亲和调度

a. Pod 亲和调度 PodAffinity

Ÿ 必须和某些 Pod 调度到一起

requiredDuringSchedulinglgnoredDuringExecution

Ÿ 优先和某些 Pod 调度到一起

preferredDuringSchedulinglgnoredDuringExecution

b. Pod 反亲和调度 PodAntiAffinity

Ÿ 禁止和某些Pod调度到一起

requiredDuringSchedulingIgnoredDuringExecution

Ÿ 优先不和某些 Pod 调度到一起

preferredDuringSchedulinglgnoredDuringExecution

c. Operator

Ÿ In/NotIn/Exists/DoesNotExist

d. nodeSelector 标签选择器

Ÿ 节点选择约束的最简单推荐形式。可以将 nodeSelector  字段添加到 Pod 的规约中设置你希望目标节点所具有的节点标签。Kubernetes 只会将 Pod 调度到指定的每个标签的节点上。

如下示例中,标签的 Key 为 disktype,Value 为 ssd。

apiVersion: v1

kind: Pod

metadata:

name: nginx

labels:

env: test

spec:

containers:

- name: nginx

image: nginx

imagePullPolicy: IfNotPresent

nodeSelector:

disktype: ssd

必须调度到带了 K1=V1 标签的 Pod 所在节点:

apiversion:vl

kind:Pod

metadata:

namespace:demo-ns

name:demo-pod

spec:

containers:

- image: nginx:1atest

name:demo-container

affinity:

podAffinity:

requiredDuringSchedulingIgnoredDuringExecution:

- labelSelector:matchExpressions:

- key:k1

operator:In

values:

- vl

topologykey:"kubernetes.io/hostname"

禁止调度到带了 K1=V1 标签的 Pod 所在节点:

apiversion:vl

kind:Pod

metadata:

namespace:demo-ns

name:demo-pod

spec:

containers:

- image: nginx:1atest

name:demo-container

affinity:

podAffinity:

requiredDuringSchedulingIgnoredDuringExecution:

- 1abelSelector:

matchExpressions:

- key:kl

operator:In

values:

- v1

topologykey:"kubernetes.io/hostname"

2. 如何满足 Pod 与 Pod 之间的关系要求?—Node 亲和调度

a. 节点污点 Node Taints

Ÿ 一个 Node 可以有多个 Taints

Ÿ Effect (不能为空)

ž NoSchedule:只是禁止新 Pods 调度上来;

ž PreferNoSchedule:尽量不调度到这台;

ž NoExecute:会驱逐没有对应 toleration 的 Pods ,并且也不会调度新的上来;

b. Pod Tolerations

Ÿ 一个 Pod 可以有多个 Tolerations

Ÿ Effect 可以为空,匹配所有

ž 取值和 Taints 的 Effect 一致

Ÿ Operator

ž Exists/Equal

示例:

Node 上带了 K1=V1 且效果是 NoSchedule 的 Taints:

apiversion:vl

Kind:Node

metadata:

name:demo-node

spec:

taints:

- key:"k1"

value:"v1"

effect:"Noschedule"

Pod 上必须带有 K1=V1 且效果是 NoSchedule 的 Tolerations:

apiversion:v1

kind:Pod

metadata:

namespace:demo-name

spec:

containers:

image:nginx=latest

name:demo-container

tolerations:

-key:"k1"

operatorEqual"

value:"v1" #当 op=Exists 可为空

effect:"Noschedule" #可以为空,匹配所有

四、集群资源优先级调度

1. 集群资源不够时怎么办?

Ÿ 先到先得策略( FIFO ):简单、相对公平、上手快;

Ÿ 优先级策略( Priority ):符合日常公司业务特点;

优先级和抢占机制,解决的是 Pod 调度失败时该怎么办的问题。正常情况下,当一个 Pod 调度失败后,它就会被暂时“搁置”起来,直到 Pod 被更新,或者集群状态发生变化,调度器才会对这个 Pod 进行重新调度。

2. 特殊要求的场景:

Ÿ 当一个高优先级的 Pod 调度失败后,该 Pod 并不会被“搁置”,而是会“挤走”某个 Node 上的一些低优先级的 Pod,这样就保证这个高优先级 Pod 的调度成功;

Ÿ 如何使用优先级调度呢?需要创建一个 priorityClass 资源,然后再为每个 Pod 应用指定不同的 priorityClassName ,这样就完成了优先级以及优先级调度的配置。

3. 优先级调度的配置

Ÿ 创建 PriorityClass 优先级资源,声明优先级大小;

Ÿ 为各个 Pod 应用指定不同的 priorityClassName;

Ÿ 内置默认优先级:DefaultPriorityWhenNoDefaultClassExists=0

Ÿ 用户可配置的最大优先级限制 HighestUserDefinablePriority=1000000000

Ÿ 系统级别优先级 SystemCriticalPriority=2000000000

Ÿ 内置系统级别优先级 system-cluster-criticalsystem-node-critical

示例:

Ÿ 创建一个名为 high 的 priorityClass,得分为 10000,示例如下:

apiversion:scheduiing.K8s.io/v1

kind:Priorityclass

metadata:

name:high

value:10000

galobalDefault:false

Ÿ 创建一个名为 low 的 priorityClass,得分为100,示例如下:

apiversion:scheduling.k8s.io/v1

kind:Priorityclass

metadata:

name:low

value=100

g1oba1Default:false

 

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
Kubernetes 监控 调度
Kubernetes Pod调度:从基础到高级实战技巧
Kubernetes Pod调度:从基础到高级实战技巧
270 0
|
2月前
|
Kubernetes Docker 容器
Kubernetes学习笔记-Part.06 Docker安装
Part.01 Kubernets与docker Part.02 Docker版本 Part.03 Kubernetes原理 Part.04 资源规划 Part.05 基础环境准备 Part.06 Docker安装 Part.07 Harbor搭建 Part.08 K8s环境安装 Part.09 K8s集群构建 Part.10 容器回退
49 1
|
4天前
|
分布式计算 资源调度 Hadoop
技术好文共享:资源管理与调度系统
技术好文共享:资源管理与调度系统
|
5天前
|
分布式计算 资源调度 监控
分布式资源管理和调度架构
分布式资源管理和调度架构
|
13天前
|
Kubernetes API 调度
Pod无法调度到可用的节点上(K8s)
完成k8s单节点部署后,创建了一个pod进行测试,后续该pod出现以下报错: Warning FailedScheduling 3h7m (x3 over 3h18m) default-scheduler 0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..
50 0
|
2月前
|
Kubernetes 应用服务中间件 调度
k8s-高级调度-污点容忍、亲和性调度
k8s-高级调度-污点容忍、亲和性调度
|
2月前
|
Kubernetes 算法 调度
k8s群集调度之 pod亲和 node亲和 标签指定
k8s群集调度之 pod亲和 node亲和 标签指定
|
2月前
|
Kubernetes 调度 Docker
Ubantu docker学习笔记(十一)k8s基本操作
Ubantu docker学习笔记(十一)k8s基本操作
|
2月前
|
Kubernetes Linux 调度
k8s-高级调度-CronJob 计划任务
k8s-高级调度-CronJob 计划任务
|
2月前
|
Kubernetes 网络协议 调度
kubernetes最小调度单元pod详解(二)
kubernetes最小调度单元pod详解(二)