这是我参与「第四届青训营 」笔记创作活动的第11天
Kuberbetes
1.Kubernetes是什么?
Kubermnetes is a portable, extensible, open source platform for managing containerized workloadsand services, that facilitates both declarative configuration and automation. Kubermnetes 是一个可移植、可扩展的开源平台,用于管理容器化工作负载和服务,有助于声明式配置和自动化。
- 特点:便携,可扩展,开源
- 目的:管理容器应用和服务
- 作用:声明式配置和自动化
2.Kubernetes设计准则
- Declarative > imperative: State your desired results, let the system actuate
- Control loops: Observe, rectify, repeat
- Simple > Complex: Try to do as little as possible
- Modularity: Components, interfaces,& plugins
- Legacy compatible: Meet users where they are, requiring apps to change is a non-starter
- Open > Closed: Open Source, standards, REST,JSON, etc.
3.Kubernetes架构
- ETCD:
- 持久化数据中心
- 维护集群中所有数据的有序性和一致性
- 事件机制同步数据变更
- APIServer:
- 对所有组件提供API接口负责admission,鉴权等功能
- 提供后端etcd数据cacher,降低ETCD压力
- 结合ETCD,提供List-Watch机制
- Controller-Manager:
- 提供一系列控制器,负责维护各种对象的生命周期
- 比如: Node controller,PV
- controller,Deployment controller ,StatefulSet controller 等
- Scheduler:
- 负责应用实例的调度,把Pod绑定到合适的Node
- Kubelet:
- 基于Pod声明,真正开始启动容器,
- 负责容器生命周期维护
- Kube-proxy:
- 网络代理,负责维护节点网络规则,接管
- Pod出入流量
4.Kubernetes核心通信机制-List-Watch
List/Watch机制是Kubernetes中实现集群控制模块最核心的设计之一,它采用统一的异步消息处理机制,保证了消息的实时性、可靠性、顺序性和性能等,为声明式风格的API奠定了良好的基础。Informer 模块是Kubernetes中的基础组件,负责各组件与Apiserver的资源与事件同步。Kubernetes中的组件,如果要访问Kubernetes中的Object,绝大部分情况下会使用Informer中的Lister()方法,而非直接请求Kubernetes API。
client-go
Reflector:reflector用来watch特定的k8s API资源。具体的实现是通过ListAndWatch的方法,watch可以是k8s内建的资源或者是自定义的资源。当reflector通过watch API接收到有关新资源实例存在的通知时,它使用相应的list API获取新创建的对象,并将其放入watchHandler 函数内的Delta Fifo队列中。Informer:informer从Delta Fifo队列中弹出对象。执行此操作的功能是processLoop。base controller的作用是保存对象以供以后检索,并调用我们的控制器将对象传递给它。Indexer:索引器提供对象的索引功能。典型的索引用例是基于对象标签创建索引。 Indexer可以根据多个索引函数维护索引。Indexer使用线程安全的数据存储来存储对象及其键。
自定义controller组件
Informer reference:指的是Informer实例的引用,定义如何使用自定义资源对象。 自定义控制器代码需要创建对应的Informer。Indexer reference: 自定义控制器对Indexer实例的引用。自定义控制器需要创建对应的Indexser。Resource Event Handlers:资源事件回调函数,当它想要将对象传递给控制器时,它将被调用。 编写这些函数的典型模式是获取调度对象的key,并将该key排入工作队列以进行进一步处理。Workqueue:任务队列。 编写资源事件处理程序函数以提取传递的对象的key并将其添加到任务队列。Process Item:处理任务队列中对象的函数, 这些函数通常使用Indexer引用或Listing包装器来重试与该key对应的对象。
5.Kubernetes核心功能
- 服务发现和负载均衡
- 存储编排
- 自动发布,回滚
- 自愈
- 秘钥,配置管理
- 资源管理,应用编排调度
Kubernetes资源管理
1.资源种类
- CPU,Memory,HugePages,GPU...
- Socket, Numa, NIC ...
- Ephemeral Storage,NFS,GlusterFS...RBD,Cinder...
- ByteDance Storage(FS,Block)...
2.资源上报
在 k8s 中,kubelet 也会定时上报心跳到 apiserver,以此判断该 node 是否存活,若 node 超过一定时间没有上报心跳,其状态会被置为 NotReady,宿主上容器的状态也会被置为 Nodelost 或者 Unknown 状态。kubelet 自身会定期更新状态到 apiserver,通过参数
--node-status-update-frequency 指定上报频率,默认是 10s 上报一次,kubelet 不止上报心跳信息还会上报自身的一些数据信息。
3.资源分配
为容器和 Pod 分配CPU和内存资源
4.资源维护
5.资源回收
回收计算资源和存储资源
调度
1.资源申请
kubernetes 中 pod 对资源的申请是以容器为最小单位进行的,针对每个容器,它都可以通过如下两个信息指定它所希望的资源量:
- request
- limit
request:
- request 指的是针对这种资源,这个容器希望能够保证能够获取到的最少的量。
- 在实际情况下,CPU request 是可以通过 cpu.shares 特性能够实现的。
- 内存资源,由于它是不可压缩的,所以在某种场景中,是有可能因为其他 memory limit 设置比 request 高的容器对内存先进行了大量使用导致其他 pod 连 request 的内存量都有可能无法得到满足。
• limit:
- limit 对于 CPU,还有内存,指的都是容器对这个资源使用的上限。
- 这两种资源在针对容器使用量超过 limit 所表现出的行为也是不同的。
- 对 CPU 来说,容器使用 CPU 过多,内核调度器就会切换,使其使用的量不会超过 limit。
- 对内存来说,容器使用内存超过 limit,这个容器就会被 OOM kill 掉,从而发生容器的重启。
- 在容器没有指定 request 的时候,request 的值和 limit 默认相等。
而如果容器没有指定 limit 的时候,request 和 limit 会被设置成的值则根据不同的资源有不同的策略。
2.调度流程
- QueueSort:对队列中的 Pod 进行排序
- PreFilter:检查预处理 Pod 的相关信息以安排调度周期
- Filter:过滤不适合该 Pod 的节点
- PostFilter:如果找不到可用于 Pod 的可行节点,调用该插件
- PreScore:运行 PreScore 任务以生成一个可共享状态供 Score 插件使用
- Score:通过调用每个 Score 插件对过滤的节点进行排名
- NormalizeScore:合并分数并计算节点的最终排名
- Reserve:在绑定周期之前选择保留的节点
- Permit:批准或拒绝调度周期结果
- PreBind:执行任何先决条件工作,例如配置网络卷
- Bind:将 Pod 分配给 Kubernetes API 中的节点
- PostBind:通知绑定周期的结果
Kubernetes和YARN的一些不同
- 基本单位
- Pod & Container
- 资源管理
- 资源种类扩展能力
- 调度模式
- Task -> Node
- Node ->Task
- 系统设计
- 中心存储&节点缓存