一、Kubernetes整体架构
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核心功能的扩展,例如增加网络和网络策略等能力。
二、Kubernetes基本组件
Kubernetes是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务。通过Kubernetes能够进行应用的自动化部署和扩缩容。
2.1Master Node(主节点):
2.1.1 API Server(API服务器)
APIServer负责对外提供RESTful的Kubernetes API服务,它是系统管理指令的统一入口,任何对资源进行增删改查的操作都要交给APIServer处理后再提交给etcd。
如架构图中所示,kubectl(Kubernetes提供的客户端工具,该工具内部就是对Kubernetes API的调用)是直接和APIServer交互的。
2.1.2 Cluster state store(集群状态存储)
Kubernetes默认使用etcd作为集群整体存储,etcd是一个简单的、分布式的、一致的key-value存储,Kubernetes使用它来存储各个资源的状态。
2.1.3 Controller-Manager Server(控制管理服务器)
如果说APIServer做的是“前台”的工作的话,那controller manager就是负责“后台”的。
每个资源一般都对应有一个控制器,而controller manager就是负责管理这些控制器的。
比如我们通过APIServer创建一个pod,当这个pod创建成功后,APIServer的任务就算完成了。而后面保证Pod的状态始终和我们预期的一样的重任就由controller manager去保证了。
2.1.4 Scheduler(调度器)
scheduler的职责很明确,就是负责调度pod到合适的Node上。如果把scheduler看成一个黑匣子,那么它的输入是pod和由多个Node组成的列表,输出是Pod和一个Node的绑定,即将这个pod部署到这个Node上。Kubernetes目前提供了调度算法,但是同样也保留了接口,用户可以根据自己的需求定义自己的调度算法。调度策略分为预选策略和优选策略,Pod的整个调度过程分为两步:
1)预选Node:遍历集群中所有的Node,按照具体的预选策略筛选出符合要求的Node列表。如没有Node符合预选策略规则,该Pod就会被挂起,直到集群中出现符合要求的Node。
2)优选Node:预选Node列表的基础上,按照优选策略为待选的Node进行打分和排序,从中获取最优Node。
2.1.5 仪表板(Dashboard)(可选)
Kubernetes提供网页UI来简化用户与API服务器(API Server)的交互。
2.2 Work Node(从节点)
2.2.1 Kubelet
Kubelet是Kubernetes中最主要的控制器,它是Pod和Node API的主要实现者,Kubelet负责驱动容器执行层。
在Kubernets中,Pod作为基本的执行单元,它可以拥有多个容器和存储数据卷,能够方便在每个容器中打包一个单一的应用。Kubelet是Master在每个Node节点上面的agent,是Node节点上面最重要的模块,它负责维护和管理该Node上面的所有容器,但是如果容器不是通过Kubernetes创建的,它并不会管理。本质上,它负责使Pod得运行状态与期望的状态一致
2.2.2 Container Runtime(容器运行时)
runtime指的是容器运行环境,目前Kubernetes支持docker和rkt两种容器。
2.2.3 Kube proxy
该模块实现了Kubernetes中的服务发现和反向代理功能。
反向代理方面:kube-proxy支持TCP和UDP连接转发,默认基于Round Robin算法将客户端流量转发到与service对应的一组后端pod。
服务发现方面,kube-proxy使用etcd的watch机制,监控集群中service和endpoint对象数据的动态变化,并且维护一个service到endpoint的映射关系,从而保证了后端pod的IP变化不会对访问者造成影响。另外kube-proxy还支持session affinity。
2.3 Kubectl
kubectl是Kubernetes集群的命令行接口。比如:
$ kubectl [command] [TYPE] [NAME] [flags]
comand:指定要对资源执行的操作,例如create、get、describe和delete
TYPE:指定资源类型,资源类型是大小写敏感的,开发者能够以单数、复数和缩略的形式。例如:
$ kubectl get pod pod1
$ kubectl get pods pod1
$ kubectl get po pod1
NAME:指定资源的名称,名称也大小写敏感的。如果省略名称,则会显示所有的资源,例如:
$kubectl get pods
flags:指定可选的参数。例如,可以使用-s或者–server参数指定Kubernetes API server的地址和端口。
三、Kubernetes术语说明
Pod
Pod安排在节点上,包含一组容器和存储卷。同一个Pod里的容器共享同一个网络命名空间,可以使用localhost互相通信。
Pod是短暂的,不是持续性实体。那么:
- 怎样才能持久化容器数据,使其能够跨重启而存在呢? Kubernetes支持卷的概念,因此可以使用持久化的卷类型。
- 是否能手动创建Pod,如果想要创建同一个容器的多份拷贝,需要一个个分别创建出来么?以手动创建单个Pod,也可以使用Replication Controller使用Pod模板创建出多份拷贝。
- 重启时,IP地址可能会改变,怎样才能从前端容器正确可靠地指向后台容器呢?使用Service。
Lable
正如上图所示,部分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应用到上面。
Replication Controller
对应上面的问题:“是否能手动创建Pod,如果想要创建同一个容器的多份拷贝,需要一个个分别创建出来么?能否将Pods划到逻辑组里?”
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的标签。
Service
假设现在已经创建了Pod副本,那么在这些副本上如何均衡负载呢?我们需要的是Service。
对应上面的问题:“如果Pods是短暂的,那么重启时IP地址可能会改变,怎么才能从前端容器正确可靠地指向后台容器呢?”
Service是定义一系列Pod以及访问这些Pod的策略的一层抽象。
Service通过Label找到Pod组。因为Service是抽象的,所以在图表里通常看不到它们的存在,这也就让这一概念更难以理解。
假设有2个后台Pod,并且定义后台Service的名称为‘backend-service’,lable为(tier=backend, app=myapp)。backend-service 的Service会完成如下两件重要的事情:
为Service创建一个本地集群的DNS入口,因此前端Pod只需要DNS查找主机名为 ‘backend-service’,就能够解析出前端应用程序可用的IP地址。
现在前端已经得到了后台服务的IP地址,但是它应该访问2个后台Pod的哪一个呢?Service在这2个后台Pod之间提供透明的负载均衡,会将请求分发给其中的任意一个(如下面的动画所示)。
通过每个Node上运行的代理(kube-proxy)完成。
下图动态展示了Service的功能。该图作了简化。
另外还有有一个特别类型的Kubernetes Service,称为'LoadBalancer',作为外部负载均衡器使用,在一定数量的Pod之间均衡流量。
比如,对于负载均衡Web流量很有用。
Node
节点(上图橘色方框)是物理或者虚拟机器,作为Kubernetes worker,通常称为Minion。每个节点都运行如下Kubernetes关键组件:
Kubelet:是主节点代理。
Kube-proxy:Service使用其将链接路由到Pod,如上文所述。
Docker或Rocket:Kubernetes使用的容器技术来创建容器。
Kubernetes Master
集群拥有一个Kubernetes Master(紫色方框)。
Kubernetes Master提供集群的独特视角,并且拥有一系列组件,比如Kubernetes API Server。
API Server提供可以用来和集群交互的REST端点。
master节点包括用来创建和复制Pod的Replication Controller。
集群
一个集群指容器运行所需要的云资源组合,关联了若干服务器节点、负载均衡、专有网络等云资源。
节点
一台服务器(可以是虚拟机实例或者物理服务器)已经安装了 Docker Engine,可以用于部署和管理容器;容器服务的 Agent 程序会安装到节点上并注册到一个集群上。集群中的节点数量可以伸缩。
容器
一个通过 Docker 镜像创建的运行时实例,一个节点可运行多个容器。
镜像
Docker 镜像是容器应用打包的标准格式,在部署容器化应用时可以指定镜像,镜像可以来自于 Docker Hub,阿里云容器 Hub,或者用户的私有 Registry。镜像 ID 可以由镜像所在仓库 URI 和镜像 Tag(缺省为 latest)唯一确认。
编排模板
编排模板包含了一组容器服务的定义和其相互关联,可以用于多容器应用的部署和管理。容器服务支持 Docker Compose 模板规范并有所扩展。
应用
一个应用可通过单个镜像或一个编排模板创建,每个应用可包含1个或多个服务。
服务
一组基于相同镜像和配置定义的容器,作为一个可伸缩的微服务。
节点(Node)
Kubernetes 集群中的计算能力由 Node 提供,Kubernetes 集群中的 Node 是所有 Pod 运行所在的工作主机,可以是物理机也可以是虚拟机。工作主机的统一特征是上面要运行 kubelet 管理节点上运行的容器。
命名空间(Namespace)
命名空间为 Kubernetes 集群提供虚拟的隔离作用。Kubernetes 集群初始有 3 个命名空间,分别是默认命名空间 default、系统命名空间 kube-system 和 kube-public ,除此以外,管理员可以可以创建新的名字空间满足需要。
Pod
Pod是 Kubernetes 部署应用或服务的最小的基本单位。一个Pod 封装多个应用容器(也可以只有一个容器)、存储资源、一个独立的网络 IP 以及管理控制容器运行方式的策略选项。
服务(Service)
Service 也是 Kubernetes 的基本操作单元,是真实应用服务的抽象,每一个服务后面都有很多对应的容器来提供支持,通过 Kube-Proxy 的 port 和服务 selector 决定服务请求传递给后端的容器,对外表现为一个单一访问接口,外部不需要了解后端如何运行,这给扩展或维护后端带来很大的好处。
部署(Deployment)
部署表示用户对 Kubernetes 集群的一次更新操作。部署比 RS 应用更广,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。滚动升级一个服务,实际是创建一个新的 RS,然后逐渐将新 RS 中副本数增加到理想状态,将旧 RS 中的副本数减小到 0 的复合操作;这样一个复合操作用一个RS是不太好描述的,所以用一个更通用的 Deployment 来描述。不建议您手动管理利用 Deployment 创建的 RS。
服务(Service)
Service 也是 Kubernetes 的基本操作单元,是真实应用服务的抽象,每一个服务后面都有很多对应的容器来提供支持,通过 Kube-Proxy 的 port 和服务 selector 决定服务请求传递给后端的容器,对外表现为一个单一访问接口,外部不需要了解后端如何运行,这给扩展或维护后端带来很大的好处。
标签(labels)
Labels 的实质是附着在资源对象上的一系列 Key/Value 键值对,用于指定对用户有意义的对象的属性,标签对内核系统是没有直接意义的。标签可以在创建一个对象的时候直接赋予,也可以在后期随时修改,每一个对象可以拥有多个标签,但 key 值必须唯一。
存储卷(Volume)
Kubernetes 集群中的存储卷跟 Docker 的存储卷有些类似,只不过 Docker 的存储卷作用范围为一个容器,而 Kubernetes 的存储卷的生命周期和作用范围是一个 Pod。每个 Pod 中声明的存储卷由 Pod 中的所有容器共享。支持使用 Persistent Volume Claim 即 PVC 这种逻辑存储,使用者可以忽略后台的实际存储技术,具体关于 Persistent Volumn(pv)的配置由存储管理员来配置。
持久存储卷(Persistent Volume,PV)和持久存储卷声明(Persistent Volume Claim,PVC)
PV 和 PVC 使得 Kubernetes 集群具备了存储的逻辑抽象能力,使得在配置 Pod 的逻辑里可以忽略对实际后台存储技术的配置,而把这项配置的工作交给 PV 的配置者。存储的 PV 和 PVC 的这种关系,跟计算的 Node 和 Pod 的关系是非常类似的;PV 和 Node 是资源的提供者,根据集群的基础设施变化而变化,由 Kubernetes 集群管理员配置;而 PVC 和 Pod是资源的使用者,根据业务服务的需求变化而变化,由 Kubernetes 集群的使用者即服务的管理员来配置。