You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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,比如:
    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
    
    这样当容器内存使用达到512Mi时,会开始使用Swap,而不是直接被OOMKilled。

注意事项

  • COS的所有系统级配置都要通过实例元数据或者cloud-init来修改,不要尝试直接修改只读的根文件系统,否则重启后会失效。
  • 启用Swap可能会影响容器的性能,毕竟Swap的读写速度比内存慢很多,所以要根据你的业务场景调整Swap的大小和Pod的限制配置。

内容的提问来源于stack exchange,提问作者Jesse Shieh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:17:16