Kubernetes(通常写成“k8s”)是最开始由google设计开发最后贡献给Cloud Native Computing Foundation的开源容器集群管理项目。它的设计目标是在主机集群之间提供一个能够自动化部署、可拓展、应用容器可运营的平台。Kubernetes通常结合docker容器工具工作,并且整合多个运行着docker容器的主机集群。
Kubernetes( 来自希腊语κυβερνήτης:,意思为 “操舵员” 或者 “飞行员”)由Joe Beda, Brendan Burns 和Craig McLuckie建立,并在2014年被google公司首次对外公布。它的发展和设计受到google的Borg系统的严重影响。Kubernetes项目的许多主要贡献者来自Borg项目。在Google内部Kubernetes最开始的名字叫Serven of Nine,引用了电影“星际迷航”中通常被认为“更加友好”的“博格人”这个角色。由于google律师的反对,它的名字被重命名为Kubernetes。从Kubernetes的logo上面那车轮上的七个幅条就能在一定程度上推断出Kubernets最开始的名字是什么。
2015年七月21日Kubernetes发布了v1.0版本。随着Kubernetes v1.0版本的发布,Google和Linux基金会合作成立Cloud Native Computing Foundation(CNCF)并提议使Kubernetes成为种子技术。
Kubernetes还被RedHat使用于OpenShift产品。
Kubernetes经过这几年的快速发展,形成了一个大的生态环境,Google在2014年将Kubernetes作为开源项目。
Kubernetes的关键特性包括:
Kubernetes定义了一套堆积木,这些堆积木统一提供部署、维护和扩展应用的机制。构成Kubernetes的这些组件让Kubernetes变得一个松耦合可延伸的,因此它能满足各种不同的工作负载。Kubernetes的延展性在很大程度上是由Kubernetes的API提供的,这些API被运行在Kubernetes的内部组件、延伸组件和容器使用。
Kubernetes中的基本调度单位叫“pod”。它增加了更高层的抽象来容纳各种组件。一个pod由一个或者多个容器组成,这些容器能够部署在同一台物理主机上面,并能够共享资源。Kubernetes中集群内部的每一个pod被指定了唯一的IP地址,用户程序可以通过相应的端口号无冲突地连接各个pod。pod能够定义一个卷(volume),比如一个本地磁盘目录或者一个网络磁盘,然后把它暴露给pod中的容器。用户可以通过Kubernetes API手动管理pod,或者把管理工作交给一个管理器。
Kubernetes可以让客户端(用户或者内部组件)把被称之为标签的键值对
依附在系统的任何API对象上,比如pods和“nodes”。相应地,”标签选择器”是针对标签的查询,这些标签用于解决匹配对象问题。
标签和选择器是Kubernetes中的主要分组机制,用来决定哪个操作应用于哪个组件。
比如,如果一个应用的pod有一个系统标签为:tier
(“front-end
“, “back-end
“,) 和 release_track
(“canary
“, “production
“), 然后所有 “back-end
” 和”canary
“节点 上的操作都可以使用如下所示的标签选择器:
tier=back-end AND release_track=canary
一个控制器是一个调节回路,通过管理一系列pod来驱动实际的集群状态变成所需的集群状态。一种控制器叫”复制控制器“,通过运行指定数目的跨集群的pod副本来进行复制和扩展操作。如果底层的节点失败了,它还能处理和创建用于替换的pod。其他的控制器是核心Kubernetes系统的一部分,包括一个运行在所有机器(或者所有机器的一些子集)但恰好一个pod上的”DaemonSet“控制器,以及一个运行pod直到结束的”Job“控制器(比如,作为批作业的一部分)。控制器所管理的那一系列pod由定义在控制器里的部分标签选择器决定。
一个Kubernetes服务是一系列工作在一起的pod,比如多层应用中其中的一层。这一系列pod构成了由标签选择器所定义的一个服务。Kubernetes提供了服务发现和请求路由的功能。请求路由是通过分配固定IP地址和DNS名字给服务
。默认的,一个服务会在一个集群内暴露(比如,后台的pod会被分到一个服务中,来自前端的pods负载平衡他们之间的请求),但是,它也可以在一个集群外暴露(比如,为客户端访问前端的pod)。
Kubernetes属于主从分布式架构,主要由Master Node和Worker Node组成,以及包括客户端命令行工具kubectl和其它附加项。
API Server主要用来处理REST的操作,确保它们生效,并执行相关业务逻辑,以及更新etcd(或者其他存储)中的相关对象。API Server是所有REST命令的入口,它的相关结果状态将被保存在etcd(或其他存储)中。API Server的基本功能包括:
另外,API Server也作为集群的网关。默认情况,客户端通过API Server对集群进行访问,客户端需要通过认证,并使用API Server作为访问Node和Pod(以及service)的堡垒和代理/通道。
Kubernetes默认使用etcd作为集群整体存储,当然也可以使用其它的技术。etcd是一个简单的、分布式的、一致的key-value存储,主要被用来共享配置和服务发现。etcd提供了一个CRUD操作的REST API,以及提供了作为注册的接口,以监控指定的Node。集群的所有状态都存储在etcd实例中,并具有监控的能力,因此当etcd中的信息发生变化时,就能够快速的通知集群中相关的组件。
Controller-Manager Serve用于执行大部分的集群层次的功能,它既执行生命周期功能(例如:命名空间创建和生命周期、事件垃圾收集、已终止垃圾收集、级联删除垃圾收集、node垃圾收集),也执行API业务逻辑(例如:pod的弹性扩容)。控制管理提供自愈能力、扩容、应用生命周期管理、服务发现、路由、服务绑定和提供。Kubernetes默认提供Replication Controller、Node Controller、Namespace Controller、Service Controller、Endpoints Controller、Persistent Controller、DaemonSet Controller等控制器。
scheduler组件为容器自动选择运行的主机。依据请求资源的可用性,服务请求的质量等约束条件,scheduler监控未绑定的pod,并将其绑定至特定的node节点。Kubernetes也支持用户自己提供的调度器,Scheduler负责根据调度策略自动将Pod部署到合适Node中,调度策略分为预选策略和优选策略,Pod的整个调度过程分为两步:
1)预选Node:遍历集群中所有的Node,按照具体的预选策略筛选出符合要求的Node列表。如没有Node符合预选策略规则,该Pod就会被挂起,直到集群中出现符合要求的Node。
2)优选Node:预选Node列表的基础上,按照优选策略为待选的Node进行打分和排序,从中获取最优Node。
Kubelet是Kubernetes中最主要的控制器,它是Pod和Node API的主要实现者,Kubelet负责驱动容器执行层。在Kubernetes中,应用容器彼此是隔离的,并且与运行其的主机也是隔离的,这是对应用进行独立解耦管理的关键点。
在Kubernets中,Pod作为基本的执行单元,它可以拥有多个容器和存储数据卷,能够方便在每个容器中打包一个单一的应用,从而解耦了应用构建时和部署时的所关心的事项,已经能够方便在物理机/虚拟机之间进行迁移。API准入控制可以拒绝或者Pod,或者为Pod添加额外的调度约束,但是Kubelet才是Pod是否能够运行在特定Node上的最终裁决者,而不是scheduler或者DaemonSet。kubelet默认情况使用cAdvisor进行资源监控。负责管理Pod、容器、镜像、数据卷等,实现集群对节点的管理,并将容器的运行状态汇报给Kubernetes API Server。
每一个Node都会运行一个Container Runtime,其负责下载镜像和运行容器。Kubernetes本身并不停容器运行时环境,但提供了接口,可以插入所选择的容器运行时环境。kubelet使用Unix socket之上的gRPC框架与容器运行时进行通信,kubelet作为客户端,而CRI shim作为服务器。
protocol buffers API提供两个gRPC服务,ImageService和RuntimeService。ImageService提供拉取、查看、和移除镜像的RPC。RuntimeSerivce则提供管理Pods和容器生命周期管理的RPC,以及与容器进行交互(exec/attach/port-forward)。容器运行时能够同时管理镜像和容器(例如:Docker和Rkt),并且可以通过同一个套接字提供这两种服务。在Kubelet中,这个套接字通过–container-runtime-endpoint和–image-service-endpoint字段进行设置。Kubernetes CRI支持的容器运行时包括docker、rkt、cri-o、frankti、kata-containers和clear-containers等。
基于一种公共访问策略(例如:负载均衡),服务提供了一种访问一群pod的途径。此方式通过创建一个虚拟的IP来实现,客户端能够访问此IP,并能够将服务透明的代理至Pod。每一个Node都会运行一个kube-proxy,kube proxy通过iptables规则引导访问至服务IP,并将重定向至正确的后端应用,通过这种方式kube-proxy提供了一个高可用的负载均衡解决方案。服务发现主要通过DNS实现。
在Kubernetes中,kube proxy负责为Pod创建代理服务;引到访问至服务;并实现服务到Pod的路由和转发,以及通过应用的负载均衡。
kubectl是Kubernetes集群的命令行接口。运行kubectl命令的语法如下所示:
$ kubectl [command] [TYPE] [NAME] [flags]
这里的command,TYPE、NAME和flags为:
$ kubectl get pod pod1 $ kubectl get pods pod1 $ kubectl get po pod1
$kubectl get pods
另外,可以通过运行kubectl help命令获取更多的信息。
在Kunbernetes中可以以附加项的方式扩展Kubernetes的功能,目前主要有网络、服务发现和可视化这三大类的附加项,下面是可用的一些附加项: