K8S是Kubernetes的缩写(首字母K+中间8个字母+末尾字母S),是一个高度自动化的资源控制系统,它通过跟踪配置库里保存的“资源期望状态”与当前环境的“实际资源状态”之间的差异来实现自动控制。例如在某节点宕机时,自动迁移服务单元到新的节点上。
(1)镜像
此处的镜像和容器都是docker中的概念,不过这里的镜像与我们常用的虚拟机中的镜像的含义并没有多大区别,只是这里的镜像适用于docker中而已。我们可以使用(docker pull 镜像名称)的命令拉取官方或其他开发者打包好的镜像。
(2)容器
容器可以理解为运行着的镜像,是一个拥有自定义端口映射、挂载卷、环境变量的,可以对外提供服务的,为docker所管理的应用实例。
(3)Pod
Pod是K8S管理的最小运行单元,多个Pod组成一个Node。一个Pod中存在一个Pause容器和多个用户容器或称为业务容器。同一个Pod中的业务容器共享Pause容器的网络栈与Volume挂载卷。
我们大可以将一组关系密切且沟通频繁的容器放到一个Pod中,从而会使得它们之间的通信和数据交换显得更加高效。
Pod的组成如下:
(4)Label
每一个Pod都会有一个或多个的Label(标签),但此标签并不是全局唯一的,多个Pod可以被指定相同的标签。Label在Pod的创建时期就被指定在Pod上,仅仅是一个名字或标识而已,用来标识该Pod的作用,或者说提供什么服务的。比如给某一个Pod设定name=mysql,则标识该pod对外提供mysql服务。
Label的选择范围如下:
(5)Service
Service字面意思是服务。在K8S外部看来,就是一个具有唯一ip+port的服务。而在K8S内部,这个服务是由多个具有相同标签的Pod构成,一致对外提供标签所代表的服务。当我们请求此ip+port时,内部的负载均衡和故障恢复机制会使得此服务具有高可用性。
Service、Pod、RC(其实和Deployment没有区别)三者的联系如下:
Service为服务提供了一个访问的入口地址,前端的Pod通过这个入口地址访问其后端的Pod实例。Service与Pod的关联则是通过Label Selector标签选择器来实现对接的。replicationController(或者Deployment)则是保证Service背后的Pod服务能力始终处于预期的标准。
其实每个Pod都要一个独立的EndPoint(ip+port)地址以供外界访问,不过现在构成了集群,则需要一个统一的地址对外提供服务。此外Pod的EndPoint地址会随着Pod的销毁而重新改变,而且Pod的销毁是很频繁的。Service与Pod不同,Service地址在其整个生命周期内,它的地址不会发生任何改变。那么Service在这里也可以充当负载均衡器的角色,外界先访问Service的地址,然后Service再依据负载均衡算法将请求转发到背后的某一个Pod中。
(6)资源对象
K8S中大部分概念,例如Node、Pod、Service都可以看做“资源对象”,可以通过K8S提供的kubelet工具或api接口来实现对这些资源的CURD操作,并将这些资源持久化在etcd上。
(7)节点
在集群管理方面,K8S将某一个集群划分为一个(或多个)Master节点与多个Node节点。不管时Master节点,还是Node节点,他们通常占用一个物理机或虚拟机。
(8)Node节点
Node是集群的工作节点,运行真正的应用程序。每一个Node上都运行着K8S的kubelet、kube-proxy与Docker engine服务进程,这些服务进程负责Pod的创建、启动、监控、重启、销毁以及实现软件模式的负载均衡器。当某个Pod所在的Node宕机后,其上的容器会被转移到健康的Pod中。
[1] kubelet
接受Master节点的指令,实现对Pod的创建、启动与停止。
[2] kube-proxy
实现Service的通信与负载均衡,将到达Service上的请求按照某种策略转发到某一个Pod上。
[3] Docker engine
Docker引擎,负责对容器的管理。
(9)Node注册与健康检查
在某一个集群中,Node节点应该是可以动态添加的。当某个Node需要加入到集群中时,Node节点的kubelet进程会向Master节点注册自己。一旦该Node成功加入集群时,在这之后,需要定时的向Master节点汇报自身的资源情况,例如CPU、内存、流量的使用情况,以及哪些Pod在运行。这样Master节点就会知道每一个Node节点的资源使用情况,从而可以实现更高效的负载均衡策略。当某个Node在规定上报周期内不上报时,Master会认为该Node出现异常情况,将该Node上一次汇报中的Pod迁移到其他Node中。
(10)Master节点
在Master节点上运行着有关集群管理的一组进程,包括kube-apiserver、kube-controller-manager、kube-scheduler与etcd server。Master节点是其所在集群的控制节点,相当于集群首脑,所有的集群控制命令全部发给它,再由它负责具体的执行流程。
[1] kube-apiserver
从字面上看,这个进程是api服务器,其提供了对资源对象进行CURD的入口,是集群内各个组件进行通信的中枢。
[2] kube-controller-manager
K8S资源对象的自动化控制中心,保证集群中的资源处于期望状态。比如,保证当前集群内某个label下的Pod数量符合我们所定义的数量。
[3] kube-scheduler
负责调度Pod的进程,将Pod绑定到某一个Node上。
[4] etcd server
负责将该集群下的资源对象持久化到etcd中。
Master和组件的关系图
容器、Pod、Node、Master三者的关系如下:
(11)Namespace
Namespace命名空间,一个k8s集群中,会有多个命名空间,这些命名空间将资源隔离开来。大多数k8s会有一个默认的命名空间,即default。我们在创建pod时,若不指定命名空间,则会在default中创建;在查询pod时,如果也没有指定命名空间,则也会在default中查找。更多详细的解释参考 Kubernetes最佳实践之:命名空间(Namespace)
(12)Deployment
Deployment可以被描述为一个yaml格式的部署文件,通常被用来告知k8s集群,我们需要什么容器,容器的个数,容器基于的镜像,容器的标签等。Deployment中比较重要的参数有:
当我们创建好一个Deployment并将之投放到k8s中后,k8s会按照我们的参数,将集群中目标容器的个数起到我们所期望的个数replicas。如果当前容器少于replicas,则k8s会按照Deployment中定义好的容器模版template去启动容器,并按照我们设置好的标签给pod打上label,方便service进行管理。
因此我们通过定义Deployment实现了Pod的创建过程与副本数量的自动控制。
(13)IP
此处的IP包含以下3个类型:
Cluster IP:Service的ip地址,也是一个虚拟的IP地址,属于K8s集群内部,在外界是无法被ping通的。倘若我们需要访问某个Service所代表的的服务,K8s提供了这样的解决方案。首先用户去访问集群外部的一个负载均衡器,负载均衡器依据负载变化转发请求到相应的某一个Node上的某一个端口上,然后再将请求转发至注册到该端口的Service上,Service再去请求背后的Pod集群实例。
架构图1
架构图2
Kubernetes属于主从分布式架构,主要由Master Node和Worker Node组成,以及包括客户端命令行工具kubectl和其它附加项。
k8s简要流程图:
附官网讲解:
在这张系统架构图中,我们把服务分为运行在工作节点上的服务和组成集群级别控制板的服务。
Kubernetes节点有运行应用容器必备的服务,而这些都是受Master的控制。
每次个节点上当然都要运行Docker。Docker来负责所有具体的映像下载和容器运行。
Kubernetes主要由以下几个核心组件组成:
除了核心组件,还有一些推荐的Add-ons:
用思维导图助于记忆:
Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示
kubelet负责管理pods和它们上面的容器,images镜像、volumes、etc。
每一个节点也运行一个简单的网络代理和负载均衡(详见services FAQ )(PS:官方 英文)。 正如Kubernetes API里面定义的这些服务(详见the services doc)(PS:官方 英文)也可以在各种终端中以轮询的方式做一些简单的TCP和UDP传输。
服务端点目前是通过DNS或者环境变量( Docker-links-compatible 和 Kubernetes{FOO}_SERVICE_HOST 及 {FOO}_SERVICE_PORT 变量都支持)。这些变量由服务代理所管理的端口来解析。
Kubernetes控制面板可以分为多个部分。目前它们都运行在一个master 节点,然而为了达到高可用性,这需要改变。不同部分一起协作提供一个统一的关于集群的视图。
所有master的持续状态都存在etcd的一个实例中。这可以很好地存储配置数据。因为有watch(观察者)的支持,各部件协调中的改变可以很快被察觉。
API服务提供Kubernetes API (PS:官方 英文)的服务。这个服务试图通过把所有或者大部分的业务逻辑放到不两只的部件中从而使其具有CRUD特性。它主要处理REST操作,在etcd中验证更新这些对象(并最终存储)。
调度器把未调度的pod通过binding api绑定到节点上。调度器是可插拔的,并且我们期待支持多集群的调度,未来甚至希望可以支持用户自定义的调度器。
所有其它的集群级别的功能目前都是由控制管理器所负责。例如,端点对象是被端点控制器来创建和更新。这些最终可以被分隔成不同的部件来让它们独自的可插拔。
replicationcontroller(PS:官方 英文)是一种建立于简单的 pod API之上的一种机制。一旦实现,我们最终计划把这变成一种通用的插件机制。