为了演示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有时间做出反应之前它会被内核杀死。
答案 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的时间更快,因此可能是明智之举尝试在脚本中更慢地分配内存。