热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

K8s前世今生与架构组件简析

k8s前世k8s的前世是google内部的Borg系统,是一个作业调度平台,调度的对象是一个个进程。Borg本身也利用了容器化技术比如Cgroups,


k8s 前世

k8s 的前世是google 内部的Borg 系统,是一个作业调度平台,调度的对象是一个个进程。
在这里插入图片描述
Borg 本身也利用了容器化技术比如 Cgroups, Namespace 实现应用的隔离。

运行在线上的业务主要分为在线业务(prod)和离线业务(non-prod, Batch),比如上边的 Gmail,Google Docs 和 Web Search 就是离线业务,中间的 MapReduce 等业务就是离线业务,大数据的批处理业务一般都是离线业务。

在线业务就要求服务的稳定性,高可用,对资源的消耗一般不高,离线业务对资源的要求比较高,比如说AI 模型训练等,但是离线业务对可用性要求相对于在线业务不高,比如说一个批处理业务跑失败了,可以重试。

Borg 就是整合了整个数据中心的离线业务和在线业务,来进一步提高资源的利用率。

Borg 简介
特性:


  • 物力资源利用率高。
  • 服务器共享,在进程级别做隔离。
  • 应用高可用,故障恢复时间短。
  • 调度策略灵活。
  • 应用接入和使用方便,提供了完备的Job 描述语言,服务发现,实时状态监控和诊断工具。

优势:


  • 对外隐藏底层资源管理和调度、故障处理等。
  • 实现应用的高可靠和高可用。
  • 足够弹性,支持应用跑在成千上万的机器。

Borg 基本概念

Workload


  • prod: 在线任务
  • non-prod: 离线任务

Cell


  • 一个Cell 就是一个集群
  • Cell 对服务器资源进行了抽象,用户在使用Borg 的时候无需关心资源分配,程序安装,依赖管理、健康检查及故障恢复。

Job 和 Task


  • Job 是作业的的描述对象,用户可以通过Job 定义属性、元信息和优先级,优先级涉及到抢占式调度过程。
  • 一个Job 可以包含多个相同的Task, 每一个Task 运行相同的应用程序,Task 数量就是应用的副本数。

Naming


  • Borg 的服务发现通过BNS(Borg Name Service) 来实现。
  • 50.jfoo.ubar.cc.borg 可表示在一个名为cc的Cell中由用户ubar部署的一个名为jFoo的Job下的第50个Task。

Borg 架构

在这里插入图片描述
Borg 的架构是比较经典的Master-Worker 加 Scheduler 调度的简洁架构。

Borgmaster 主进程


  • 处理客户端RPC请求,比如创建Job, 查询Job 等。
  • 维护系统组件和服务的状态,比如服务器、Task等。
  • 负责与Borglet 通信。

Scheduler 进程


  • 调度策略


    • Worst Fit,将任务调度到集群资源利用率最低的节点运行,目的就是使提高整个集群各个节点的资源利用率
    • Best Fit,根据任务指定的资源情况,分配到剩余资源最合适(最接近指定资源量)的节点,比如说一个任务需要2个CPU,刚好有个机器只剩下2个多CPU资源,那么这个任务就会被分配到该机器运行。
      这样就会导致很多任务都运行在一个节点上,那么就会出现有的节点很忙,有的节点很闲,这样就意味着可以将空闲的节点移除,降低资源成本
    • Hybrid,混合模式。
  • 调度优化


    • Score caching: 当服务器或者任务的状态未发生变更或者变更很少时,直接采用数据缓存,避免重复计算。
    • Equivalencecalsses: 调度同一个Job 下多个相同的Task 只需要计算一次。
    • Relaxed randomization: 引入一些随机性,即每次随机选择一些机器,只要符合需求的服务器数量达到一定值时,就可以停止计算,无需每次对Cell 中所有服务器进行feasibility checking.

Borglet


  • Borglet 是部署在所有服务器上的Agent, 负责接收master 进程的指令。

应用高可用


  • 被抢占的离线任务放回pending queue ,等待重新调度。
  • 多副本应用跨故障域部署
  • 对于类似服务器或操作系统升级的维护操作,避免大量服务器同时进行。
  • 支持幂等性,支持客户端重复操作。
  • 当服务器状态变为不可用时,要控制重新调度任务的速率。因为Borg 无法区分是节点故障还是出现了短暂的网络分区,如果是后者,等待网络恢复更利于保障服务可用性。
  • 当某种“任务 @ 服务器”的组合出现故障时,下次重新调度时需避免这种组合再次出现,因为极大可能会再次出现相同故障。
  • 记录详细的内部信息,便于故障排查和分析
  • 保障应用高可用的关键性设计原则:无论何种原因,即使Borg 进程挂掉、失联,都不能杀死正在运行的服务(Task)。

Borg 系统自身高可用


  • Borgmaster 组件多副本设计。
  • 采用一些简单的和底层的工具来部署Borg 实例,避免引入过多的外部依赖。
  • 每个Cell的Borg 独立部署,避免不同Borg 系统相互影响。

资源利用率


  • 通过将在线任务和离线任务混合部署,空闲时,离线任务可以充分利用计算资源;繁忙时,在线任务通过抢占的方式保证优先得到执行,合理地利用资源
  • 夜间用户使用在线任务比较少,资源空闲多,所以一般将离线任务在夜间运行。

隔离性


  • 安全性隔离
    • 早期使用Chroot jail, 后期版本基于 Namespace
  • 性能隔离
    • 采用基于Cgroup 的容器技术实现。
    • 在线任务是延时敏感型的,优先级高,而离线任务优先级低。
    • 通过不同优先级之间的抢占式调度来优先保障在线业务任务的性能,牺牲离线任务。
    • Borg 将资源分为两类:
      可压榨资源,CPU是可压榨资源,资源耗尽不会终止进程。
      不可压榨资源,内存是不可压榨资源,资源耗尽进程会被终止。

Borg 调度原理

作为开发人员除了编写健壮的代码逻辑,还希望自己的服务能够在资源足够的环境下运行,这个足够资源就难以判断,一般是通过压测来决定:

比如说我的服务目标是实现qps 最少为10,为了保证峰值资源足够,那么就以100作为基准进行压测,在申请服务器资源的时候就以10倍申请,这样在大多数空闲的时候,是极度浪费的。

针对这种情况,Borg做了优化,Borg 的调度在Task 申请资源的时候,并不会直接按照用户所说的资源大小去申请,而是会计算出实际使用的资源,然后再预留一点资源防止峰值,最后将剩下的多的资源回收。
在这里插入图片描述
这样在使用Borg 的时候,Task的资源就是动态变化的,而无需担心资源的浪费。


什么是kubernetes(K8S)

k8s 是google 基于 Borg 开源的容器集群管理系统,主要功能包括:


  • 基于容器的应用部署、维护和滚动升级
  • 负载均衡和服务发现
  • 跨机器和跨地区的集群调度
  • 自动伸缩
  • 无状态服务和有状态服务
  • 插件机制保证扩展性

系统一般分为声明式系统和命令式系统,命令式系统关注如何做,声明式系统关注做什么:

比如说使用电视遥控器切换上下台,调节音量大小就是命令式系统,你要告诉电视如何做。
使用空调遥控器将温度设置为25度,就是声明式系统,你不用关心空调该如何做,而是告诉空调做什么。


  • 声明式包括直接声明与间接声明,直接声明就是告诉你我需要什么,间接声明就是不直接告诉你我的需求,我会把我的需求放在特定的地方,请在方便的时候拿出来处理。
  • 声明式系统的好处就是幂等性,状态固定,每次我要你做事,请给我返回相同结果。
  • 声明式系统是面向对象的,把一切抽象成对象。

k8s 中的声明式
k8s 的所有管理能力构建在对象抽象的基础上,核心对象包括:


  • Node: 计算节点的抽象,用来描述计算节点的资源抽象、健康状态等。
  • Namespace:资源隔离的基本单位,可以简单理解为文件系统中的目录结构。
  • Pod: 用来描述应用实例,包括镜像地址,资源请求等。k8s 中最核心的对象,也是打通应用和基础架构的秘密武器。
  • Service:服务如何将应用发布成服务,本质上是负载均衡和域名服务的声明。

k8s 架构

在这里插入图片描述
k8s 采用与Borg 类似的架构,都是主从结构,每个worker 上都有一个 Kubelet用来管理worker 节点,master 也只能通过kubelet 与 worker 交互。

用户与K8s的交互以及k8s 间各组件间的交互都需要通过API Server, master 与 worker 节点都不能直接与etcd 交互,也只能通过API Server。

包括的主要组件如下:
在这里插入图片描述master 节点包括认证鉴权模块, REST API模块,scheduler 模块,controller 模块, 分布式存储模块etcd。


  • 用户的所有请求都只能通过该服务的REST API与k8s 交互。
  • k8s 的元数据存储使用的是分布式存储服务etcd, 这是一个强大的、稳定的、高可用的键值存储。
  • kube-controller manager 控制管理器,运行着所有处理集群日常任务的控制器。包括了节点控制器、副本控制器、端点控制器以及服务账户等。
  • 调度器Scheduler,会监控新建的pods(一组或一个容器)并将其分配给节点。

node 节点包括kubelet 模块,Proxy 模块,以及核心Pod 模块和运行在Pod 中的容器。


  • kebelet 负责调度到对应节点的Pod 的声明周期管理,执行任务并将 Pod 状态报告给主节点的渠道,通过容器运行时(拉取镜像、启动和停止容器)来运行这些容器。还会定期执行被请求的容器的健康探测程序。
  • Kube-proxy 负责节点的网络,在主机上维护网络规则并执行连接转发。还负责对正在服务的 pods 进行负载均衡。

etcd

在这里插入图片描述
etcd 是基于 Raft 协议开发的分布式k-v 存储,可用于服务发现、共享配置以及一致性保障(如数据库选主、分布式锁等)。


  • 基本的k-v 存储
  • 监听机制
  • key 的过期及续约机制,用于监控和服务发现
  • 原子CAS 和 CAD, 用于分布式锁和 leader 选举

关于etcd 的操作,官方文档讲解的很清楚:https://etcd.io/docs/v3.3/demo/


API Server

在这里插入图片描述
kube-APIServer 是k8s 最重要的核心组件之一,主要提供以下功能:


  • 提供集群管理的REST API 接口,包括:
    认证:Authentication,校验身份是否合法
    授权:Authorization,校验是否有权限
    准入:Admission(Mutating & Valiating),校验是否运行执行该动作, 鉴权是层层递进的,当执行一个动作时,有权限不代表该动作在当时是合法的。
  • 提供其他模块之间的数据交互和通信的枢纽(其他模块通过APIServer 查询或修改数据,只有APIServer 才可以直接操作etcd)
  • APIServer 提供etcd 数据缓存以减少集群对etcd 的访问。

API Server 展开:
在这里插入图片描述
API Server 没有太多的逻辑,主要就是对各个请求进行权限验证:


  • APIHandler: 每一个请求都会对应一个handler 处理
  • AuthN: 认证,这里的认证可以使用外部认证服务(AuthService),这样就可以和企业的一些自己的认证相结合。
  • Rate Limit: 限流
  • Auditing: 审计,会对请求进行log 记录,为了日后的安全审查
  • AuthZ: 这里使用的是RBAC进行权限校验,可以使用k8s 自身的也可以使用外部的鉴权服务。
  • Aggregator: APIServer 接收的是REST API,它可以像Nginx 一样将不同的请求路由的不同的服务,这里支持用户自定义一些APIServer验证逻辑,当走到 Aggregator 时,如果你的请求需要走自定义的那么 Aggregator 就会将请求转发到 Aggregated APIServer
    然后最终请求到达 etcd。
  • Mutating: 对请求参数进行变形封装,方便后边的校验
  • Validating: 对请求参数进行校验

Controller Manager

Controller Manager 是集群的大脑,是确保整个集群动起来的关键,会监控APIServer。


  • 确保k8s 遵循声明式系统规范,确保系统的真实状态与用户的期望状态一致。
  • Controller Manager 是多个控制器的组合,每个 Controller 都是一个loop, 负责监听其管控的对象,当对象发生变更时完成配置。
  • Controller 配置失败通常会触发自动重试,整个集群会在控制器不断重试的机制下确保最终一致性(Eventual Consistency)

比如说我启动一个deployment 期望启动两个Pod, 但是当时集群资源不足,只能够启动一个Pod, 那么另一个Pod 就会处于未调度状态, Controller 会不断的重试,当集群资源够的时候,吊起另一个Pod。

控制器的工作流程
k8s 的任何对象是允许用户自己去做监听的,针对这些对象的访问,k8s 提供了CodeGenerator 可以帮助用户生成访问这些对象的代码框架,这个代码框架就叫Controller Interface:
在这里插入图片描述


  • Informer: 可以通过Informer 监听任何对象,当对象的状态进行变化,比如说增删改查,都会生成一个event 事件,任何的controller 都是一个生产者消费者模型,会将事件对应的key, 放在一个队列中,然后worker 去消费这些key, 进行下一步动作。
  • Lister: 会对对象的状态进行一些缓存,并且对外提供接口,这样就可以通过Lister 直接获取cache 中的对象状态,无需走APIServer

Informer 的工作机制
在这里插入图片描述


  • List & Watch 会将所有对象作为一个List 返回过来,然后保持一个长连接去监听对象的状态。
  • APIServer 传递到Informer的对象是序列化的,在Informer 中就需要用到反射,将对象反序列化为一个个对象放到队列中。
  • 每个对象状态的变更,都会分配到一个Event 进行处理,当处理完毕后,会将处理过的状态也同步更新至 Thread Safe Store, 这里的 Thread Safe Store 就是Controller Interface 中的Lister 中缓存的对象状态。

控制器的协同工作原理
在这里插入图片描述
APIServer 中有各种各样的控制器,每个控制器的分工是不同的,比如上边创建一个Deployment 就先经过多个控制器:
Deployment Controller:监听Deployment, 创建副本集。

ReplicaSet Controller: 监听副本集,创建Pod, 这个时候创建出来的Pod 是未调度状态的,需要经过调度器发现可用节点,然后再根据调度策略,将Pod 绑定至对应节点。

然后节点上的kubelet 就会加载对应Pod, 通过CRI(Container Runtime Interface) 将容器进程拉起来,通过CNI(Container Network Interface)加载对应容器网络,通过CSI(Container Storage Interface) 挂载对用容器存储,这个时候这个Pod 就处于已调度状态了。


Scheduler

特殊的Controller,工作原理与其他控制器无差别。

Scheduler 的职责在于监控当前集群所有未调度的 Pod, 并且获取当前集群所有节点的健康状况和资源使用情况,为待调度 Pod 选择最佳计算节点,完成调度。

调度阶段分为:
在这里插入图片描述


  • Predict: 过滤不能满足业务需求的节点,如资源不足、端口冲突等。
  • Priority:按既定要素将满足调度需求的节点评分,选择最佳节点。
  • Bind:将计算节点与Pod 绑定,完成调度。

Kubelet

在这里插入图片描述
k8s 的初始化系统(init system)


  • 从不同源获取Pod 清单,并按需求启停 Pod 的核心组件:
    • Pod 清单可从本地文件目录,给定的HTTPServer 或 Kube-APIServer 等源头获取
    • Kubelet 将运行时,网络和存储抽象成了 CRI, CNI, CSI
  • 负责汇报当前节点的资源信息和健康状态
  • 负责 Pod 的健康检查和状态汇报

Kube-Proxy

在这里插入图片描述


  • 控制集群中用户发布的服务,并完成负载均衡配置。
  • 每个节点的Kube-Proxy 都会配置相同的负载均衡策略,使得整个集群的服务发现建立在分布式负载均衡器之上,服务调用无需经过额外的网络跳转。
  • 负载均衡配置置于不同插件实现:
    • userspace
    • 操作系统网络协议栈不同的Hooks 点和插件:
      iptables
      ipvs

推荐的Add-ons


  • kube-dns: 负责为整个集群提供DNS 服务(现在已经作为k8s内置组件了)
  • ingress Controller:为服务提供外网入口
  • MetricsServer: 提供监控资源
  • Dashboard: 提供GUI
  • Fluentd-Elasticsearch: 提供集群日志采集、存储与查询






推荐阅读
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
author-avatar
葫芦娃才是萌神
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有