一、进程ID约束和预留机制
Kubernetes提供了进程ID(PID)约束和预留机制,以帮助管理员更好地管理节点上的资源。通过限制一个Pod中可以使用的PID数目,可以防止某个Pod中的进程消耗过多的系统资源,从而影响其他进程的正常运行。同时,管理员还可以为每个节点预留一定数量的可分配的PID,供操作系统和守护进程使用。
进程ID是节点上的一种基础资源,如果未受到限制,很容易就会在超出其它资源约束的情况下导致宿主机器不稳定。因此,集群管理员需要一定的机制来确保运行的Pod不会导致PID资源枯竭,甚至造成宿主机上的守护进程无法正常运行。此外,确保Pod中PID的个数受限对于保证其不会影响到同一节点上其他负载也很重要。
注意:在某些 Linux 安装环境中,操作系统会将 PID 约束设置为一个较低的默认值,例如 32768,这时可以考虑提升 /proc/sys/kernel/pid_max 的设置值。
Kubernetes允许管理员通过kubelet来限制每个Pod可以使用的PID数量,以避免某个Pod中的进程Kubernetes允许管理员通过kubelet来限制每个Pod可以使用的PID数量,以避免某个Pod中的进程消耗过多的系统资源,从而影响其他进程的正常运行。例如,如果节点上的宿主操作系统最多可使用262144个PID,同时预计节点上会运行的Pod个数不会超过250,那么可以为每个Pod设置1000个PID的预算,避免耗尽该节点上可用PID的总量。
虽然管理员可以像CPU或内存那样允许对PID进行过量分配(Overcommit),但这样做会有一些额外的风险。因此,任何一个Pod都不可以将整个机器的运行状态破坏。这类资源限制有助于避免简单的派生炸弹(Fork Bomb)影响到整个集群的运行。
在Pod级别设置PID限制使得管理员能够保护Pod之间不会互相伤害,但无法确保所有调度到该宿主机器上的所有Pod都不会影响到节点整体。Pod级别的限制也无法保护节点代理任务自身不会受到PID耗尽的影响。
此外,管理员还可以预留一定量的PID作为节点的额外开销,与分配给Pod的PID集合独立。这类似于在给操作系统和其它设施预留CPU、内存或其它资源时所做的操作,这些任务都在Pod及其所包含的容器之外运行。
需要注意的是,PID限制是与计算资源请求和限制相辅相成的一种机制。不过,需要用一种不同的方式来设置这一限制:需要将其设置到kubelet上而不是在Pod的.spec中为Pod设置资源限制。目前还不支持在Pod级别设置PID限制。
注意:Kubernetes 允许为系统预留一定量的进程 ID。为了配置预留数量,可以使用 kubelet 的 –system-reserved 和 –kube-reserved 命令行选项中的参数 pid=<number>,所设置的参数值分别用来声明为整个系统和 Kubernetes 系统守护进程所保留的进程 ID 数目。
二、节点级别PID限制
Kubernetes 允许为系统预留一定量的进程 ID。为了配置预留数量,可以使用 kubelet 的 –system-reserved 和 –kube-reserved 命令行选项中的参数 pid=<number>。所设置的参数值分别用来声明为整个系统和 Kubernetes 系统守护进程所保留的进程 ID 数目。
三、Pod级别PID限制
Kubernetes 允许限制 Pod 中运行的进程个数。可以在节点级别设置这一限制, 而不是为特定的 Pod 来将其设置为资源限制,且每个节点都可以有不同的 PID 限制设置。 要设置限制值,可以设置 kubelet 的命令行参数 –pod-max-pids,或者在 kubelet 的配置文件中设置 PodPidsLimit。
四、基于PID的驱逐
可以配置 kubelet,使其在 Pod 行为异常或消耗过多资源时将其终止,这一特性称为驱逐,可以针对不同的驱逐信号配置资源不足的处理,使用 pid.available 驱逐信号来配置 Pod 使用的 PID 个数的阈值,可以设置硬性和软性的驱逐策略。然而,即使使用硬性的驱逐策略,如果 PID 个数增长过快,节点仍然可能因为触及节点 PID 限制而进入一种不稳定状态。驱逐信号的取值是周期性计算的,而不是一直能够强制实施约束。
Pod 级别和节点级别的 PID 限制会设置硬性限制。一旦触及限制值,工作负载会在尝试获得新的 PID 时开始遇到问题,这可能会也可能不会导致 Pod 被重新调度,取决于工作负载如何应对这类失败以及 Pod 的存活性和就绪态探测是如何配置的。但是,如果限制值被正确设置,可以确保其他 Pod 负载和系统进程不会因为某个 Pod 行为异常而没有 PID 可用。