综述
学习Kubernetes时,发现它的概念和术语仍是比较多的,光靠啃官方文档比较晦涩。因此边学习边整理,对主要的概念和术语作一下分类及简要说明。感受把重要概念都理解了,对Kubernetes的设计思想,总体框架也就有了初步的认识。node
从功能上来讲,我把Kubernetes的概念或术语大概分为如下三类:数据库

- 组件:指实际在集群中运行的Kubernetes程序集,分为Master组件、Node组件及附加组件。
- 对象:对象是一个抽象的概念实体,Kubernetes把应用、运行场景、功能、集群状态等都抽象成一个个对象,并经过API对这些对象进行管理,从而管理整个集群的状态。
- 标识:对组件和对象的各类表示方式,例如命名、标签、注释等。标识是KubernetesAPI与操做对象间的纽带。
组件
Master组件
Master组件提供了k8s管理集群的核心功能,k8s经过Master组件实现整个集群的调度管理,它就像集群的大脑,会根据集群当前的状态,不断进行调整,使集群一直保持在指望的状态。Master组件包括如下几个进程:ubuntu
Etcd
Etcd是Kubernetes集群的基础组件,用于保存集群全部的元数据信息、配置信息、对象状态等。安全
Node组件
运行Node组件的节点称为Node节点,是k8s集群实际的工做负载节点。Node节点能够是物理机、虚拟机或任何能够运行Node组件的设备。全部的业务应用都运行在Node节点中。Node组件包括如下几个部分:架构
- Kubelet
kubelet负责实际的容器管理,Kubernetes经过apiserver给kubelet发送Pod管理请求,同时把Pod及Node的运行状态汇报给apiserver。
- kube-proxy
kube-proxy负责集群内部的请求转发及负载均衡工做。它经过Service对象的配置信息,为Pod建立代理服务,实现请求从Service到Pod的路由转发。
- 容器运行时
实际的容器运行引擎。Kubernetes其实支持其余的容器技术好比rkt,可是Docker相比与它们处于绝对的优点地位。因此,Kubernetes生态中的容器也基本特指指Docker容器。负载均衡
对象
在说明对象以前,先区分下Kubernetes中的三个名词:对象(objects)、资源(resources)和工做负载(workload).框架
- 对象:指的是KubernetesAPI中定义好的操做对象,是抽象概念。
- 资源:抽象API对象被建立后,对象就被实例化了。实例化后的对象被称为资源。
- 工做负载:特指有运行容器的资源,例如Deployment资源就是工做负载,而service资源不是。
Kubernetes集群为每一个对象维护三类信息:对象元数据(ObjectMeta)、指望状态(Desired State)与实际状态(Autual State),元数据指对象的基本信息,好比命名、标签、注释等等,用于识别对象;指望状态通常由用户配置spec来描述的;实际状态是由集群各个组件上报的集群实际的运行状况。Kubernetes努力使每一个对象的实际状态与指望状态相匹配,从而使整个集群的状态与用户配置的指望状态一致。
Kubernetes对象通常用yaml文件来描述,有几个个字段是必须的:运维
- apiVersion: 建立该对象所使用的 Kubernetes API 的版本
- kind: 想要建立的对象的类型
- metadata: 帮助识别对象惟一性的数据,包括一个 name 字符串、UID 和可选的 namespace
- spec: 对象指望状态的描述
用户经过命令行工具kubectl来操做这些对象,Kubectl吧yaml转换成JSON格式来执行API请求。下面是一个POD对象的描述文件示例及注释:分布式
apiVersion: v1
kind: Pod # 对象名称
metadata: # 对象的基本信息
name: pod-example # 对象惟一标示
spec: # 指望状态
containers: # 指定pod中运行的容器镜像及运行参数(相似Dockerfile)
- name: ubuntu
image: ubuntu:trusty
command: ["echo"]
args: ["Hello World"]
其中,kind字段描述对象类型"Pod",spec以前是对象的ObjectMeta,spec开始,就是对象指望状态的描述。
根据官方API对象参考文档的分类,下面咱们把对象分为几大类来分别简要说明。计划之后的文章,会结合实际操做,对各个重要对象作更深刻的说明。
Workloads 资源对象
- workloads类的对象用于管理运行容器实例
- Pod:
Pod是Kubernetes里最重要的对象,也是Kubernetes集群中运行部署应用或服务的最小单位。Pod对象描述一个Pod由哪些容器镜像构成,以及这些容器应该怎么运行。类比传统的业务架构,Pod更接近于虚拟机的角色而不是应用进程的角色。
- ReplicaSet:
ReplicaSet对象是对Pod的更高一层抽象,它用来管理一组相同POD副本,并确保这组相同Pod的数量始终与用户指望一致,并实现Pod的高可用。即若是有容器异常退出,ReplicaSet会自动建立新的Pod来替代,保证Pod数量永远与用户配置一致。
- Deployment:
Deployment对象是Kubernetes中最经常使用的对象之一,用于部署无状态服务。它在ReplicaSet对象的基础上,又作了一层抽象。经过管理多组ReplicaSet对象,来实现POD的滚动升级、回滚、扩容缩容等。
- StatefulSet:
不一样于Deployment,StatefulSet对象顾名思义是对有状态服务的一种抽象。因此,StatefulSet对象在定义时,相比与Deployment多了一些与状态相关的内容,好比持久化存储、服务对外的不变的惟一标示、部署、扩容、滚动升级时确保有序等等。
- DaemonSet:
DaemonSet对象是Kubernetes对守护进程的抽象。当咱们须要集群中的每一个Node都跑一些如日志收集、监控等守护进程时,就能够把这类型进程包装成Pod,并用调用DaemonSet来部署了。DaemonSet作的事情其实和Deployment差很少,只不过Deployment对象部署的Pod,会根据集群状况,在不一样Node间自动调度。而DaemonSet会指定的NODE上(默认是集群全部Node),都部署定义Pod,确保这些NODE都有跑着守护进程Pod。
- Job、CronJob:
除了上面几个对象所抽象描述的应用工做场景外,实际业务场景中,还有一类应用或服务并不须要一直运行,好比一些一次性任务,或须要定时执行的任务。这种不须要长时间运行的任务,完成了就能够退出的服务,就能够用Job对象来定义。CronJob和Job对象的关系,和Deployment与ReplicaSet的关系很像,能够类比来理解。首先,Job也是直接用于管理Pod的,同时能够定义这个一次性任务Pod的执行时间、超时时间、错误处理(重启仍是生成新Pod)等任务属性。而CronJob管理是用来管理Job,相似crobtab,它能够经过yaml文件中的schedule字段配置具体时间,来控制指定Job定时执行,从而实现定时执行特定的一次性任务。
Discovery & LB 资源对象
- 该类对象用于服务发现和负载均衡的对象
而Service对象就是用来解决这两个问题的。它用固定的VIP或DNS名称和指定标识的一组Pod对应起来,无论Pod IP怎么变,Service对外的VIP都不会变化,而且,自动的将请求在这组Pod中负载均衡。
Config & Storage 资源对象
- 该类对象用于初始化容器配置及持久化容器存储的对象
- Volume:
前面说到,Pod里的不一样容器能够共享存储,这个共享存储就靠Volume来配置的。要注意的是,这里Volume与Docker中的定义不用,Kubernetes中Volume跟Pod生命周期一致,Pod终止了,该Pod挂载的Volume就失效了(根据挂载volume的类型不一样,数据可能丢失也可能不丢失)。
- PV,PVC:
Volume能够支持多种类型的存储,除了直接在Volume字段中去声明全部存储细节,K8S还抽象出了PV和PVC对象。简单来讲PV是对具体存储资源的描述,好比存储类型、地址、访问帐户等;而PVC,是对怎么使用资源的方法的描述,好比只读只写,须要的空间等;而Pod经过Volume字段挂载具体要使用的PVC。PV和PVC是独立于Pod单独定义的,这样,就把共享存储的配置、分割、挂载等操做都解耦了。好比,一个NFS迁移后ip地址变了,存储管理员只须要修改PV中的配置,而不用关心具体哪一个业务POD在使用这个NFS。
- ConfigMap,Securet
K8S中除了常见的存储,还有一类特殊的Volume,不是为了Pod存放数据,而是为了给Pod提供数据的。ConfigMap和Secret对象就是用来定义这类型的Volume。简单来讲,能够将它们理解为一份Key:Value格式的数据,Pod能够经过Volume挂载它们,将这份数据保存成文件随时调用。惟一的区别是,ConfigMap对象保存的数据是明文,通常做为应用配置文件;而Secret对象保存的对象要求是通过Base64转码的,用于提供数据库密码等对安全要求比较高的配置。不过这些配置,直接在作容器镜像时就配置不就行了,为啥要画蛇添足呢?缘由和上面PV和PVC同样,都是为了尽量解耦业务核心与常常可能变化的依赖配置。好比数据库更换了帐号,只须要修改Secret对象,不用从新去构建容器镜像。
Cluster resources objects
- 该类对象定义整个K8S集群运行方式的对象
- Namespace
Kubernetes做为一个集群管理平台,为不一样用户划分不一样权限管理,例如多租户等,是必备的功能。而不一样用户做用域的隔离,就是靠Namespace对象实现的。Namespace是Kubernetes项目中的一个逻辑管理单位,不一样Namespace的API对象,在调用API进行操做是,是相互隔离开的。经过不一样用户角色与Namespace关联,从而实现权限管理。
Metadata resources
- 除了上述分类外的其余对象都归为这一类,通常用来管理集群的特殊功能好比弹性伸缩等
- Horizontal Pod Autoscaling
容器做为一个轻量级的承载应用的技术,快速启动和快速部署是它的优势之一。天然的,根据业务负载自动扩缩容等需求,在容器集群的可行性和效率就能够变得很高。而Kubernetes中 Horizontal Pod Autoscaling对象,就是用于进行POD自动水平缩放的,这也是Kubernetes最能体现运维优点的特性之一。
Horizontal Pod Autoscaling具体的操做对象是Deployment和ReplicaSet,经过不一样循环获取每一个Pod的资源状况,好比CPU利用率,并根据设定的目标利率来计算目前须要的Pod副本缩放的比例,而后经过访问相应的Deployment或ReplicaSet对象,来对Pod数量进行自动缩放,从而提升了集群资源总体利用率。
标识
标识是Kubernetes中最重要的概念,由于它是全部API的操做与操做对象间的纽带。Kubernetes中的标识主要有如下几种:
- Label
Label能够说是Kubernetes中最最重要的核心概念,一个Lable是一个KEY=Value的键值对。任何对象资源均可以有一个或多个Label,而同个Label,也能够配置在多个对象上。而后重点来了,大多数API对象的yaml字段中,都有Label Selector字段,能够实现对Label中的key或value的多维度选择,例如in、not in、and、or等等。这样,Kubernetes对API做用对象就能进行多维度,细粒度的选择,从而实现比较精细化的容器编排调度工做,好比,对全部"ENV:release"执行扩容操做,或者把部分请求灰度到有"ver:v1.14.0"的pod上等等。Label把资源对象和应用、基础设施都解耦了,你不用关心这个Pod具体在那个Node上运行,也不用关心具体是什么应用用了哪一个容器镜像,只要Label符合Label Selector,就能够经过API调用统一进行操做。
- Names
除了Label,全部资源对象确定还必须有一个全局惟一的标识,即Names字段。
- Annotation
Annotation很好理解,与一般意义的注释同样,用于描述做者、版本、配置说明等等任何须要的信息,须要说明的是,Annotation也必须是Key:Value格式的。
总结
经过上面对Kubernetes重要概念的说明,咱们能够大体梳理出Kubernetes的一些设计理念:
- Kubernetes对容器应用进行了抽象,例如把一个容器或强关联的一组容器抽象为Pod,把各种存储都抽象成Volume,把一组Pod抽象成Service等等基础对象。
- 在基础对象的层面上,Kubernetes又对应用使用场景,作了一层抽象。极客时间的Kubernetes课程有一张图画的很好:
能够看到,Kubernetes中各个对象实际就是对生产业务场景的各种需求的抽象。
- 抽象出各种型对象之后,用户能够经过yaml文件(或直接命令行调用API)来描述这些对象的指望状态,确认了各对象些指望状态的集合,也就确认了整个集群的指望状态。这些全部的操做,都是声明式的,而不是命令集群要怎么作
- Kubernetes经过控制器循环不断将各组件收集来的集群实际状态与各对象的指望状态对比,并自动化的将集群实际状态向指望状态转移,这个过程,也就是Kubernetes最核心的概念:编排。
本文对Kubernetes中的重要概念作了分类和简要,后面的文章会结合集群的实际操做,对每一个概念作更详细的说明。