【问题标题】:How can I OOM all BestEffort Pods in Kubernetes?如何 OOM Kubernetes 中的所有 BestEffort Pod?
【发布时间】:2018-08-17 23:28:44
【问题描述】:

为了演示 kubelet 的驱逐行为,我正在尝试部署一个 Kubernetes 工作负载,该工作负载将消耗内存到 kubelet 由于内存压力而驱逐所有 BestEffort Pod 但不会杀死我的工作负载(或至少不会在 BestEffort 之前)豆荚)。

我的最佳尝试如下。它写入两个 tmpfs 卷(因为默认情况下,tmpfs 卷的限制是节点总内存的一半)。 100 来自于在 kubelet 上设置了 --eviction-hard=memory.available<100Mi

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fallocate
  namespace: developer
spec:
  selector:
    matchLabels:
      app: fallocate
  template:
    metadata:
      labels:
        app: fallocate
    spec:
      containers:
      - name: alpine
        image: alpine
        command:
        - /bin/sh
        - -c
        - |
          count=1
          while true
          do          

            AVAILABLE_DISK_KB=$(df /cache-1 | grep /cache-1 | awk '{print $4}')
            AVAILABLE_DISK_MB=$(( $AVAILABLE_DISK_KB / 1000 ))
            AVAILABLE_MEMORY_MB=$(free -m | grep Mem | awk '{print $4}')
            MINIMUM=$(( $AVAILABLE_DISK_MB > $AVAILABLE_MEMORY_MB ?  $AVAILABLE_MEMORY_MB : $AVAILABLE_DISK_MB ))
            fallocate -l $(( $MINIMUM - 100 ))MB /cache-1/$count

            AVAILABLE_DISK_KB=$(df /cache-2 | grep /cache-2 | awk '{print $4}')
            AVAILABLE_DISK_MB=$(( $AVAILABLE_DISK_KB / 1000 ))
            AVAILABLE_MEMORY_MB=$(free -m | grep Mem | awk '{print $4}')
            MINIMUM=$(( $AVAILABLE_DISK_MB > $AVAILABLE_MEMORY_MB ?  $AVAILABLE_MEMORY_MB : $AVAILABLE_DISK_MB ))
            fallocate -l $(( $MINIMUM - 100 ))MB /cache-2/$count            

            count=$(( $count+1 ))
            sleep 1

          done
        resources:
          requests:
            memory: 2Gi
            cpu: 100m
          limits:
            cpu: 100m
        volumeMounts:
        - name: cache-1
          mountPath: /cache-1
        - name: cache-2
          mountPath: /cache-2
      volumes:
      - name: cache-1
        emptyDir:
          medium: Memory
      - name: cache-2
        emptyDir:
          medium: Memory

此脚本的目的是将内存耗尽到节点内存使用量处于硬驱逐阈值边界的程度,从而导致 kubelet 开始驱逐。它会驱逐一些 BestEffort Pod,但在大多数情况下,工作负载会在所有 BestEffort Pod 被驱逐之前被终止。有更好的方法吗?

我在集群版本 1.9.3-gke.0 的 GKE 上运行。

编辑:

我也尝试过使用 simmemleak:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: simmemleak
  namespace: developer
spec:
  selector:
    matchLabels:
      app: simmemleak
  template:
    metadata:
      labels:
        app: simmemleak
    spec:
      containers:
      - name: simmemleak
        image: saadali/simmemleak
        resources:
          requests:
            memory: 1Gi
            cpu: 1m
          limits:
            cpu: 1m

但是在任何驱逐之前,这种工作量一直在消失。我认为问题在于它在 kubelet 有时间做出反应之前就被内核杀死了。

【问题讨论】:

  • 您是否以任何方式更改了驱逐政策?顺便说一句,这个问题真的很有趣,我跟着。
  • @GalloCedrone 不,这是一个普通的 GKE 集群,我没有使用任何 PriorityClasses - 是的,我认为让我找到的工作更容易

标签: kubernetes google-cloud-platform google-kubernetes-engine


【解决方案1】:

为避免系统 OOM 在 kubelet 驱逐之前生效,您可以配置 kubepods 内存限制 --system-reserved--enforce-node-allocatable Read more

比如Node有32Gi的内存,配置kubepods内存最高20Gi

--eviction-hard=memory.available<500Mi

【讨论】:

    【解决方案2】:

    我在 Kubernetes docs 上找到了这个,希望对你有帮助:

    kubelet 可能无法立即观察到内存压力 kubelet 当前会定期轮询 cAdvisor 以收集内存使用统计信息。
    如果在该窗口内内存使用量迅速增加,kubelet 可能无法足够快地观察 MemoryPressure,OOMKiller 仍将被调用。
    我们打算在未来的版本中与 memcg 通知 API 集成以减少这种延迟,而是让内核在超过阈值时立即告诉我们。

    如果您不是试图实现极端利用率,而是一种合理的过度使用措施,解决此问题的可行解决方法是将驱逐阈值设置为大约 75% 的容量。
    这增强了此功能防止系统 OOM 并促进驱逐工作负载的能力,以便集群状态可以重新平衡。

    ==EDIT== :由于 OOM 和 kubelet 之间似乎存在竞争,并且您的脚本分配的内存增长速度快于 Kubelet 意识到需要驱逐 pod 的时间,因此明智的做法是尝试在脚本中更慢地分配内存。

    【讨论】:

    • 是的,我已经阅读了这篇文章,这就是我认为我遇到的问题,如编辑末尾所述 - 我正在寻找一个保持在驱逐阈值内足够长的示例kubelet 在没有内核的 OOM 杀手采取行动的情况下引起注意
    • 对不起,但这并没有真正帮助,我尝试了很多变化,包括减慢内存分配。我知道高级目标,它提出了一个我正在努力解决的实际示例
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-06
    • 2021-10-16
    • 2022-07-22
    • 1970-01-01
    • 2022-08-14
    • 2021-05-16
    相关资源
    最近更新 更多