一、Kubernetes简介
Kubernetes,简称K8s,是用8代替8个字符“ubernete”而成的缩写,是一个开源的容器集群管理应用,也是一个自动化的容器操作平台。Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制。
传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的所有生存周期(运行、配置、管理)将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作。
新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器都有自己的文件系统 ,容器之间的进程不会相互影响。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统是解耦的,所以它能在不同云、不同版本操作系统间进行迁移。
容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间形成一对一的关系,使用容器可以在 build 或 release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。
注:
Grafana是一款可视化工具,常与Prometheus结合实现对Kubernetes的监控。其大多使用在时序数据的监控方面,UI十分灵活,有丰富的插件,功能强大。Kubernetes 通常由 Prometheus + Grafana 进行性能监控。
二、Kubernetes架构
Master
Master组件可以在集群中任何节点上运行。但是为了简单起见,通常在一台VM机器上启动所有Master组件,并且不会在此VM机器上运行用户容器。Master是Kubernetes 的主节点。Master节点上面主要由四个模块组成:etcd、api server、controller manager、scheduler。
-
etcd 是 Kubernetes 提供的一个高可用的键值存储系统,用于保存集群所有的网络配置和对象的状态信息,也就是保存了整个集群的状态。整个kubernetes系统中一共有两个服务需要用到etcd用来协同和存储配置,分别是:(1)网络插件flannel,其它网络插件也需要用到etcd存储网络的配置信息;(2)kubernetes本身,包括各种对象的状态和元信息配置。
-
api server 负责对外提供RESTful的Kubernetes API服务,它是系统管理指令的统一入口,任何对资源进行增删改查的操作都要交给APIServer处理后再提交给etcd,同时它也是集群控制的入口,提供了认证、授权、访问控制、API注册和发现等机制(用于暴露Kubernetes API,任何的资源请求/调用操作都是通过apiserver提供的接口进行的)。
-
controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。包括运行管理控制器(kube-controller-manager)和云管理控制器(cloud-controller-manager)。每个资源一般都对应有一个控制器,这些Controller通过API Server实时监控各个资源的状态,controller manager就是负责管理这些控制器的。当有资源因为故障导致状态变化,Controller就会尝试将系统由“现有状态”恢复到“期待状态”。比如我们通过APIServer创建一个pod,当这个pod创建成功后,APIServer的任务就算完成了。而后面保证Pod的状态始终和我们预期的一样的重任就由controller manager去保证了。
-
scheduler 监视新创建没有分配到Node的Pod,并为Pod选择一个Node,即负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上。一旦绑定,就由Node上的kubelet接手Pod的接下来的生命周期管理。如果把scheduler看成一个黑匣子,那么它的输入是pod和由多个Node组成的列表,输出是Pod和一个Node的绑定,即将这个pod部署到这个Node上。Kubernetes目前提供了调度算法,但是同样也保留了接口,用户可以根据自己的需求定义自己的调度算法。
Node
Node上运行着Master分配的负载(Pod),当一个Node宕机,其上的负载会被自动转移到其他Node上。一个节点就是一个运行 Kubernetes 的物理或者虚拟机器。每个Node节点主要由三个模块组成:kubelet、kube-proxy、runtime。
-
kubelet 它会监视已分配给节点的pod,负责Pod的生命周期管理,同时与Master密切协作,维护和管理该Node上面的所有容器,实现集群管理的基本功能。可以理解为kubelet是Master在每个Node节点上面的agent。本质上,它负责使Pod的运行状态与期望的状态一致。
-
Container runtime:容器运行环境,目前Kubernetes支持docker和rkt两种容器。
-
kube-proxy 是实现Service的通信与负载均衡机制的重要组件。
整体架构如下:
抽象后的架构为:
Kubernetes Master 的架构位:
controller-manager 包括运行管理控制器(kube-controller-manager)和云管理控制器(cloud-controller-manager)。
kube-controller-manager
kube-controller-manager是集群中处理常规任务的后台线程。
这些控制器包括:
节点(Node)控制器
副本(Replication)控制器:负责维护系统中每个副本中的pod。
端点(Endpoints)控制器:填充Endpoints对象(即连接Services&Pods)。
Service Account和Token控制器:为新的Namespace创建默认帐户访问API Token。
cloud-controller-manager
云控制器管理器负责与底层云提供商的平台进行交互。其上仅运行云提供商特定的控制器循环(controller loops)。可以通过将–cloud-providerflag 设置为 external 启动kube-controller-manager ,来禁用控制器循环。
这些控制器包括:
节点(Node)控制器
路由(Route)控制器
Service控制器
卷(Volume)控制器
Node架构:
除了核心组件,还有一些推荐的Add-ons:
- kube-dns负责为整个集群提供DNS服务
- Ingress Controller为服务提供外网入口
- Heapster提供资源监控
- Dashboard提供GUI
- Federation提供跨可用区的集群
Kubernetes作为云原生应用的的基础调度平台,相当于云原生的操作系统,为了便于系统的扩展,Kubernetes中开放的以下接口,可以分别对接不同的后端,来实现自己的业务逻辑:
- CRI(Container Runtime Interface):容器运行时接口,提供计算资源
- CNI(Container Network Interface):容器网络接口,提供网络资源
- CSI(Container Storage Interface):容器存储接口,提供存储资源
以上三种资源相当于一个分布式操作系统中最基础的几种资源类型,而Kuberentes是将他们粘合在一起的纽带。
三、kubernetes 中常见的概念
集群是一组节点,这些节点可以是物理服务器或者虚拟机,之上安装了Kubernetes平台。
注:controller manager 包括运行管理控制器(kube-controller-manager)和云管理控制器(cloud-controller-manager)。运行管理控制器中又包含副本(Replication)控制器。
Container 即为容器
Pod
Pod(上图绿色方框)安排在节点上,包含一组容器和卷,是一个容器组。同个组内的容器共享一个存储卷(volume),共享根容器的 ip 。Pod是短暂的,不是持续性实体。Pod是kubernetes中可以创建和部署的最小也是最简单位。一个Pod代表着集群中运行的一个进程,是应用运行的载体。整个Kubernetes系统都是围绕着Pod展开的。一个Pod一旦被创建就会放到Etcd中存储,然后由Master调度到一个Node绑定,再由这个Node上的Kubelet对其进行实例化。
每个Pod会被分配一个单独的Pod IP,Pod IP + ContainerPort 组成了一个Endpoint。
那么怎么才能持久化容器数据使其能够跨重启而存在呢?Kubernetes支持卷的概念,因此可以使用持久化的卷类型。
如果想要创建同一个容器的多份拷贝,可以手动创建单个Pod,也可以使用Replication Controller使用Pod模板创建出多份拷贝。
Pod是短暂的,那么重启时IP地址可能会改变,那么怎么才能从前端容器正确可靠地指向后台容器呢?这时可以使用Service。
Pod与容器:在Docker中,容器是最小的处理单元,增删改查的对象是容器,容器是一种虚拟化技术,容器之间是隔离的,隔离是基于Linux Namespace实现的。而在Kubernetes中,Pod包含一个或者多个相关的容器,Pod可以认为是容器的一种延伸扩展,一个Pod也是一个隔离体,而Pod内部包含的一组容器又可以访问共同的数据卷来实现文件系统的共享。
Pod被分配到Node之后会根据镜像下载策略进行镜像下载,可以根据自身集群的特点来决定采用何种下载策略。无论何种策略,都要确保Node上有正确的镜像可用。
volume
一个卷就是一个目录,容器对其有访问权限。
Service
一个Service对应后端多个Pod计算实例。Service通过Label找到Pod组。因为Service是抽象的,所以在图表里通常看不到它们的存在。
假定有2个后台Pod,并且定义后台Service的名称为‘backend-service’,lable选择器为(tier=backend, app=myapp)。backend-service 会完成如下两件重要的事情:
- 会为Service创建一个本地集群的DNS入口,前端Pod只需要根据 ‘backend-service’,就能够解析出前端应用程序可用的IP地址。
- 现在前端已经得到了后台服务的IP地址,但是它应该访问2个后台Pod的哪一个呢?Service在这2个后台Pod之间提供透明的负载均衡,会将请求分发给其中的任意一个(如下面的动画所示)。通过每个Node上运行的代理(kube-proxy)完成。
如下图(动图的开始为“DNS lookup backend-service”,首先确定后台服务的IP地址,然后展示了两次随机过程,分别将请求发送给了两个后台Pod):
Label
如上图所示,一些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应用到上面。
Kubernetes Master
集群拥有一个Kubernetes Master,是Kubernetes 的主节点。Kubernetes Master 提供集群的独特视角,并且拥有一系列组件,如Kubernetes api server。
Replication Controller
如果想要创建同一个容器的多份拷贝,可以使用Replication Controller使用Pod模板创建出多份拷贝。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的标签。
如下面的动画所示:
四、理解 kubernetes 中的对象
以上列举的内容都是 kubernetes 中的 Object,这些对象都可以在 yaml 文件中作为一种 API 类型来配置。