K8S是什么?

        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中比较重要的参数有:

  • replicas:我们所期待的容器副本数
  • selector:标签选择器,k8s通过查询具有此label对的容器个数来确定进行扩容或缩容操作
  • label:当k8s进行扩容时,会将启动的容器给打上label标签。一般来说,此处label是selector的超集,也就是说,selector值必定在label中出现,否则k8s一直处于创建状态,因为k8s每次只查询具有selector值的容器的个数,而新启动的容器压根不具有label标签。
  • template:k8s根据容器模版启动容器

       当我们创建好一个Deployment并将之投放到k8s中后,k8s会按照我们的参数,将集群中目标容器的个数起到我们所期望的个数replicas。如果当前容器少于replicas,则k8s会按照Deployment中定义好的容器模版template去启动容器,并按照我们设置好的标签给pod打上label,方便service进行管理。

       因此我们通过定义Deployment实现了Pod的创建过程与副本数量的自动控制。


(13)IP

此处的IP包含以下3个类型: 

  • Node IP:Node节点的物理网卡的IP地址,是一个真实存在的网络,所有属于这个网络的主机可以直接相互通信,不管这些主机是否属于同一个K8s集群。
  • Pod IP:Pod的IP地址,是一个虚拟的IP地址,通常是一个虚拟二层网络。所以当一个Pod访问另外一个Pod时,就是通过Pod IP所在的虚拟二层网络进行通信的,而真实的TCP/IP流量则是通过Node IP所在的物理网卡流出的。

Cluster IP:Service的ip地址,也是一个虚拟的IP地址,属于K8s集群内部,在外界是无法被ping通的。倘若我们需要访问某个Service所代表的的服务,K8s提供了这样的解决方案。首先用户去访问集群外部的一个负载均衡器,负载均衡器依据负载变化转发请求到相应的某一个Node上的某一个端口上,然后再将请求转发至注册到该端口的Service上,Service再去请求背后的Pod集群实例。


K8S架构

架构图1

架构图2

Kubernetes属于主从分布式架构,主要由Master Node和Worker Node组成,以及包括客户端命令行工具kubectl和其它附加项。

  • Master Node:作为控制节点,对集群进行调度管理;Master Node由API Server、Scheduler、Cluster State Store和Controller-Manger Server所组成;
  • Worker Node:作为真正的工作节点,运行业务应用的容器;Worker Node包含kubelet、kube proxy和Container Runtime;
  • kubectl:用于通过命令行与API Server进行交互,而对Kubernetes进行操作,实现在集群中进行各种资源的增删改查等操作;
  • Add-on:是对Kubernetes核心功能的扩展,例如增加网络和网络策略等能力。
  • repliceation 用于伸缩副本数量
  • endpoint 用于管理网络请求

k8s简要流程图:

  1. 用户提交创建Pod的请求,可以通过API Server的REST API ,也可用Kubectl命令行工具,支持Json和Yaml两种格式;
  2. API Server 处理创建请求,存储Pod数据到Etcd;
  3. 接着API Server通知Schedule,Schedule尝试为Pod绑定Node,会选择一个最优的Node,并将此Node返回给API Server;
  4. API Server将该返回结果存储至Etcd中。并通知Node节点上的Kubelet。
  5.  kubelet根据调度结果执行Pod创建操作,并通知API Server绑定成功。
  6. API Server将绑定结果存储至Etcd中。

附官网讲解:

Kubernetes设计架构

Kubernetes节点

在这张系统架构图中,我们把服务分为运行在工作节点上的服务和组成集群级别控制板的服务。

Kubernetes节点有运行应用容器必备的服务,而这些都是受Master的控制。

每次个节点上当然都要运行Docker。Docker来负责所有具体的映像下载和容器运行。

Kubernetes主要由以下几个核心组件组成:

  • etcd保存了整个集群的状态;
  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  • kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;

除了核心组件,还有一些推荐的Add-ons:

  • kube-dns负责为整个集群提供DNS服务
  • Ingress Controller为服务提供外网入口
  • Heapster提供资源监控
  • Dashboard提供GUI
  • Federation提供跨可用区的集群
  • Fluentd-elasticsearch提供集群日志采集、存储与查询

用思维导图助于记忆:

分层架构

Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示

  • 核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
  • 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)
  • 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)
  • 接口层:kubectl命令行工具、客户端SDK以及集群联邦
  • 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
    • Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等
    • Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

kubelet

kubelet负责管理pods和它们上面的容器,images镜像、volumes、etc。

kube-proxy

每一个节点也运行一个简单的网络***和负载均衡(详见services FAQ )(PS:官方 英文)。 正如Kubernetes API里面定义的这些服务(详见the services doc)(PS:官方 英文)也可以在各种终端中以轮询的方式做一些简单的TCP和UDP传输。

服务端点目前是通过DNS或者环境变量( Docker-links-compatible 和 Kubernetes{FOO}_SERVICE_HOST 及 {FOO}_SERVICE_PORT 变量都支持)。这些变量由服务***所管理的端口来解析。

Kubernetes控制面板

Kubernetes控制面板可以分为多个部分。目前它们都运行在一个master 节点,然而为了达到高可用性,这需要改变。不同部分一起协作提供一个统一的关于集群的视图。

etcd

所有master的持续状态都存在etcd的一个实例中。这可以很好地存储配置数据。因为有watch(观察者)的支持,各部件协调中的改变可以很快被察觉。

Kubernetes API Server

API服务提供Kubernetes API (PS:官方 英文)的服务。这个服务试图通过把所有或者大部分的业务逻辑放到不两只的部件中从而使其具有CRUD特性。它主要处理REST操作,在etcd中验证更新这些对象(并最终存储)。

Scheduler

调度器把未调度的pod通过binding api绑定到节点上。调度器是可插拔的,并且我们期待支持多集群的调度,未来甚至希望可以支持用户自定义的调度器。

Kubernetes控制管理服务器

所有其它的集群级别的功能目前都是由控制管理器所负责。例如,端点对象是被端点控制器来创建和更新。这些最终可以被分隔成不同的部件来让它们独自的可插拔。

replicationcontroller(PS:官方 英文)是一种建立于简单的 pod API之上的一种机制。一旦实现,我们最终计划把这变成一种通用的插件机制。