技术笔记分享

Pod 资源对象

Pod 资源对象集合了一个或者多个应用容器、存储资源、专用 IP 及支持容器运行的其他逻辑组件。
Kubernetes 网络模型要求其各 Pod 对象的 IP 地址位于同一 IP 网段内,各个 Pod 之间可使用其 IP 直接通信,无论他们运行于集群内的哪个工作节之上,这些 Pod 对象都像是运行于同一局域网中的多个主机。Pod 对象中的各进程均运行于彼此隔离的容器中,并于同一 Pod 中各容器间共享两种关键资源:网络和存储卷

  • 网络(networking):每个 Pod 对象都会被分配一个集群内专用的 IP 地址,也称为 Pod IP,同一 Pod 内部的所有容器共享 Pod 对象的 Network 和 UTS 名称空间,其中包含主机名、IP 地址和端口等。因此这些容器间的通信可以基于本地回环接口直接进行,而与 Pod 外的其他组件通信则需要使用 Service 资源对象的 Cluster IP 及相应的端口进行实现。
  • 存储卷(volume):用户可以为 Pod 对象配置一组 ”存储卷“ 资源,这些资源可以共享给其内部所有容器使用,从而完成同容器间数据的共享。存储卷还可以确保在容器终止后被重启,甚至是删除后也确保数据不丢失,从而保证了生命周期内的 Pod 对象数据持久化存储。

一个 Pod 对象代表某个应用程序的一个特定实例,如果需要扩展应用程序,那么即为此程序同时创建多个 Pod 实例,每个实例均代表应用程序的一个 ”副本“。这些容器 “副本” 的创建和管理操作通常由另一组称为 “控制器(Controller)” 的对象实现,例如,Deployment 控制器对象。

创建Pod 时,还可以使用 Pod Preset 对象为 Pod 注入特定的信息,如 ConfigMap、Secret、存储卷、卷挂载和环境变量等。有了 Pod Preset 对象,Pod 模板的创建者久无需为每个模板显式提供所有信息,因此,也就无须事先了解需要配置的每个应用的细节即可完成模板定义。

Controller

Kubernetes 集群设计中,Pod 是由生命周期的对象,用户通过手工创建或由 Controller(控制器) 直接创建的 Pod 对象会被 “调度器(Scheduler)” 调度至集群中的某工作节点运行,待到容器应用进程运行结束之后正常终止,随后就会被删除。另外,节点资源耗尽也会导致 Pod 对象被回收。

Pod 对象本身不具备 “自愈” 功能,若是因为工作节点甚至是调度器自身导致运行失败,那么它将会被删除;同样,资源耗尽或节点故障导致的回收操作也会删除相关的 Pod 对象,在设计上,Kubernetes使用 “控制器” 实现对一次性的(用后即弃) Pod 对象的管理操作,例如:要确保 Pod 副本数量严格反映用户期望的数目,以及基于 Pod 模板来重建的 Pod 对象等,从而实现 Pod 对象的扩缩容,滚动更新和自愈能力。例如某 Pod 节点发生故障时,相关控制器会将此节点上运行的 Pod 对象重新调度到其它节点进行重建。

控制器本身也是一种资源类型,它有着多种实现,其中与工作负载相关的实现如 Replication、Controller、Deployment、StatefulSet、DaemonSet、DaemonSet、和 Jobs 等,也可统称他们为 Pod 控制器,Deployment 就是这类控制器的代表实现,是目前最常用的管理无状态应用的 Pod 控制器。

Pod 控制器的定义是由期望的副本数量、Pod 模板和标签选择器(Label Selector)组成。Pod 控制器会根据标签选择器对 Pod 对象的标签进行匹配检查,所有满足条件的 Pod 对象都将受控于当前控制器并计入其副本总数,并确保此数目能够精确反映期望的副本数量。

在实际的应用场景中,在接收到请求流量负载明显低于或者接近已用 Pod 副本的整体承载能力时,用户需要手动修改 Pod 控制器中的期望副本数量以实现应用规模的扩容或缩容。如果集群中部署了 HeapSter 或 Prometheus 一类的资源指标监控附件时,用户可以使用 “HorizontalPodAutoscaler"(HPA) 计算出合适的 Pod 副本数量,并自动修改 Pod 控制器中期望的副本数以实现应用规模的动态伸缩,提高集群资源利用率。
Kubernetes 集群中的每个节点都运行着 cAdvisor 用来收集容器及 Pod 节点的 CPU、内存及磁盘资源的利用率指标数据,这些统计数据由 Heapster 聚合后可通过 API Server 访问。HorizontalPodAutoscaler 基于这些统计数据监控容器健康状态并作出扩展决定。

Service

虽然 Pod 对象可以拥有 IP 地址,但是 Pod 地址无法确保在 Pod 对象重启或重建后保持不变,对此解决办法为,Service 资源被用于在被访问的 Pod 对象中添加一个有固定 IP 地址的中间层,客户端向此地址发起访问请求后由相关的 Service 资源调度并代理至后端的 Pod 对象。Service 是通过定义出多个 Pod 对象组合而成的逻辑组合,并附带访问这组 Pod 对象的策略。Service 对象挑选关联 Pod 对象的方式同 Pod 控制器已用,都是基于 标签选择器 Label Selector 进行定义。

undefined

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 听得服务,而是需要事先经由某一个工作节点(如 Node Y)的 IP 地址进行,这类请求需要两次才能到达目标 Pod 对象,因此在通信效率上必然存在负面影响。
NodePort 会部署于集群中的每一个节点,这就意味着,集群外部的客户端通过任何一个工作节点的 IP 地址来访问定义好的 NodePort 都可以到达相应的 Service对象。此种场景中,如果存在集群外部一个负载均衡器,即可将用用户请求负载均衡至集群中的部分或所有节点,这是一种称为 ”LoadBalancer“ 类型的 Service,它通常是由 Cloud Provider 自动创建并提供的软件负载均衡器。例如 Nginx、HAProxy或者硬件负载 F5等。

简单来说,Service 主要由三种常用类型;
第一种是仅用于集群内部通信的 Cluster IP类型。
第二种是接入集群外部请求的 NodePort 类型,它工作与每个节点的主机 IP 之上。
第三种是 LoadBalancer 类型,它可以把外部请求负责均衡至多个 Node 主机IP的NodePort之上。
三种类型中,每一种都以其前一种为基础才能实现,而且第三种类型中的 LoadBalancer 需要协同集群外部的组件才能实现,并且此外部组件不接受 Kubernetes 的管理。

发表评论

邮箱地址不会被公开。 必填项已用*标注