我怎样才能在Kubernetes中使用所有BestEffort Pod?

时间:2018-03-09 11:40:22

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

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

我最好的尝试如下。它写入两个tmpfs卷(因为默认情况下,tmpfs卷的限制是Node的总内存的一半)。 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开始逐出。它驱逐了一些BestEfforts Pods,但在大多数情况下,工作负载在所有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有时间做出反应之前它会被内核杀死。

2 个答案:

答案 0 :(得分:0)

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

例如,Node具有32Gi的内存,配置为将kubepods的内存限制为最大20Gi

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

答案 1 :(得分:-1)

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

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

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

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