一.概要
基本对象
- Pod
Pod是最小部署单元,一个Pod有一个或多个容器组成,Pod中容器共享存储和网络,在同一台Docker主机上运行。 - Service
Service一个应用服务抽象,定义了Pod逻辑集合和访问这个Pod集合的策略。
Service代理Pod集合对外表现是为一个访问入口,分配一个集群IP地址,来自这个IP的请求将负载均衡转发后端Pod中的容器。
Service通过Lable Selector选择一组Pod提供服务。 - Volume
数据卷,共享Pod中容器使用的数据。 - Namespace
命名空间将对象逻辑上分配到不同Namespace,可以是不同的项目、用户等区分管理,并设定控制策略,从而实现多租户。
命名空间也称为虚拟集群。 - Lable
标签用于区分对象(比如Pod、Service),键/值对存在;每个对象可以有多个标签,通过标签关联对象。
基于基本对象更高层次抽象:
- ReplicaSet
下一代Replication Controller。确保任何给定时间指定的Pod副本数量,并提供声明式更新等功能。
RC与RS唯一区别就是lable selector支持不同,RS支持新的基于集合的标签。RS支持新的基于集合的标签,RC仅支持基于等式的标签。 - Deployment
Deployment是一个更高层次的API对象,它管理ReplicaSets和Pod,并提供声明式更新等功能。
官方建议使用Deployment管理ReplicaSets,而不是直接使用ReplicaSets,这就意味着可能永远不需要直接操作ReplicaSet对象。 - StatefulSet
StatefulSet适合持久性的应用程序,有唯一的网络标识符(IP),持久储存,有序的部署、扩展、删除和滚动更新。 - DaemonSet
DaemonSet确保所有(或一些)节点运行同一个Pod、当节点加入Kubernetes集群中,Pod会被调度到节点上运行,当节点从集群中移除时,DaemonSet的Pod会被删除,删除DaemonSet会清理它所有创建的Pod。 - Job
一次性任务,运行完成后Pod销毁,不再重新启动新容器。还可以任务定时运行。
二 . 详细道来
2.1 Pod资源对象
Pod
资源对象是一种集合了一到多个应用容器、存储资源、专用IP
及支撑容器运行的其他选项的逻辑组件,如图所示。Pod
代表着Kubernetes
的部署单元及原子运行单元,即一个应用程序的单一运行实例,它通常由共享资源且关系紧密的一个或多个应用容器组成。
Kubernetes
的网络模型要求其各Pod
对象的IP
地址位于同一网络平面内(同一IP
网段),各Pod
之间可使用其IP
地址直接进行通信,无论它们运行于集群内的哪个工作节点上,这些Pod
对象都像运行于同一局域网中的多个主机。不过,
Pod
对象中的各进程均运行于彼此隔离的容器中,并于容器间共享两种关键资源:网络和存储卷。
- 网络:每个
Pod
对象都会被分配一个集群内专用的IP
地址,也称为Pod IP
,同一Pod
内部的所有容器共享Pod
对象的Network
和UTS
名称空间,其中包括主机名、IP
地址和端口等。因此,这些容器间的通信可以基于本地回环接口lo
进行,而与Pod
外的其他组件的通信则需要使用Service
资源对象的ClusterIP
及相应的端口完成。- 存储卷:用户可以为
Pod
对象配置一组“存储卷”资源,这些资源可以共享给其内部的所有容器使用,从而完成容器间数据的共享。存储卷还可以确保在容器终止后重启,甚至是被删除后也能确保数据不会丢失,从而保证了生命周期内的Pod
对象数据的持久化存储。一个
Pod
对象代表某个应用程序的一个特定实例,如果需要扩展应用程序,则意味着为此应用程序同时创建多个Pod
实例,每个实例均代表应用程序的一个运行的“副本”(replica
)。这些副本化的Pod
对象的创建和管理通常由另一组称为“控制器”(Controller
)的对象实现,例如,Deployment
控制器对象。创建
Pod
时,还可以使用Pod Preset
对象为Pod
注入特定的信息,如ConfigMap
、Secret
、存储卷、挂载卷和环境变量等。有了Pod Preset
对象,Pod
模板的创建者就无须为每个模板显示提供所有信息,因此,也就无须事先了解需要配置的每个应用的细节即可完成模板定义。基于期望的目标状态和各节点的资源可用性,
Master
会将Pod
对象调度至某选定的工作节点运行,工作节点于指向的镜像仓库(image register
)下载镜像,并于本地的容器运行时环境中启动容器。Master
会将整个集群的状态保存于etcd
中,并通过API Server
共享给集群的各组件及客户端。
2.2 Controller
Kubernetes
集群的设计中,Pod
是有生命周期的对象。通过手动创建或由Controller
(控制器)直接创建的Pod
对象会被“调度器”(Scheduler
)调度至集群中的某工作节点运行,待到容器应用进程运行结束之后正常终止,随后就会被删除。另外,节点资源耗尽或故障也会导致Pod
对象被回收。但
Pod
对象本身并不具有“自愈”功能,若是因为工作节点甚至是调度器自身导致了运行失败,那么它将会被删除;同样,资源耗尽或节点故障导致的回收操作也会删除相关的Pod
对象。在设计上,Kubernetes
使用”控制器“实现对一次性的(用后即弃)Pod
对象的管理操作,例如,要确保部署的应用程序的Pod副本数量严格反映用户期望的数目,以及基于Pod
模板来创建Pod
对象等,从而实现Pod
对象的扩缩容、滚动更新和自愈能力等。例如,某节点发生故障时,相关的控制器会将此节点上运行的Pod
对象重新调度到其他节点进行重建。控制器本身也是一种资源类型,它有着多种实现,其中与工作负载相关的实现如
Replication Controller
、Deployment
、StatefulSet
、DaemonSet
和Jobs
等,也可统称它们为Pod
控制器。
Pod
控制器的定义通常由期望的副本数量、Pod
模板和标签选择器(Label Selector
)组成。Pod
控制器会根据标签选择器对Pod
对象的标签进行匹配检查,所有满足选择条件的Pod
对象都将受控于当前控制器并计入其副本总数,并确保此数目能够精确反映期望的副本数。
2.3 Service
尽管
Pod
对象可以拥有IP
地址,但此地址无法确保在Pod
对象重启或被重建后保持不变,这会为集群中的Pod
应用间依赖关系的维护带来麻烦:前端Pod
应用(依赖方)无法基于固定地址持续跟踪后端Pod
应用(被依赖方)。于是,Service
资源被用于在被访问的Pod
对象中添加一个有这固定IP
地址的中间层,客户端向此地址发起访问请求后由相关的Service
资源调度并代理至后端的Pod
对象。换言之,
Service
是“微服务”的一种实现,事实上它是一种抽象:通过规则定义出由多个Pod
对象组合而成的逻辑集合,并附带访问这组Pod
对象的策略。Service
对象挑选、关联Pod
对象的方式同Pod
控制器一样,都是要基于Label Selector
进行定义,其示意图如下
Service IP
是一种虚拟IP
,也称为Cluster IP
,它专用于集群内通信,通常使用专用的地址段,如“10.96.0.0/12”
网络,各Service
对象的IP
地址在此范围内由系统动态分配。集群内的
Pod
对象可直接请求此类的Cluster IP
,例如,图中来自Pod client
的访问请求即可以Service
的Cluster IP
作为目标地址,但集群网络属于私有网络地址,它们仅在集群内部可达。将集群外部的访问流量引入集群内部的常用方法是通过节点网络进行,实现方法是通过工作节点的IP
地址和某端口(NodePort
)接入请求并将其代理至相应的Service
对象的Cluster IP
上的服务端口,而后由Service
对象将请求代理至后端的Pod
对象的Pod IP
及应用程序监听的端口。因此,图中的External Clients
这种来自集群外部的客户端无法直接请求此Service
提供的服务,而是需要事先经由某一个工作节点(如NodeY
)的IP
地址进行,这类请求需要两次转发才能到达目标Pod
对象,因此在通信效率上必然存在负面影响。事实上,
NodePort
会部署于集群中的每一个节点,这就意味着,集群外部的客户端通过任何一个工作节点的IP
地址来访问定义好的NodePort
都可以到达相应的Service
对象。此种场景下,如果存在集群外部的一个负载均衡器,即可将用户请求负载均衡至集群中的部分或者所有节点。这是一种称为“LoadBalancer”
类型的Service
,它通常是由Cloud Provider
自动创建并提供的软件负载均衡器,不过,也可以是有管理员手工配置的诸如F5
一类的硬件设备。简单来说,
Service
主要有三种常用类型:第一种是仅用于集群内部通信的ClusterIP
类型;第二种是接入集群外部请求的NodePort
类型,它工作与每个节点的主机IP
之上;第三种是LoadBalancer
类型,它可以把外部请求负载均衡至多个Node
的主机IP
的NodePort
之上。此三种类型中,每一种都以其前一种为基础才能实现,而且第三种类型中的LoadBalancer
需要协同集群外部的组件才能实现,并且此外部组件并不接受Kubernetes
的管理。