如何在Google Container Optimized OS上启用Swap限制支持
解决Google Container Optimized OS上Docker/Kubernetes的Swap限制支持问题
我之前在GCE的Container Optimized OS(COS)上也碰到过一模一样的问题——容器一触碰到内存限制就被OOMKilled,完全不会用Swap当缓冲,docker info最后一行还显示没有Swap限制支持。毕竟COS的架构和Ubuntu/Debian差异很大,常规的配置方法根本不适用,下面是我亲测有效的解决步骤:
一、确认并启用系统Swap
COS默认没有启用Swap,所以首先得先给实例配置Swap空间:
- 临时启用(重启后失效):
# 创建Swap文件(这里设置为4G,你可以按需调整) sudo fallocate -l 4G /mnt/disks/state/swapfile sudo chmod 600 /mnt/disks/state/swapfile sudo mkswap /mnt/disks/state/swapfile sudo swapon /mnt/disks/state/swapfile - 持久化启用(重启后生效):
因为COS的根文件系统是只读的,所以要通过自定义实例元数据添加启动脚本:- 打开GCE控制台,找到你的COS实例
- 编辑实例,在「自定义元数据」里添加键为
user-data,值为下面的cloud-init脚本:#cloud-config bootcmd: - fallocate -l 4G /mnt/disks/state/swapfile - chmod 600 /mnt/disks/state/swapfile - mkswap /mnt/disks/state/swapfile - swapon /mnt/disks/state/swapfile
二、启用Docker的Swap限制支持
COS的Docker daemon配置不能直接编辑/etc/docker/daemon.json(因为只读),需要通过实例元数据来修改:
- 同样在实例的「自定义元数据」里,添加键为
docker-daemon-config,值为:
重点是加上{ "experimental": false, "storage-driver": "overlay2", "default-runtime": "runsc", "runtimes": { "runsc": { "path": "/usr/bin/runsc" } }, "exec-opts": ["native.cgroupdriver=cgroupfs"], "storage-opts": ["overlay2.override_kernel_check=true"], "memory-swap": "-1" }"memory-swap": "-1",这个配置允许容器使用的Swap等于内存限制值(如果Pod里配置了memory限制的话),或者你也可以设置具体数值。 - 重启实例让配置生效,之后执行
docker info,应该就能看到Swap限制支持已启用。
三、配置Kubernetes Pod使用Swap缓冲
现在需要让K8s的Pod允许使用Swap,避免直接OOMKilled:
- 首先要修改kubelet的配置,因为COS的kubelet配置也是通过元数据管理的:
- 在实例元数据里添加键为
kubelet-config,值为:
这里的apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration featureGates: NodeSwap: true memorySwap: swapBehavior: "AllowSwap"NodeSwap特性门控要开启,swapBehavior设置为AllowSwap允许Pod使用Swap。
- 在实例元数据里添加键为
- 然后在Pod的配置里,除了设置
resources.limits.memory,还要加上resources.limits.memorySwap,比如:
这样当容器内存使用达到512Mi时,会开始使用Swap,而不是直接被OOMKilled。apiVersion: v1 kind: Pod metadata: name: test-swap-pod spec: containers: - name: test-container image: nginx resources: limits: memory: "512Mi" memorySwap: "1Gi" # 这里设置为内存限制的2倍,允许容器用512Mi内存+512Mi Swap
注意事项
- COS的所有系统级配置都要通过实例元数据或者cloud-init来修改,不要尝试直接修改只读的根文件系统,否则重启后会失效。
- 启用Swap可能会影响容器的性能,毕竟Swap的读写速度比内存慢很多,所以要根据你的业务场景调整Swap的大小和Pod的限制配置。
内容的提问来源于stack exchange,提问作者Jesse Shieh
相关产品推荐
相关产品推荐

