一.什么是POD

k8s daemonset pod个数 k8s中pod_Pod


在Kubernetes集群中,Pod是所有业务类型的基础,也是K8S管理的最小单位级,它是一个或多个容器的组合。这些容器共享存储、网络和命名空间,以及如何运行的规范。在Pod中,所有容器都被同一安排和调度,并运行在共享的上下文中。对于具体应用而言,Pod是它们的逻辑主机,Pod包含业务相关的多个应用容器。

k8s daemonset pod个数 k8s中pod_重启_02


Pod有两个必须知道的特点。

网络:每一个Pod都会被指派一个唯一的Ip地址,在Pod中的每一个容器共享网络命名空间,包括Ip地址和网络端口。在同一个Pod中的容器可以同locahost进行互相通信。当Pod中的容器需要与Pod外的实体进行通信时,则需要通过端口等共享的网络资源。

存储:Pod能够被指定共享存储卷的集合,在Pod中所有的容器能够访问共享存储卷,允许这些容器共享数据。存储卷也允许在一个Pod持久化数据,以防止其中的容器需要被重启。

二. Pod的工作方式

K8s一般不直接创建Pod。 而是通过控制器和模版配置来管理和调度

2.1 Pod模版

k8s daemonset pod个数 k8s中pod_k8s daemonset pod个数_03


k8s daemonset pod个数 k8s中pod_初始化_04


2.2 Pod重启

在Pod中的容器可能会由于异常等原因导致其终止退出,Kubernetes提供了重启策略以重启容器。重启策略对同一个Pod的所有容器起作用,容器的重启由Node上的kubelet执行。Pod支持三种重启策略,在配置文件中通过restartPolicy字段设置重启策略:

Always:只要退出就会重启。
OnFailure:只有在失败退出(exit code不等于0)时,才会重启。
Never:只要退出,就不再重启

注意,这里的重启是指在Pod的宿主Node上进行本地重启,而不是调度到其它Node上。

2.3资源限制

Kubernetes通过cgroups限制容器的CPU和内存等计算资源,包括requests(请求,调度器保证调度到资源充足的Node上)和limits(上限)等:

k8s daemonset pod个数 k8s中pod_k8s daemonset pod个数_05


2.4健康检查

在Pod部署到Kubernetes集群中以后,为了确保Pod处于健康正常的运行状态,Kubernetes提供了两种探针,用于检测容器的状态:

Liveness Probe :检查容器是否处于运行状态。如果检测失败,kubelet将会杀掉掉容器,并根据重启策略进行下一步的操作。如果容器没有提供Liveness Probe,则默认状态为Success;

ReadinessProbe :检查容器是否已经处于可接受服务请求的状态。如果Readiness Probe失败,端点控制器将会从服务端点(与Pod匹配的)中移除容器的IP地址。Readiness的默认值为Failure,如果一个容器未提供Readiness,则默认是Success。

kubelet在容器上周期性的执行探针以检测容器的健康状态,kubelet通过调用被容器实现的处理器来实现检测,在Kubernetes中有三类处理器:

ExecAction :在容器中执行一个指定的命令。如果命令的退出状态为0,则判断认为是成功的;

TCPSocketAction :在容器IP地址的特定端口上执行一个TCP检查,如果端口处于打开状态,则视为成功;

HTTPGetAcction :在容器IP地址的特定端口和路径上执行一个HTTP Get请求使用container的IP地址和指定的端口以及请求的路径作为url,用户可以通过host参数设置请求的地址,通过scheme参数设置协议类型(HTTP、HTTPS)如果其响应代码在200~400之间,设为成功。

健康检测的结果为下面三种情况:

Success :表示容器通过检测
Failure :表示容器没有通过检测
Unknown :表示容器容器失败

2.5初始化容器

在开发一个程序时,通常初化代码与主体业务代码放置在同一个程序中。为什么kubernetes提供初始化容器这种功能,将初始化工作从普通容器中隔离出来?这种特性有什么用呢?初始化容器与普通容器有各自独立的image,本质上是将初始化逻辑与主体业务逻辑分离并放置在不同的image中,以下是初始化容器的主要用处:

1.初始化容器可以包含不能随普通容器一起发布出去的敏感信息。

2.初始化容器可以包含用户自定义的代码、工具,如sed、awk、python等方便完成初始化、设置工作。

3.因为初始化逻辑与主体业务逻辑分布在不同的image中,因此image构建者与主体业务逻辑开发者可以各自独立的工作。

4.初始化容器使用Linux namespace,不同于普通应用容器,具有不同的文件系统视图,并且对于低层的操作系统有更大的访问权限。

5.当应用启动的前置条件不具备时,初始化容器可以阻止普通应用容器启动,避免在条件不具备时反复启动注定会失败的容器而浪费系统资源。

三.POD调度

3.1 选择节点(nodeSelector)

nodeSelector是目前最为简单的一种pod运行时调度限制,Pod.spec.nodeSelector通过kubernetes的label-selector机制选择节点,由调度器调度策略匹配label,而后调度pod到目标节点,该匹配规则属于强制约束。

3.2 亲和性(Affinity)与非亲和性(anti-affinity)
三大优势

表述语法更加多样化,不再仅受限于强制约束与匹配。

调度规则不再是强制约束(hard),取而代之的是软限(soft)或偏好(preference)。

指定pod可以和哪些pod部署在同一个/不同拓扑结构下。

3.2.1节点亲和性(Node affinity)

1.requiredDuringSchedulingIgnoredDuringExecution:

可认为一种强制限制,如果 Node 的标签发生了变化导致其没有符合 Pod 的调度要求节点,那么pod调度就会失败。

2.preferredDuringSchedulingIgnoredDuringExecution:

软限或偏好,同样如果 Node 的标签发生了变化导致其不再符合 pod 的调度要求,pod 依然会调度运行。

k8s daemonset pod个数 k8s中pod_重启_06


检查结果符合预期,pod nginx成功部署到非master节点且CPU高配的机器上。

3.2.2 pod亲和性(Inter-pod affinity)与反亲和性(anti-affinity)
podAffinity用于调度pod可以和哪些pod部署在同一拓扑结构之下。而podAntiAffinity相反,其用于规定pod不可以和哪些pod部署在同一拓扑结构下。通过pod affinity与anti-affinity来解决pod和pod之间的关系。

本示例中假设部署场景为:期望is服务与oltp服务就近部署,而不希望与solr服务部署同一拓扑结构上。

k8s daemonset pod个数 k8s中pod_初始化_07


3.2.3污点(Taints)与容忍(tolerations)

对于Node affinity,无论是强制约束(hard)或偏好(preference)方式,都是调度pod到预期节点上,而Taints恰好与之相反,如果一个节点标记为 Taints ,除非 Pod也被标识为可以耐受污点节点,否则该Taints节点不会被调度pod。Taints)与tolerations当前处于beta阶段,
Taints节点应用场景比如用户希望把Kubernetes Master节点保留给 Kubernetes 系统组件使用,或者把一组具有特殊资源预留给某些 pod。pod不会再被调度到taint标记过的节点。