kubelet是Kubernetes中的主要节点组件,它执行许多关键任务。Kubelet主要职责在:
- 向kube-apiserver注册节点
- watch kube-apiserver中已经调度完成的Pod,并在Pod被调度完成之后告诉容器运行时(例如Docker)启动容器
- 监视运行中的容器并将其状态报告给kube-apiserver
- 执行活动性探针并在容器失败后重新启动容器
- 运行由kubelet直接管理的静态Pod
- 与Core Metrics Pipeline和容器运行时进行交互以收集容器和节点metrcis
我们在本文中要讨论的另一个重要的kubelet任务是,当节点资源耗尽时,“agent”具有将Pods逐出的功能。当计算资源(例如磁盘,RAM或CPU)不足时,kubelet在维护节点稳定性方面起着至关重要的作用。对于Kubernetes管理员来说,了解配置资源超过配额的最佳做法很有用,以使节点资源更灵活,同时保留系统的整体容错性和关键系统进程的稳定性。
Kubelet如何确定资源不足?
如前所述,kubelet可以从节点上驱逐工作负载,以释放资源来处理其他Pod和/或系统任务,例如容器运行时或kubelet本身。但是,kubelet如何确定资源不足?
Kubelet根据收回信号和收回阈值确定何时回收资源。驱逐信号是系统资源(如内存或存储器)的当前容量。反过来,驱逐阈值是kubelet应该维护的此资源的最小值。
换句话说,每个驱逐信号都与某个驱逐阈值相关联,该阈值告诉kubelet何时开始回收资源。目前,支持以下驱逐信号:
-
memory.available
— 描述集群内存状态的信号。内存的默认逐出阈值为100Mi。换句话说,当内存下降到100 Mi时,kubelet开始驱逐Pod。 -
nodefs.available
— nodefs是kubelet用于卷,守护程序日志等的文件系统。默认情况下,如果nodefs.available <10%,则kubelet开始回收节点资源。 -
nodefs.inodesFree
— 描述nodefs索引节点内存状态的信号。默认情况下,如果nodefs.inodesFree <5%,则kubelet将开始驱逐工作负载。 -
imagefs.available
— imagefs文件系统是容器运行时使用的可选文件系统,用于存储容器镜像和容器可写层。默认情况下,如果imagefs.available <15%,则kubelet开始驱逐工作负载。 -
imagefs.inodesFree
— imagefs索引节点内存的状态。它没有默认驱逐阈值。
上述驱逐阈值是非常合理的默认值。但是,用户可以通过在kubelet二进制文件上设置适当的标志来配置其自定义逐出阈值。这些用户定义的阈值可以更改默认的kubelet驱逐行为。
目前,Kubernetes支持硬驱和软驱逐阈值。
如果达到硬驱逐阈值,则kubelet将立即开始回收资源,而没有任何宽限期。相反,软驱逐阈值包括用户定义的宽限期,该宽限期应在kubelet开始回收任何资源之前到期。
您可以使用kubelet二进制文件上的--eviction-hard
标志定义硬驱逐阈值。例如,kubelet-eviction-hard = memory.available <1Gi
将告诉kubelet在节点的memory.available
低于1Gi时开始回收资源。
如果要在驱逐之前允许宽限期,则可以将-eviction-soft
标志与--eviction-soft-grace-period
标志结合使用。例如,kubelet —- eviction-soft=memory.available<2Gi
和kubelet —- eviction-soft-grace-period=1m30s
将使驱逐阈值保持90秒,然后触发驱逐阈值。
用户还可以通过以秒为单位设置--eviction-max-pod-grace-period
来指定允许的最大宽限期。
Kubelet如何回收资源?
Kubelet以用户Pod的利益为代价来回收资源。它首先尝试回收未使用的容器镜像或 dead 的Pod。
如果节点具有专用的imagefs
文件系统以及nodefs
文件系统,则kubelet会以不同的方式回收节点资源。在这种情况下,如果nodefs
达到驱逐阈值,则kubelet会删除所有已失效的Pod及其容器。相应地,如果imagefs
达到驱逐阈值,则kubelet会删除所有未使用的容器镜像。
如果没有使用imagefs
,则kubelet首先删除所有无效的Pod及其容器,然后删除所有未使用的镜像。有关此过程的更多信息,请参见Kubernetes文档。
如果回收容器镜像,失效的Pod和其他资源没有导致资源匮乏,则kubelet将删除用户Pod作为最后的选择。 kubelet根据Pod的QoS等级,Pod优先级和下面讨论的许多其他参数,决定退出哪个用户Pod。在描述此过程之前,让我们回顾一下Kubernetes中的基本QoS类。
Pod的Qos共分为Guaranteed,Burstable或Best-Effort。
-
Guaranteed
: 在Pod的所有容器中都为CPU和RAM设置资源限制和请求,并且它们的值相等。 -
Burstable
Pod中一个或多个容器的资源(例如,CPU,RAM)设置了请求和限制的容器,它们不相等。 -
Best-Effort
Pod中的容器未设置资源限制。
此QoS模型由kubelet在其Pod排序方案中隐式使用。通常,kubelet使用以下规则对驱逐候选人进行排名:
- Pod是否超出其资源请求。在Kubernetes中,Pod是根据其请求而不是限制进行调度的。因此,保证所有容器和Pod都具有它们所请求的RAM / CPU数量。但是,如果没有设置限制,并且Pod超出了其资源请求,则在保证Pod或某些系统任务需要受限资源的情况下,可以终止或限制该Pod。在某些情况下,甚至那些消耗少于要求量的Pod也会被杀死。例如,当系统任务内存严重不足并且没有较低优先级的Pod被杀死时。
- 按Pod优先级排列。如果没有Pod超出其请求,则kubelet会检查Pod Priority。它将尝试先驱逐优先级较低的Pod。注意:在Kubernetes 1.14中,Pod的优先级和抢占式迁移到了GA。从1.11开始默认启用它们。您可以在本文中了解有关Pod Priority的更多信息。
根据这些规则,kubelet会按以下顺序驱逐用户Pod:
- 驱逐的第一个候选对象是Best-Effort 和/或 Burstable的Pod,其受限资源的使用超出了请求。如果有多个此类Pod,则kubelet会按优先级对它们进行排序,然后将资源消耗按指定的请求进行排序。
- 最后驱逐了资源使用量低于请求的Guaranteed 和 Burstable Pods的Pod。但是,如果某些系统任务(如kubelet或Docker)需要更大的资源,并且节点上没有Best-EffortPod,则kubelet可以驱逐消耗量低于其请求量的Guaranteed Pod。在这种情况下,它将首先以最低优先级驱逐Guaranteed 和 Burstable Pods。
最低驱逐收回
如果kubelet回收的资源量很小,则系统可以反复达到驱逐阈值。这不是理想的行为,因为它可能导致不良的调度决策和Pods频繁驱逐。为了避免这种情况,用户可以使用kubelet二进制文件上的-eviction-minimum-reclaim
标志设置每个资源的最小回收级别。
例如,查看下面的kubelet配置:
--eviction-hard=memory.available<1Gi,nodefs.available<2Gi,imagefs.available<200Gi
--eviction-minimum-reclaim=memory.available=0Mi,nodefs.available=1Gi,imagefs.available=2Gi
—- eviction-minimum-reclaim
设置可确保回收后可用的nodefs最小存储量为3Gi,可用的imagefs最小存储量为202 Gi。因此,以上配置可确保系统具有足够的可用资源,以避免非常频繁地达到收回阈值。
资源匮乏的处理配置不当可能遇到的另一个潜在问题是节点条件的波动。当kubelet收到逐出信号时,后者会映射到相应的节点条件。例如,当达到memory.available逐出阈值时,kubelet将MemoryPressure节点条件分配给该节点。此条件与相应的污点关联,该污点可防止在具有MemoryPressure节点条件的节点上调度新Pod。
但是,如果您使用具有较长宽限期的软驱逐阈值,则节点条件可能会在宽限期内在true和false之间振荡。这可能会导致驱逐不确定性,并因此导致不良的调度决策。为避免这种情况,您可以在kubelet上使用-- eviction-pressure-transition-period
标志,该标志定义kubelet在满足驱逐条件之前必须等待多长时间。
一个简单的资源短缺处理方案
现在,我们将说明如何为K8s集群配置资源不足的处理。让我们想象一个简单的场景,其中仅考虑节点RAM。假设我们节点的内存容量为10 Gi RAM。我们希望为内核,kubelet,Docker等系统守护进程保留总内存的10%。我们还希望驱逐Pods,使其占用95%的内存。
使用默认逐出阈值启动kubelet,并且没有系统保留。我们需要在kubelet上显式设置几个标志,以启用所需的行为。
为了实现我们的目标,我们需要在kubelet上设置以下标志:
eviction-hard=memory.available<500Mi
system-reserved=memory=1.5Gi
如您所见,系统保留设置为1.5Gi,尽管直观上应将其设置为10%= 1Gi。但是,“系统保留”应包括驱逐阈值(1Gi + .5Gi)覆盖的内存量。
根据配置K8s集群的方式,可以不同地设置kubelet标志。例如,如果计划使用Kops配置K8s集群,请运行kops edit cluster $NAME以使用集群配置打开编辑器。如果是VI编辑器,则按“ I”进入插入模式以编辑文件。上述资源不足处理策略的kubelet标志应如下所示:
kubelet:
eviction-hard=memory.available<500Mi
system-reserved=memory=1.5Gi
结论
在本文中,我们讨论了一些有用的Kubernetes管理实践,用于在Kubernetes中自定义kubelet超出资源的管理。该平台允许管理员设置自定义逐出阈值和逐出宽限期,以决定哪些条件被视为对节点稳定性有害。但是,有了这种自由,就要承担很多责任。 Kubernetes附带了合理的资源短缺管理默认设置。因此,在将驱逐阈值设置得太高或将驱逐宽限期设置得太长时,您应保持谨慎。
PS: 本文属于翻译,原文
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。