深入理解K8S资源管理和调度
这是我参与「第四届青训营」笔记创作活动的第十七天
1.Kubernetes简介
kubernetes,简称K8s,是用8代替名字中间的8个字符“ubernete”而成的缩写。是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。
1.需要Kubernetes的原因
- 容器相比于传统的虚拟化技术,更轻量,更敏捷,更易于管理,运维成本更低;
- 一次打包,任意地方运行
- 如果容器规模巨大,如何编排管理容器也是个巨大的挑战,需要一个强大的管理系统,Kubernetes 在这方面表现很好
2.核心概念
- Pod:Kubernetes 的基本构建块。 一个 Pod 包含一组(一个或多个)容器。 通常,每个 Pod 有一个容器。
- Depolyment:- Deployment是一个部署在Pod内的一个或多个容器映像(Docker ..etc)的组,并通过Kubernetes部署控制器监视和创建,更新或删除此类部署
- StatefulSet:StatefulSet 是用于管理有状态应用的工作负载对象,与 ReplicaSet和Deployment这两个对象不同,StatefulSet 不仅能管理 Pod 的对象,还它能够保证这些 Pod 的顺序性和唯一性。
- Volume:Kubernetes提供了更强大的Volume机制和插件,解决了容器数据持久化以及容器间共享数据的问题。Kubernetes存储卷的生命周期与Pod绑定
- 容器挂掉后Kubelet再次重启容器时,Volume的数据依然还在
- Pod删除时,Volume才会清理。数据是否丢失取决于具体的Volume类型,比如emptyDir的数据会丢失,而PV的数据则不会丢
- PV:PV是集群中的一块存储,一般可以由集群的管理员事先供应,或者使用storage class的方式来动态供应。pv属于集群资源,它们的生命周期跟使用它们的pod时相互独立。
- PVC:表达的是用户对存储的请求(persistant volume claim),也是kubernetes中独立存在的API资源。Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。
- Node:Kubernetes 通过将容器放入在节点(Node)上运行的 Pod 中来执行你的工作负载。 节点可以是一个虚拟机或者物理机器,取决于所在的集群配置。 每个节点包含运行 Pod所需的服务; 这些节点由控制面负责管理。
3.Kubernetes 架构
- ETCD
- 持久化数据中心
- 维护集群中所有数据的有序性和一致性
- 事件机制同步数据变更
- APIServer
- 对所有组件提供 API 接口
- 负责 admission,鉴权等功能
- 提供后端 etcd 数据 cacher,降低 ETCD 压力
- 结合 ETCD,提供 List-Watch 机制
- Controller-manager
- 提供一系列控制器,负责维护各种对象的生命周期 比如: Node controller, PV controller, Deployment controller, StatefulSet controller 等
- Kubelet
- 基于 Pod 声明,真正开始启动容器,负责容器生命周期维护
- Kube-proxy
- 网络代理,负责维护节点网络规则,接管 Pod 出入流量
4.Kubernetes 特心功能
- 服务发现和负载均衡
- 存储编排
- 自动发布,回滚
- 自愈
- 秘钥,配置管理
- 资源管理,应用编排调度
2.资源管理
1.资源种类
- 计算类
- 原生: CPU,memory,等;
- 可通过 Device plugin 方式支持的非原生: numa,socket。。。
- 存储类
- 原生:
- 临时存储: Ephemeral storage,EmptyDir 等
- 持久化 (PV): Cinder, RBD, Cephfs, NFS, GlusterFS...
- 可以通过 CSI 方式扩展支持其他存储;
- 原生:
2.资源上报
- 计算资源上报:
- cAdvisor -> Kubelet -> Node
- Agent -> Device plugin -> Kubelet -> Node
- 存储资源上报:
- 临时存储:
- cAdvisor -> Kubelet -> Node
- 持久化存储:
- 托管到存储提供商管理
- 临时存储:
3.资源分配
- 计算资源分配
- Kubelet -> cgroup manager -> cpu, memory...
- Kubelet -> device manager -> extended resources
- 存储资源分配
- Controller manager -> provisioner -> attacher -> mounter
4.资源状态维护
- 计算资源状态维护
- kubelet/cgroup manager/device manager/evictioner manager -> cpu, memory, extended resources
- 存储资源维护
- PV controller -> PV/PVC
5.资源回收
- 计算资源回收
- Kubelet -> cgroup manager -> cpu, memory...
- Kubelet -> device manager -> extended resources
- 存储资源回收
- Controller manager -> unmounter -> detacher -> deleter
3.Kubernetes 调度
1.调度流程
2.调度框架
主要分为几个步骤:
- 过滤
- Pre-Filter: 进行一些全局的准备工作,防止流程中多次重复计算;
- Filter: 基于 Pod 的约束,进行 Pod -> Node 的匹配工作;
- Post-Filter: 如果没有一个合适的节点,则进行一些抢占行为(驱逐低优任务),看是否能找到合适节点;
- 打分
- 基于前面的过滤节点,对合适的节点进行打分,按照分值高低进行排序;
- 如果前面没有合适的节点,则直接调度失败;
- 任务分配
- Reserve: 在调度器 cache 里面缓存调度结果,为了解决异步 API 操作带来的时延问题;
- Permit: 扩展接口,可以在这里支持一些扩展语音,比如: Gang 等;
- 结果有三类: 失败,成功,等待
- 失败: 直接返回调度失败结果;
- 成功: 直接通过;
- 等待: 则异步等待,不阻塞其他流程;
- 结果有三类: 失败,成功,等待
- Pre-Bind: 任务运行前的一些准备操作,比如: 动态创建 Volume 等;
- Bind: 把 Pod 绑定到 Node,即: 给应用分配运行节点;
4.Kubernetes 与 Yarn 的一些不同点:
- 基本单位:
- Yarn: Container;
- Kubernetes: Pod;
- 资源管理的扩展能力:
- Yarn: 没提供 Plugin 机制,侵入性较大;
- Kubernetes: plugin 机制扩展,侵入性小;
- 调度模式:
- Yarn: Node -> Task
- Kubernetes: Task -> Node
- 系统设计
- Yarn: 节点缓存,无核心中心化存储;
- Kubernetes: 中心化存储;