Kubernetes 核心架构
一、Kubernetes 简介
Kubernetes代码托管在GitHub上:https://github.com/kubernetes/kubernetes
1、什么是 Kubernetes
Kubernetes (通常称为K8s,K8s是将8个字母“ubernete”替换为“8”的缩写) 是用来管理容器集群的平台。
Kubernetes 致力于提供跨主机集群的自动部署、扩展、高可用以及运行应用程序容器的平台,其遵循主从式架构设计,其组件可以分为管理单个节点(Node)组件和控制平面组件,可对集群进行的操作包括部署,调度和集群节点扩展。
Kubernetes Master是集群的主要控制单元,用于管理其工作负载并指导整个系统的通信。
Kubernetes 每个组件都可以在单个主节点上运行,也可以在支持高可用集群的多个节点上运行。
Kubernetes 集群都由一个或多个 Master 负责管理和控制集群节点。Master 对每个节点 Node 发送命令。简单来说,Master 就是管理者,Node 就是被管理者。Node 可以是一台机器或者一台虚拟机。在 Node 上面可以运行多个 Pod,Pod 是 Kubernetes 管理的最小单位,同时每个 Pod 可以包含多个容器(Docker)。
使用Kubernetes可以实现:
自动化容器的部署和复制
随时扩展或收缩容器规模
将容器组织成组,并且提供容器间的负载均衡
很容易地升级应用程序容器的新版本
提供容器弹性,如果容器失效就替换它,等等...
2、Kubernetes 发展史
Kubernetes (希腊语"舵手" 或 "飞行员") 由Joe Beda,Brendan Burns和Craig McLuckie创立,并由其他谷歌工程师,包括Brian Grant和Tim Hockin进行加盟创作,并由谷歌在2014年首次对外宣布。它的开发和设计都深受谷歌的Borg系统的影响,它的许多顶级贡献者之前也是Borg系统的开发者。在谷歌内部,Kubernetes的原始代号曾经是Seven,即星际迷航中友好的Borg(博格人)角色。Kubernetes标识中舵轮有七个轮辐就是对该项目代号的致意。
Kubernetes v1.0于2015年7月21日发布。随着v1.0版本发布,谷歌与Linux 基金会合作组建了Cloud Native Computing Foundation (CNCF)并把Kubernetes作为种子技术来提供。
Kubernetes作为容器集群管理工具,于2015年7月22日迭代到 v 1.0并正式对外公布,这意味着这个开源容器编排系统可以正式在生产环境使用。与此同时,谷歌联合Linux基金会及其他合作伙伴共同成立了CNCF基金会( Cloud Native Computing Foundation),并将Kuberentes 作为首个编入CNCF管理体系的开源项目,助力容器技术生态的发展进步。Kubernetes项目凝结了Google过去十年间在生产环境的经验和教训,从Borg的多任务Alloc资源块到Kubernetes的多副本Pod,从Borg的Cell集群管理,到Kubernetes设计理念中的联邦集群,在Docker等高级引擎带动容器技术兴起和大众化的同时,为容器集群管理提供独了到见解和新思路。
Rancher Labs在其Rancher容器管理平台中包含了Kubernetes的发布版。Kubernetes也在很多其他公司的产品中被使用,比如Red Hat在OpenShift产品中,CoreOS的Tectonic产品中, 以及IBM的IBM云私有产品中。
Docker 作为高级容器引擎快速发展的同时,Google也开始将自身在容器技术及集群方面的积累贡献出来。在Google内部,容器技术已经应用了很多年,Borg系统运行管理着成千上万的容器应用,在它的支持下,无论是谷歌搜索、Gmail还是谷歌地图,可以轻而易举地从庞大的数据中心中获取技术资源来支撑服务运行。
Borg 是集群的管理器,在它的系统中,运行着众多集群,而每个集群可由成千上万的服务器联接组成,Borg每时每刻都在处理来自众多应用程序所提交的成百上千的Job, 对这些Job进行接收、调度、启动、停止、重启和监控。正如Borg论文中所说,Borg提供了3大好处:
隐藏资源管理和错误处理,用户仅需要关注应用的开发。
服务高可用、高可靠。
可将负载运行在由成千上万的机器联合而成的集群中。
Borg作为Google的竞争技术优势,Borg理所当然的被视为商业秘密隐藏起来,但当Tiwtter的工程师精心打造出属于自己的Borg系统(Mesos)时, Google也审时度势地推出了来源于自身技术理论的新的开源工具。
2014年6月,谷歌云计算专家埃里克·布鲁尔(Eric Brewer)在旧金山的发布会为这款新的开源工具揭牌,它的名字Kubernetes在希腊语中意思是船长或领航员,这也恰好与它在容器集群管理中的作用吻合,即作为装载了集装箱(Container)的众多货船的指挥者,负担着全局调度和运行监控的职责。
Google推出Kubernetes的目的之一是推广其周边的计算引擎(Google Compute Engine)和谷歌应用引擎(Google App Engine)。但Kubernetes的出现能让更多的互联网企业可以享受到连接众多计算机成为集群资源池的好处。
Kubernetes对计算资源进行了更高层次的抽象,通过将容器进行细致的组合,将最终的应用服务交给用户。Kubernetes在模型建立之初就考虑了容器跨机连接的要求,支持多种网络解决方案,同时在Service层次构建集群范围的SDN网络。其目的是将服务发现和负载均衡放置到容器可达的范围,这种透明的方式便利了各个服务间的通信,并为微服务架构的实践提供了平台基础。而在Pod层次上,作为Kubernetes可操作的最小对象,其特征更是对微服务架构的原生支持。
Kubernetes 项目来源于Borg,可以说是集结了Borg设计思想的精华,并且吸收了Borg系统中的经验和教训。
3、Kubernetes 核心组件
Kubernetes 遵循 master-slave architecture。Kubernetes 组件可以分为管理单个的 node 组件和控制平面的一部分的组件
Kubernetes Master 是集群的主要控制单元,用于管理其工作负载并指导整个系统的通信。Kubernetes控制平面由各自的进程组成,每个组件都可以在单个主节点上运行,也可以在支持 high-availability clusters 的多个主节点上运行。
Kubernetes 主要由以下几个核心组件组成:
组件名称说明
etcd :分布式键值存储系统。用于保存集群状态,比如Pod、Service等对象信息。
apiserver : 提供了资源操作的唯一入口,各组件协调者,并提供认证、授权、访问控制、API注册和发现等机制;以 HTTPAPI 提供接口服务,所有对象资源的增删改查和监听操作都交给 APIServer 处理后再提交给 Etcd 存储
controller manager : 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;处理集群中常规后台任务,一个资源对应一个控制器,而 ControllerManager 就是负责管理这些控制器的。
scheduler : 负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
kubelet : kubelet 是 Master 在 Node 节点上的 Agent,管理本机运行容器的生命周期,比如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等工作。kubelet 将每个Pod 转换成一组容器。负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
Container runtime : 负责镜像管理以及Pod和容器的真正运行(CRI);
kube-proxy : 负责为Service提供cluster内部的服务发现和负载均衡;在 Node 节点上实现 Pod 网络代理,维护网络规则和四层负载均衡工作。
核心组件结构图
除了核心组件,还有一些推荐的 Add-ons:
组件名称说明
coredns : 负责为整个集群提供DNS服务
Ingress Controller : 为服务提供外网入口
Metrics-server : 提供资源监控
Dashboard : 提供GUI
Federation : 提供跨可用区的集群
Fluentd-elasticsearch : 提供集群日志采集、存储与查询 EFK
4、Kubernetes 核心概念
Kubernetes 核心是集群,集群是一组节点,这些节点可以是物理服务器或者虚拟机,之上安装了 Kubernetes 平台。
Kubernetes 定义了一组构建块,它们可以共同提供部署、维护和扩展应用程序的机制。
Kubernetes 的组件设计为松耦合和可扩展的,这样可以满足多种不同的工作负载。
Kubernetes 可扩展性在很大程度上由 Kubernetes API 提供——它被作为扩展的内部组件以及Kubernetes上运行的容器等使用。
上图可以看到如下组件,使用特别的图标表示Service和Label:
Kubernetes Master(Kubernetes主节点)
Node(节点)
Pod
Container(容器)
Label(
)(标签)
Replication Controller(复制控制器)
Service(
)服务
1、Master
集群拥有一个Kubernetes Master(紫色方框)。Kubernetes Master提供集群的独特视角,并且拥有一系列组件,比如Kubernetes API Server。API Server提供可以用来和集群交互的REST端点。master节点包括用来创建和复制Pod的Replication Controller。
Master节点是Kubernetes集群的控制节点,在生产环境中不建议部署集群核心组件外的任何Pod,公司业务的Pod更是不建议部署到Master节点上,以免升级或者维护时对业务造成影响。
Master节点的组件包括:
APIServer。APIServer是整个集群的控制中枢,提供集群中各个模块之间的数据交换,并将集群状态和信息存储到分布式键-值(key-value)存储系统Etcd集群中。同时它也是集群管理、资源配额、提供完备的集群安全机制的入口,为集群各类资源对象提供增删改查以及watch的REST API接口。APIServer作为Kubernetes的关键组件,使用Kubernetes API和JSON over HTTP提供Kubernetes的内部和外部接口。
Scheduler。Scheduler是集群Pod的调度中心,主要是通过调度算法将Pod分配到最佳的节点(Node),它通过APIServer监听所有Pod的状态,一旦发现新的未被调度到任何Node节点的Pod(PodSpec.NodeName为空),就会根据一系列策略选择最佳节点进行调度,对每一个Pod创建一个绑定(binding),然后被调度的节点上的Kubelet负责启动该Pod。Scheduler是集群可插拔式组件,它跟踪每个节点上的资源利用率以确保工作负载不会超过可用资源。因此Scheduler必须知道资源需求、资源可用性以及其他约束和策略,例如服务质量、亲和力/反关联性要求、数据位置等。Scheduler将资源供应与工作负载需求相匹配以维持系统的稳定和可靠,因此Scheduler在调度的过程中需要考虑公平、资源高效利用、效率等方面的问题。
Controller Manager。Controller Manager是集群状态管理器(它的英文直译名为控制器管理器),以保证Pod或其他资源达到期望值。当集群中某个Pod的副本数或其他资源因故障和错误导致无法正常运行,没有达到设定的值时,Controller Manager会尝试自动修复并使其达到期望状态。Controller Manager包含NodeController、ReplicationController、EndpointController、NamespaceController、ServiceAccountController、ResourceQuotaController、ServiceController和TokenController,该控制器管理器可与API服务器进行通信以在需要时创建、更新或删除它所管理的资源,如Pod、服务断点等。
Etcd。Etcd由CoreOS开发,用于可靠地存储集群的配置数据,是一种持久性、轻量型、分布式的键-值(key-value)数据存储组件。Etcd作为Kubernetes集群的持久化存储系统,集群的灾难恢复和状态信息存储都与其密不可分,所以在Kubernetes高可用集群中,Etcd的高可用是至关重
2、Node
Node节点也被称为Worker或Minion,是主要负责部署容器(工作负载)的单机(或虚拟机),集群中的每个节点都必须具备容器的运行环境(runtime),比如Docker及其他组件等。
Kubelet作为守护进程运行在Node节点上,负责监听该节点上所有的Pod,同时负责上报该节点上所有Pod的运行状态,确保节点上的所有容器都能正常运行。当Node节点宕机(NotReady状态)时,该节点上运行的Pod会被自动地转移到其他节点上。
Node节点包括:
Kubelet,负责与Master通信协作,管理该节点上的Pod。
Kube-Proxy,负责各Pod之间的通信和负载均衡。
Docker Engine,Docker引擎,负载对容器的管理。
3、Pod
Kubernetes 中 Pod 运行在节点上,包含一组容器和卷,处于同一个Pod中的容器共享同样的存储空间(Volume,卷或存储卷)、网络命名空间IP地址和Port端口,容器之间使用localhost:port相互访问。根据Docker的构造,Pod可被建模为一组具有共享命令空间、卷、IP地址和Port端口的Docker容器。
Pod 包含的容器最好是一个容器只运行一个进程。每个Pod包含一个pause容器,pause容器是Pod的父容器,它主要负责僵尸进程的回收管理,解耦,隔离,管理容器。
Pod是短暂的,不是持续性实体。可以把更高级别的抽象内容增加到容器化组件。一个pod一般包含一个或多个容器,并且可以共享资源。
Pod 可以定义一个卷,例如本地磁盘目录或网络磁盘,并将其暴露在pod中的一个容器之中。pod可以通过Kubernetes API手动管理,也可以委托给控制器来管理。
你可能会有这些问题:
如果Pod是短暂的,那么我怎么才能持久化容器数据使其能够跨重启而存在呢? 是的,Kubernetes支持卷的概念,因此可以使用持久化的卷类型。
是否手动创建Pod,如果想要创建同一个容器的多份拷贝,需要一个个分别创建出来么?可以手动创建单个Pod,但是也可以使用Replication Controller使用Pod模板创建出多份拷贝,
如果Pod是短暂的,那么重启时IP地址可能会改变,那么怎么才能从前端容器正确可靠地指向后台容器呢?这时可以使用Service,下文会详细介绍。
4、标签和选择器
Kubernetes 使客户端(用户或内部组件)将称为“标签”的键值对附加到系统中的任何API对象,如pod和节点。相应地,“标签选择器”是针对匹配对象的标签的查询。
标签和选择器是Kubernetes中的主要分组机制,用于确定操作适用的组件。
正如图所示,一些Pod有Label()。一个Label是attach到Pod的一对键/值对,用来传递用户定义的属性。比如,你可能创建了一个"tier"和“app”标签,通过Label(tier=frontend, app=myapp)来标记前端Pod容器,使用 Label(tier=backend, app=myapp)标记后台Pod。然后可以使用 Selectors 选择带有特定Label的Pod,并且将 Service 或者 Replication Controller 应用到上面。
5、控制器
是否手动创建 Pod,如果想要创建同一个容器的多份拷贝,需要一个个分别创建出来么,能否将Pods划到逻辑组里?
控制器是将实际集群状态转移到所需集群状态的对帐循环。它通过管理一组 pod来实现。一种控制器是一个“复制控制器”,它通过在集群中运行指定数量的pod副本来处理复制和缩放。如果基础节点出现故障,它还可以处理创建替换 pod。
Replication Controller 确保任意时间都有指定数量的Pod“副本”在运行。如果为某个Pod创建了 Replication Controller并且指定3个副本,它会创建3个Pod,并且持续监控它们。如果某个Pod不响应,那么 Replication Controller 会替换它,保持总数为3.如下面的动画所示:
如果之前不响应的Pod恢复了,现在就有4个Pod了,那么Replication Controller会将其中一个终止保持总数为3。如果在运行中将副本总数改为5,Replication Controller会立刻启动2个新Pod,保证总数为5。还可以按照这样的方式缩小Pod,这个特性在执行滚动升级时很有用。
创建Replication Controller时,需要指定两个东西:
Pod模板:用来创建Pod副本的模板
Label: Replication Controller 需要监控的Pod的标签。
6、服务 Service
Service 是定义一系列Pod以及访问这些Pod的策略的一层抽象。Service 通过 Label 找到Pod 组, 是为已经创建了Pod的进行负载均衡。
Kubernetes 服务是一组协同工作的 pod,就像多层架构应用中的一层。构成服务的pod组通过标签选择器来定义。
Kubernetes 通过给 Service 分配静态 IP 地址和域名来提供服务发现机制,并且以轮询调度的方式将流量负载均衡到能与选择器匹配的 pod 的 IP 地址的网络连接上(即使是故障导致pod从一台机器移动到另一台机器)。
默认情况下,一个服务会暴露在集群中(例如,多个后端 pod 可能被分组成一个服务,前端pod的请求在后端 pod之间负载平衡);也可以暴露在集群外部(例如,从客户端访问前端pod)。
假定有2个后台Pod,并且定义后台Service的名称为‘backend-service’,lable 选择器为(tier=backend, app=myapp)。backend-service 的 Service 会完成如下两件重要的事情:
为 Service 创建一个本地集群的 DNS 入口,因此前端 Pod 只需要 DNS 查找主机名为 ‘backend-service’,就能够解析出前端应用程序可用的IP地址。
前端得到了后台服务的IP地址,Service在这2个后台Pod之间提供透明的负载均衡,会将请求分发给其中的任意一个(如下面的动画所示)。通过每个Node上运行的代理(kube-proxy)完成。
下述动画展示了Service的功能。注意该图作了很多简化。
有一个特别类型的Kubernetes Service,称为 LoadBalancer,作为外部负载均衡器使用,在一定数量的Pod之间均衡流量。比如,对于负载均衡Web流量很有用。
5、Kubernetes 分层架构
Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示:
分层说明:
分层结构说明
核心层Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
应用层部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)
管理层系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)
接口层kubectl 命令行工具、客户端SDK以及集群联邦
生态系统在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
Kubernetes外部日志、监控、配置管理、CI、CD、Workflow、FaaS(功能及服务)、OTS应用、ChatOps(AIDevOps)等
Kubernetes内部CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等
二、Kubernetes 优势
1、传统部署和容器部署
传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。
新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。
容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势,使用容器可以在build或release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚机轻量、更“透明”,这更便于监控和管理。最后,
2、Kubernetes 容器优势总结
可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)
可扩展: 模块化, 插件化, 可挂载, 可组合
自动化: 自动部署,自动重启,自动复制,自动伸缩/扩展
快速部署应用,快速扩展应用:与VM虚拟机相比,容器镜像的创建更加容易。
持续开发、集成和部署:提供可靠且频繁的容器镜像构建/部署,并使用快速和简单的回滚(由于镜像不可变性)。
开发和运行相分离:在build或者release阶段创建容器镜像,使得应用和基础设施解耦。
无缝对接新的应用功能,开发,测试和生产环境一致性:在本地或外网(生产环境)运行的一致性。
云平台或其他操作系统:可以在 Ubuntu、RHEL、 CentOS、on-prem、Google Container Engine或其它任何环境中运行。
Loosely coupled(松耦合),分布式,弹性,微服务化:应用程序分为更小的、独立的部件,可以动态部署和管理。
资源隔离
资源利用:更高效
三、Kubernetes 劣势
Kubernetes 并不是传统的 PaaS(平台即服务)系统。
Kubernetes 限制受支持的语言runtimes (例如, Java, Python, Ruby),不限制支持应用的类型,不限制应用框架。
Kubernetes 不提供中间件(如 message buses)、数据处理框架(如 Spark)、数据库(如 Mysql)或者集群存储系统(如Ceph)作为内置服务。但这些应用都可以运行在Kubernetes上面。
Kubernetes 不部署源码不编译应用。持续集成的 (CI) 工作流方面,不同的用户有不同的需求和偏好的区域,因此,我们提供分层的 CI工作流,但并不定义它应该如何工作。
Kubernetes 不提供或授权一个全面的应用程序配置 语言/系统(例如,jsonnet)。
Kubernetes 不提供任何机器配置、维护、管理或者自修复系统。
Kubernetes 运行在应用级别而不是硬件级,因此只提供了普通的Paas平台提供的一些通用功能,比如部署,扩展,负载均衡,日志,监控等。
四、Kubernetes 基本功能
可以在物理或虚拟机的 Kubernetes 集群上运行容器化应用,Kubernetes 能提供一个以“容器为中心的基础架构”,满足在生产环境中运行应用的一些常见需求,如:
1、数据卷
Pod 中容器之间共享数据,可以使用数据卷。
2、应用程序健康检查
容器内服务可能进程堵塞无法处理请求,可以设置监控检查策略保证应用健壮性。
3、复制应用程序实例
控制器维护着Pod副本数量,保证一个Pod或一组同类的Pod数量始终可用。
4、弹性伸缩
根据设定的指标(CPU利用率)自动缩放Pod副本数。
5、服务发现
使用环境变量或DNS服务插件保证容器中程序发现Pod入口访问地址。
6、负载均衡
一组Pod副本分配一个私有的 ClusterIP 地址,负载均衡转发请求到后端容器。在集群内部其他Pod可通过这个ClusterIP访问应用。
7、滚动更新
更新服务不中断,一次更新一个Pod,而不是同时删除整个服务。
8、服务编排
通过文件描述部署服务,使得应用程序部署变得更高效。
9、资源监控
Node节点组件集成cAdvisor资源收集工具,可通过Heapster汇总整个集群节点资源数据,然后存储到InfluxDB时序数据库,再由Grafana展示。
10、认证和授权
支持属性访问控制(ABAC)、角色访问控制(RBAC)认证授权策略。