这是我参与「第四届青训营 」笔记创作活动的第15天,这次记录了k8s的学习笔记,这次整理了在线业务调度框架k8s的学习笔记,包含基本架构和与离线业务场景调度框架Yarn的不同。
Kubernetes 简介
什么是容器引擎?
容器引擎允许你绑定和运行一个应用在一个容器里,这是一个松散隔离的环境。由于隔离性和安全性,你可以在一台主机上操作多个容器。
容器引擎利用了操作系统的内核资源隔离特性,可以在同一个操作系统上运行多个容器。人们通常把容器引擎比作虚拟机(VMs)。
另一方面,虚拟机利用物理硬件资源抽象层之上可执行代码封装了整个操作系统。
什么是容器?
一个容器镜像是一个可运行的软件包,其中包含了一个完整的可执行程序,包括代码和运行时需要应用、系统库和全部重要设置的默认值。
应用程序通过使用容器与底层的宿主机架构解耦。如下图所示,我们可以利用底层机器在容器引擎之上运行多个容器。这促进了容器在各种操作系统和云场景中的部署。
为什么需要 Kubernetes ?
- 容器相比于传统的虚拟化技术,更轻量,更敏捷,更易于管理,运维成本更低
- 一次打包,任意地方运行
- 如果容器规模巨大,如何编排管理容器也是个巨大的挑战,需要一个强大的管理系统,Kubernetes 在这方面表现很好
- 基于 google 超过 15 年的大规模容器管理经验
- 功能丰富,易于扩展,架构优雅
- 社区活跃,仅次于 Linux 的全球第二大社区
Kubernetes 定义
便携,可扩展,开源的容器管理平台
Kubernetes 特性
- 服务发现和负载均衡
- 存储编排
- 自动发布,回滚
- 自愈
- 秘钥,配置管理
- 资源管理,应用编排调度
Kubernetes 架构
ETCD
K8s使用了Etcd,一个提供分布式键值存储的数据库,用来共享集群的整体状态的信息。
- 持久化数据中心
- 维护集群中所有数据的有序性和一致性
- 事件机制同步数据变更
APIServer
API 服务器为K8s集群提供了一个REST接口。 所有在pod上激活的服务和别的对象都是可以用可编程的方式与与终端进行交互。
- 对所有组件提供 API 接口
- 负责 admission,鉴权等功能
- 提供后端 etcd 数据 cacher,降低 ETCD 压力
- 结合 ETCD,提供 List-Watch 机制
Controller-manager
K8s控制器管理器是管理K8s核心控制循环的服务。它负责确保集群的共享状态正常运行。
- 提供一系列控制器,负责维护各种对象的生命周期 比如: Node controller, PV controller, Deployment controller, StatefulSet controller 等
Kubelet
Kubelet是一个工作节点组件。它的任务是跟踪pod及其容器的运行状态。它与pod的YAML 或JSON描述文件相关。Kubelet检查 pod 规格并确定 pod 是否健康。
- 基于 Pod 声明,真正开始启动容器,负责容器生命周期维护
Kube-proxy
Kube代理是一个网络代理和负载均衡器,充当每个节点和API服务器之间的连接。它在集群中的每个节点上运行,并允许你从内部和外部连接到pod。
- 网络代理,负责维护节点网络规则,接管 Pod 出入流量
控制平面
- 控制平面是管理员和用户管理不同节点的地方。它通过HTTP调用接收命令或者连接到系统并且运行命令行脚本。顾名思义,它控制了K8s与应用程序的交互方式。
调度器
调度器负责将任务分配给各个节点。它监控资源容量并保证工作节点的性能保持在可接受的范围内。
节点
节点是运行了pod的物理机或虚拟机。控制平面管理集群中的每个节点,该节点包含运行 pod所需的服务。
Pods
K8s pod 是K8s管理容器集的最小单位。 每个pod有一个分配给pod中的所有容器的单独的IP 地址。在pod中的容器内存和存储资源是共享的。当应用程序只有一个进程时,pod 也可以有一个容器。
Kubectl
Kubectl是K8s的命令行工具。它用于部署应用程序、监控和控制集群资源以及查看日志。
- 从用户的角度来看,Kubectl 是你的K8s的控制面板。它使你能够执行所有K8s操作
- 从技术角度来看,Kubectl 是K8s API的客户端
Kubernetes 资源管理
资源种类:
计算类
- 原生: CPU,memory
- 可通过 Device plugin 方式支持的非原生: numa,socket
存储类
- 原生:
- 临时存储: Ephemeral storage,EmptyDir
- 持久化 (PV): Cinder, RBD, Cephfs, NFS, GlusterFS
- 可以通过 CSI 方式扩展支持其他存储;
资源分配
计算资源分配:
- Kubelet -> cgroup manager -> cpu, memory
- Kubelet -> device manager -> extended resources
存储资源分配:
- Controller manager -> provisioner -> attacher -> mounter
资源状态维护
计算资源状态维护:
- kubelet/cgroup manager/device manager/evictioner manager -> cpu, memory, extended resources
存储资源维护
- PV controller -> PV/PVC
资源回收
计算资源回收:
- Kubelet -> cgroup manager -> cpu, memory
- Kubelet -> device manager -> extended resources
存储资源回收:
- Controller manager -> unmounter -> detacher -> deleter
Kubernetes 调度
主要分为几个步骤:
过滤
- Pre-Filter: 进行一些全局的准备工作,防止流程中多次重复计算
- Filter: 基于 Pod 的约束,进行 Pod -> Node 的匹配工作
- Post-Filter: 如果没有一个合适的节点,则进行一些抢占行为(驱逐低优任务),看是否能找到合适节点
打分
- 基于前面的过滤节点,对合适的节点进行打分,按照分值高低进行排序
- 如果前面没有合适的节点,则直接调度失败
任务分配
-
Reserve: 在调度器 cache 里面缓存调度结果,为了解决异步 API 操作带来的时延问题
-
Permit: 扩展接口,可以在这里支持一些扩展,比如: Gang 等
- 结果有三类: 失败,成功,等待
- 失败: 直接返回调度失败结果
- 成功: 直接通过
- 等待: 则异步等待,不阻塞其他流程
- 结果有三类: 失败,成功,等待
-
Pre-Bind: 任务运行前的一些准备操作,比如: 动态创建 Volume 等
-
Bind: 把 Pod 绑定到 Node,即: 给应用分配运行节点
Kubernetes 与 Yarn 的不同点
基本单位
- Yarn:Container
- Kubernetes:Pod
资源管理的扩展能力
- Yarn:没提供 Plugin 机制,侵入性较大
- Kubernetes:plugin 机制扩展,侵入性小
调度模式
- Yarn: Node -> Task
- Kubernetes: Task -> Node
系统设计
- Yarn: 节点缓存,无核心中心化存储
- Kubernetes: 中心化存储
Kubernetes 在哪些地方可以更好
- 非原生资源的精细化管理能力
- 动态资源的接入,管理能力
- 更多场景的调度功能和性能优化
- 调度质量