Kubernetes核心资源对象
Kubernete API Server提供了RESTful风格的编程接口,其管理的资源是Kubernetes API中的端点,用于存储某种API对象的集合。资源对象是用于表现集群状态的实体,常用于描述应于哪个节点进行容器化应用、需要为其配置什么资源以及应用程序的管理策略,比如,重启、升级以及容错机制等。Pod、Deployment和Service是K8S最常用的核心对象。
1、Pod资源对象
一个或者多个容器的集合(可以理解为在容器上面又封装了一层)。Pod是Kubernetes最小部署单元以及原子运行单元。
图1.Pod通常由一个或者多个共享网络和存储资源的容器组合而成Kubernetes网络模型要求其Pod对象的IP必须都在同一网络平面内,即处于同一IP网络段。Pod之间使用IP进行直接通信。可以把每个Pod对象想象成一个逻辑主机,它类似于现实世界中的物理主机;Pod对象中运行的多个进程也类似于物理机上独立运行的进程。只不过,Pod对象中的各进程均运行于彼此隔离的容器中,并在各容器间共享两种资源:
* 网络(networking)
每个Pod都会被分配到一个集群内专用的IP地址,Pod IP。同一个Pod内部的所有容器共享Pod对象的Network和UTS(主机名/域名)命名空间。
容器间通信可以基于本地回环接口lo进行 ,而与Pod外的其他组件的通信则需要使用Service资源对象的ClusterIP及相应的端口完成。
* 存储卷(volume)
用户可以为Pod对象配置存储卷资源,内部的容器可以共享这些资源,从而实现容器间的数据共享以及Pod对象数据的持久化存储。
当然,创建Pod时,可以使用Pod Preset对象为Pod注入特定的信息,比如ConfigMap、Secret、环境变量等(后面会专门整理)。最后,基于期望的目标状态和各节点的资源可用性,Master会将Pod对象调度到某个特定的工作节点运行。此外,Master会将整个集群的状态记录到etcd中,并通过API Server共享给集群的各组件及客户端。
2. Controller资源对象
控制器有着多种实现,与工作负载相关的实现如Replication Controller、Deployment、StatefulSet、DaemonSet和Job等。管理无状态应用最常用的Pod控制器Deployment实现原理大致如下:
图2.Replication ControllerPod是有生命周期的对象。等到容器应用进程运行结束或者节点资源耗尽或者故障都会导致Pod对象被回收,而Pod对象本身并不具有"自愈"的功能。Pod控制器通常是由期望的副本数量、Pod模板对象和标签选择器组成。Pod控制器会根据标签选择器对Pod对象的标签进行匹配检查,所有满足选择条件的Pod对象都将受控于当前控制器。
如果接收到的请求流量负责显著低于或者接近于已有Pod副本整体的承载能力,用户只能手动修改Pod数量以实现规模的扩容或者缩容。那么如果实现动态地根据请求流量以及资源使用率修改控制器中期望的副本数呢?需要部署Heapster或者Prometheus一类的资源指标监控配合使用HPA(HorizontalPodAutoScaler)计算出合适的Pod副本数量。
Kubernetes集群中的每个节点都运行着cAdvisor收集容器及节点的CPU、内存及磁盘资源的利用率指标数据,这些统计数据由Heapster聚合后可以通过API Server访问。HPA基于这些统计数据监控容器健康状态并作出扩展决策。
3. Service资源对象
问题:Pod IP在Pod对象重启或重建后随之发生变化,这就为集群中的Pod应用间依赖关系的维护带来了麻烦:前端Pod应用(依赖方)无法基于固定地址持续跟踪后端Pod应用(被依赖方)。
Service资源对象就是用于在被访问的Pod对象中添加一个有着固定IP地址的中间层,客户端向此地址发起访问请求后由相关的Service资源调度并代理到后端的Pod对象。
可以将Service理解为是一种"微服务"的实现:通过规则定义出由多个Pod对象组合而成的逻辑集合,并附带访问这组Pod对象的策略。示意图如下:
图3.Service对象功能示意图Service IP是一种虚拟IP,也称为Cluster IP,专用于集群内通信,通常使用专用的地址段。各Service对象的IP地址在此范围内由系统动态分配。集群内Pod对象可以直接请Cluster IP。集群网络属于私有网络地址,仅在集群内部可达。
将集群外部的访问流量引入集群内部的常用办法是通过节点网络进行,实现方法是通过工作节点的IP地址和端口(NodePort)接入请求并将其代理到相应的Service对象的Cluster IP上的服务端口,然后再由Service对象将请求代理到后端的Pod对象的Pod IP及应用程序监听的端口。
图4.外部流量引入集群内部调用顺序NodePort会部署在集群中每一个节点,集群外部的客户端通过任何一个工作节点的IP地址来访问定义好的NodePort都可以达到相应的Service对象。这种场景下,如果集群存在集群外部的一个负载均衡器,就可以把用户请求负载均衡至集群中的部分或者所有节点。
Service简单总结来说,主要有三种常用类型:
(1)仅用于集群内部通信的固定IP地址ClusterIP
(2)接入集群外部请求的NodePort类型,它工作于每个节点的主机IP之间
(3)LoadBalance类型,它可以把外部请求负载均衡至多个Node的主机IP中NodePort之上
每一种都以其前一种为基础才能实现,第三种需要依赖集群外部的组件才能实现,并且此外部组件不接受Kubernetes的管理。