Kubernetes--资源限制

161 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第31天,点击查看活动详情

容器的资源需求仅能达到为其保证可用的最少资源量的目的,它并不会限制容器的可用资源上限,因此对因应用程序自身存在Bug等多种原因而导致的系统资源被长时间占用的情况则无计可施,这就需要通过timits属性为容器定义资源的最大可用量。资源分配时,可压缩型资源CPU的控制阀可自由调节,容器进程无法获得超出其CPU配额的可用时间。不过,如果进程申请分配超出其limits属性定义的硬限制的内存资源时,它将被OOM killer杀死,不过,随后可能会被其控制进程所重启,例如,容器进程的Pod对象会被杀死并重启(重启策略为Always或OnFailure时),或者是容器进程的子进程被其父进程所重启。

下面的配置清单文件(memleak-pod.yaml)中定义了如何使用saadali/simmemleak镜像运行一个Pod对象,它模拟内存泄漏操作不断地申请使用内存资源,直到超出limits属性中memory字段设定的值而导致“OOMKilled”为止:

apiVersion: v1
kind: Pod
metadata:
  name: memleak-pod
  labels:
    app: memleak
spec:
  containers:
  - name: simmemleak
    image: saadali/simmemleak
    resources:
      requests:
        memory: "64Mi"
        cpu: "1"
      limits:
        memory: "64Mi"
        cpu: "1"

下面测试其运行结果,首先将配置清单中定义的资源复用下面的命令创建于集群中:

kubectl apply -f memleak-pod.yaml
pod/memleak created

pod资源的默认重启策略为Always,于是在memleak因内存资源达到硬限制而被终止后会立即重后,因此很难观察到其因OOM而被杀死的相关信息。不过,多次重复地因为内存资源耗尽而重启会触发Kubernetes系统的重启延迟机制,即每次重启的时间间隔会不断地拉长。于是,看到的Pod资源的相关状态通常为“CrashLoopBackOff”:

kubectl get pods -l app=memleak
NAME          READY   STATUS             RESTARTS   AGE
memleak-pod   0/1     CrashLoopBackOff   119        43d

Pod资源首次的重启将在crash后立即完成,若随后再次crash,那么其重启操作会延迟10秒进行,随后的延迟时长会逐渐增加,依次为20秒、40秒、80秒、160秒和300秒,随后的延迟将固定在5分钟的时长之上而不再增加,直到其不再crash或者delete为止。

describe命令可以显示其状态相关的详细信息,其部分内容如下所示:

kubectl describe pods memleak-pod 
Name:         memleak-pod
······
Last State:     Terminated
      Reason:       OOMKilled
      Exit Code:    137
      Started:      Mon, 10 Oct 2022 09:20:14 +0800
      Finished:     Mon, 10 Oct 2022 09:20:14 +0800
    Ready:          False
    Restart Count:  119
······

如上述命令结果所显示的,OOMKilled表示容器因内存耗尽而被终止,因此,为limits属性中的memory设置一个合理值至关重要。与requests不同的是,limits并不会影响Pod的调度结果,也就是说,一个节点上的所有Pod对象的limits数量之和可以大于节点所拥有的资源量,即支持资源的过载使用(overcommitted)。不过,这么一来一旦资源耗尽,尤其是内存资源耗尽,则必然会有容器因OOMKilled而终止。

另外需要说明的是,Kubernetes仅会确保Pod能够获得它们请求(requests)的CPU时间额度,它们能否获得额外(throttled)的CPU时间,则取决于其他正在运行的作业对CPU资源的占用情况。例如对于总数为1000m的CPU资源来说,容器A请求使用200m,容器B请求使用S00m,在不超出它们各自的最大限额的前提下,余下的300m在双方都需要时会以2:5(200m:500m)的方式进行配置。