官网
官方文档
Kubernetes(通常称为K8s,K8s是将8个字母“ubernete”替换为“8”的缩写)是一个以容器为中心的基础架构,可以实现在物理集群或虚拟机集群上调度和运行容器,提供容器自动部署、扩展和管理的开源平台。满足了应用程序在生产环境中的一些通用需求:应用实例副本、水平自动扩展、命名与发现、负载均衡、滚动升级、资源监控等。
Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化工作负载和服务,有助于声明式配置和自动化。它拥有庞大且快速发展的生态系统。
Kubernetes由Joe Beda,Brendan Burns和Craig McLuckie创立,并由其他谷歌工程师进行加盟创作,谷歌在2014年首次对外宣布。在谷歌内部,Kubernetes的原始代号曾经是Seven,即星际迷航中友好的Borg(博格人)角色。Kubernetes标识中舵轮有七个轮辐就是对该项目代号的致意。
Kubernetes v1.0于2015年7月21日发布。随着v1.0版本发布,谷歌与Linux 基金会合作组建了Cloud Native Computing Foundation (CNCF)并把Kubernetes作为种子技术来提供。CNCF又名云原生技术基金会。
总所周知kubernetes是一个容器编排工具,可以高效、批量的去管理容器;那么有人就要问了,docker有自带的docker-compose(单机编排)和docker-Swarm(多机编排),为什么还要用k8s,Docker-Compose的运用可以充分地把单物理服务器的性能充分利用起来,并且可以快速地进行持续交付,那如何高效地进行监控各个容器的健康运行情况以及崩溃后如何迁移服务呢?也就是常见的集群管理问题,此时的docker Swarm技术解决了这个问题,但是如何更加高效、智能的管理容器集群呢?这时谷歌公司内部使用很久k8s横空出世,抢占了近80%的市场份额,成为行业领头羊,为什么k8s能击败docker Swarm呢?那是因为kubernetes的这些优点:
技术 | 应用场景 | 资源占用比 |
---|---|---|
docker | 单机部署简单应用 | 低 |
Docker-Compose | 单机/少数机器部署应用 | 低 |
kubernetes | 集群部署高可用应用 | 低 |
什么是配置中心
在微服务架构中,当系统从一个单体应用,被拆分成分布式系统上一个个服务节点后,配置文件也必须跟着迁移(分割),这样配置就分散了,不仅如此,分散中还包含着冗余。在这种背景下中心化的配置服务即配置中心应运而生。
配置中心的服务流程如下:
一个合格的配置中心需要满足如下特性:
最基础的,Kubernetes可以在物理或虚拟机集群上调度和运行应用程序容器.然而,Kubernetes还允许开发人员从物理和虚拟机’脱离’,从以主机为中心的基础架构转移到以容器为中心的基础架构,这样可以提供容器固有的全部优点和益处。
Kubernetes满足了生产中运行应用程序的许多常见的需求:
Master节点上运行的负责集群管理调度的一组进程
Kubernetes API Server(kube-apiserver):是Kubernetes里所有资源的增删改查等操作的唯一入口,是集群控制的入口进程。
Kubernetes Controller Manager(kube-controller-manager):Kubernetes里所有资源对象的自动化控制中心
Kubernetes Scheduler(kube-scheduler):负责资源调度
Node节点上运行的负责资源创建、通信、负载均衡、Docker创建与管理的一组进程
kubelet:与Master节点密切协作实现集群管理,负责Pod对应的容器的创建、启停等任务;
kube-proxy:实现服务间的通信与负载均衡;
Docker Engine(Docker):负责本机Docker容器的创建于管理等。
Pod和Service是Kubernetes中较为核心的两个概念。
pod可以理解为容器的外壳,它为容器做了一层抽象的封装,pod里面运行容器,pod的特点是可以将多个容器加入到同一个网络名称空间中。同一个pod可以共享储存卷。
一个pod上无论是有一个容器还是有多个容器,一旦将此pod调度到某个node上运行时,这一个pod内的所有容器只能运行在同一个node上。
node是kubernetes集群中的工作节点,就是负责工作的。
node可以是任何形式的计算设备,能装k8s的集群代理程序,它都可以作为整个k8s集群一个成员。
当大量的pod运行在一个集群中时,怎么批量进行管理呢?想只控制一部分的pod时又该如何?如何挑选和检测这些pod?有人会想到通过名称来识别容器,但是pod是随时删除和创建的,名称也会随着pod的删除和创建而发生改变。这样我们就给一类的pod进行分组,就是在创建pod时为其附上app的key的一个键值对,这样我们进行批量操作时可以通过检查pod中是否存在app的key,来实现对多个pod的控制,这样就会有一个新的问题了,怎么实现对多个标签的管理呢?这里我们就可以通过标签选择器组件来实现。
标签选择器就是一种根据标签来过滤符合条件的资源对象的机制。
Pod是Kubernetes里最小的资源管理对象,Pod运行在Node节点上,容器运行在Pod里,Pod里包含一个根容器和一个或多个业务容器,一般来说,紧密相关联的几个业务进程会被以不同的容器镜像的形式放在同一个Pod里。
Node、Pod、容器间关系
Pod有两种类型,普通的Pod和静态Pod,静态Pod存放在某个具体的Node上的一个具体文件中,且只在此Node上运行;普通的Pod一旦创建,就会被放入到etcd存储中,随后会被Master节点调度到某个具体的Node上进行绑定,然后被该Node上的kubelet进程实例化为一组相关的Docker容器并启动起来。
Service简称(Svc)
Svc就是一个“微服务”,Svc定义了一个服务的访问入口地址,前端应用(Pod)通过这个入口地址访问其背后的一组由Pod副本组成的集群实例。Service与其后端的Pod之间通过Label Selector实现“无缝对接”,Replication Controller(简称RC)的作用是通过满足要求的Pod副本数,保证Svc的服务能力和服务质量始终处于预期的标准。
这里我们思考一个问题就是后端的多个Pod副本实例保证Svc的服务能力,为前端提供服务,前端是如何访问后端的多个Pod的呢?那就的用到负载均衡了。
master节点在kubernetes中称为Kubernetes控制平面
master节点负责整个集群的管理和控制,基本上Kubernetes所有的控制命令都发给它。执行的命令一般都是在Master上执行,Master节点一般是独立运行在一台主机上,并且由于Master节点至关重要,一旦宕机会导致整个集群的失效不可用,这样我们可以对master节点做高可用,来保证服务的正常运行。
node节点
除了Master节点,还有其他的节点被称为node都是负责实际工作的,master只是用来发送命令的,就类似于saltstack上的master端用来发送命令,正真工作的是minion端。
Kubernetes Master是集群的主要控制单元,用于管理其工作负载并指导整个系统的通信。Kubernetes控制平面由各自的进程组成,每个组件都可以在单个主节点上运行,也可以在支持high-availability clusters的多个主节点上运行。
组件名称 | 作用 |
---|---|
etcd | 保存整个集群的状态; |
apiserver | 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制; |
controller manager | 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等; |
scheduler | 负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上; |
kubelet | 负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理; |
Container runtime | 负责镜像管理以及Pod和容器的真正运行(CRI); |
kube-proxy | 负责为Service提供cluster内部的服务发现和负载均衡; |
其他组件
组件名称 | 作用 |
---|---|
kube-dns | 负责为整个集群提供DNS服务 |
Ingress Controller | 为服务提供外网入口 |
Heapster | 提供资源监控 |
Dashboard | 提供GUI |
Federation | 提供跨可用区的集群 |
Fluentd-elasticsearch | 提供集群日志采集、存储与查询 |
master:
node(工作节点):
核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)
管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)
接口层:kubectl命令行工具、客户端SDK以及集群联邦
生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
– Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、 FaaS、OTS应用、ChatOps等
– Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等
kubelet
创建的所有对象 - pod,ReplicationController,服务和私密凭据等,需要以持久化方式存储到某个地方,这样它们的manifest在API服务器重启和失败的时候才不会丢失.为此,Kubernetes使用了etcd
etcd是一个响应快,分布式,一致的Key-value存储.因为它是分布式的,故可以运行多个etcd实例来获取高可用性和更好的性能
唯一能直接和etcd通信的是Kubernetes的API服务器.所有其他组件通过API服务器间接地读取,写入数据到etcd.这带来一些好处,其中之一就是增强乐观锁系统,验证系统的健壮性;并且,通过把实际存储机制从其他组件抽离,未来替换起来也更容易.值得强调的是,etcd是Kubernetes存储集群状态和元数据的唯一的地方
Kubernetes API服务器作为中心组件,其他组件或者客户端都会去调用它.以RESTful API的形式提供了可以查询,修改集群状态的CRUD(Create,Read,Update,Delete)接口.他将状态存储到etcd中
API服务器除了提供一种一致的方式将对象存储到etcd,也对这些对象做校验,这样客户端就无法存入非法的对象(直接写入存储的话是有可能的).除了检验,还会处理乐观锁,这样对于并发更新的情况,对对象做更改就不会被其他客户端覆盖
API服务器的客户端之一就是使用的命令行工具kubectl,也支持监听资源
通常不会去指定pod应该运行在哪个集群节点上,这项工作交给调度器.宏观来看,调度器的操作比较简单.就是利用API服务器的监听机制等待新创建的pod,然后给每个新的,没有节点集的pod分配节点
调度器不会命令选中的节点去运行pod.调度器做的就是通过API服务器更新pod的定义.然后API服务器再去通知Kubelet该pod已经被调度过.当目标节点上的Kubelet发现该pod被调度到本节点,他就会创建并且运行pod的容器
尽管宏观上调度的过程看起来比较简单,但实际上为pod选择最佳节点的任务并不简单.当然,最简单的调度方式是不关心节点上已经运行的pod,随机选择一个节点.另一方面,调度器可以利用高级技术,例如机器学习,来预测接下来几分钟或几小时哪种类型的pod将会被调度,然后以最大的硬件利用率,无须重新调度已运行pod的方式来调度.Kubernetes的默认调度器实现方式处于最简单和最复杂程度之间
API服务器只做了存储资源到etcd和通知客户端有变更的工作.调度器则只是给pod分配节点,所以需要有活跃的组件确保系统真实状态朝API服务器定义的期望的状态收敛.这个工作由控制器管理器里的控制器来实现
单个控制器,管理器进程当前组合了多个执行不同非冲突任务的控制器.这些控制器最终会被分解到不同的进程,如果需要的话,我们能够用自定义实现替换它们每一个
Kubelet就是负责所有运行在工作节点上内容的组件.它第一个任务就是在API服务器中创建一个Node资源来注册该节点.然后需要持续监控API服务器是否把该节点分配给pod,然后启动pod容器.具体实现方式是告知配置好的容器进行时来从特定容器镜像运行容器,Kubelet随后持续监控运行的容器,向API服务器报告他们的状态,事件和资源消耗,负责管理pods和他们的容器,images镜像,卷组。
Kubelet也是运行容器存活探针的组件,当探针报错时它会重启容器.最后一点,当pod从API服务器删除时,Kubelet终止容器,并通知服务器pod已经被终止了
每个工作节点都会运行kube-proxy,用于确保客户端可以通过Kubernetes API连接到你定义的服务
kube-proxy确保对服务IP和端口的连接最终能到达支持服务的某个pod处.如果有多个pod支撑一个服务,那么代理会发挥对pod的负载均衡作用
集群中的所有pod默认配置使用集群内部DNS服务器.这使得pod能够轻松地通过名称查询到服务,甚至是无头服务pod的IP地址
DNS服务pod通过kube-dns服务对外暴露,使得该pod能够像其他pod一样在集群中移动.服务的IP地址在集群每个容器的/etc/reslv.conf文件的nameserver中定义.kube-dns pod利用API服务器的监控机制来订阅Service和Endpoint的变动,以及DNS记录的变更,是的其客户端总是能够获取到最新的DNS信息.客观的说,在Service和Endpoint资源发生变化到DNS pod收到订阅通知时间点之间,DNS记录可能会无效
Ingress控制器运行一个反向代理服务器,根据集群中定义的Ingress,service以及Endpoint资源来配置该控制器.所以需要订阅这些资源,然后每次其中一个发生变化则更新代理服务器的配置