将节点配置为使用磁盘空间作为虚拟内存

Google Kubernetes Engine (GKE) 节点内存交换功能可让 GKE 节点在物理内存耗尽时使用磁盘空间作为虚拟内存。节点内存交换有助于提高应用弹性,并防止某些工作负载出现内存不足 (OOM) 错误。

何时使用节点内存交换

使用节点内存交换可为内存密集型应用提供缓冲,以防出现 OOM 错误,尤其是在出现意外的使用高峰时。节点内存交换有助于提高工作负载的弹性,例如在以下场景中:

  • 运行具有不可预测内存模式的工作负载。
  • 降低因节点内存耗尽而导致应用崩溃的风险。
  • 避免因偶尔出现高峰而过度预配内存,从而优化费用。

节点内存交换的工作原理

启用节点内存交换后,GKE 会将节点的操作系统配置为使用磁盘空间作为虚拟内存。此进程可为遇到临时内存压力的应用提供缓冲区。

GKE 会根据容器的内存资源限制和节点的总内存来计算容器交换限制

您可以针对不同的存储类型配置交换,以平衡性能和成本:

  • 启动磁盘:使用节点的启动磁盘作为交换空间。
  • 临时本地 SSD:使用也与 Pod 临时存储共享的本地 SSD。
  • 专用本地 SSD:专门为交换预留一个或多个本地 SSD。

为了保护敏感数据,GKE 默认使用临时密钥对交换空间进行加密。

要求和限制

节点内存交换有以下要求和限制:

  • GKE 集群必须为 1.34.1-gke.1341000 版或更高版本。
  • 只有具有 Burstable 服务质量 (QoS) 类的 Pod 才能使用节点内存交换。如需详细了解 QoS 类,请参阅 Kubernetes 文档中的 Pod 服务质量类
  • 如果您启用节点内存交换,则必须将容器调整大小政策设置为 RestartContainer
  • 如果您将节点内存交换配置为使用启动磁盘,则交换大小不得超过启动磁盘总容量的 50%。
  • 如果您将节点内存交换配置为使用本地 SSD,则机器类型必须支持本地 SSD。您无法将原始块存储与本地 SSD 搭配使用。

最佳做法

节点内存交换旨在为不可预测的内存峰值提供安全保障,而不是替代足够的物理内存。如需有关优化工作负载的指南,请参阅大规模调整工作负载大小

使用节点内存交换时,您还应考虑以下最佳实践:

  • 通过向节点池应用污点(例如 gke-swap=enabled:NoSchedule)并将相应的容忍添加到旨在利用交换空间的工作负载,来隔离启用了节点内存交换的节点。
  • 适当调整节点内存交换空间的大小。节点内存交换空间不足可能无法防止 OOM 错误,而过度使用则会降低性能。
  • 监控工作负载的节点内存交换使用情况。频繁使用节点内存交换空间可能表明内存压力过大。

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 命令以获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。

启用节点内存交换

您可以按集群或节点池启用节点内存交换。如需启用节点内存交换,请创建或更新包含所需节点内存交换配置的 system-config.yaml 文件。以下示例使用默认设置启用节点内存交换:

linuxNodeConfig:
  swapConfig:
    enabled: true

您还可以配置其他设置。此示例将未加密的交换配置为使用临时本地 SSD 存储空间的 30%:

linuxNodeConfig:
  swapConfig:
    enabled: true
    encryptionConfig:
      disabled: true
    ephemeral_local_ssd_profile:
      swapSizePercent: 30
ephemeralStorageLocalSsdConfig:
  localSsdCount: 1

在集群上启用节点内存交换

如需在集群上启用节点内存交换,请完成以下某个步骤:

  • 如需创建启用了节点内存交换的新集群,请运行以下命令:

    gcloud beta container clusters create CLUSTER_NAME \
        --location=LOCATION \
        --cluster-version=1.34.1-gke.1341000 \
        --system-config-from-file=system-config.yaml
    

    替换以下内容:

    • CLUSTER_NAME:新集群的名称。
    • LOCATION:集群所在的区域或可用区。
  • 如需更新现有集群以启用节点内存交换,请运行以下命令:

    gcloud beta container clusters update CLUSTER_NAME \
        --location=LOCATION \
        --system-config-from-file=system-config.yaml
    

    替换以下内容:

    • CLUSTER_NAME:新集群的名称。
    • LOCATION:集群所在的区域或可用区。

在节点池上启用节点内存交换

如需在节点池上启用节点内存交换,请完成以下任一步骤:

  • 如需创建启用了节点内存交换的新节点池,请运行以下命令:

    gcloud beta container node-pools create NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=LOCATION \
        --node-version=1.34.1-gke.1293000 \
        --system-config-from-file=system-config.yaml
    

    替换以下内容:

    • NODEPOOL_NAME:新节点池的名称。
    • CLUSTER_NAME:您的集群的名称。
    • LOCATION:集群所在的区域或可用区。
  • 如需更新现有节点池以启用节点内存交换,请运行以下命令:

    gcloud beta container node-pools update NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=LOCATION \
        --system-config-from-file=system-config.yaml
    

    替换以下内容:

    • NODEPOOL_NAME:节点池的名称。
    • CLUSTER_NAME:您的集群的名称。
    • LOCATION:集群所在的区域或可用区。

验证配置

如需验证是否已启用节点内存交换,请完成以下步骤:

  1. 运行以下命令,验证 system-config.yaml 是否已应用 swapConfig 设置:

    gcloud beta container node-pools describe NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=LOCATION \
        --format='yaml(config.linuxNodeConfig.swapConfig)'
    
  2. 运行以下命令,验证节点上是否存在 kubelet 配置:

    kubectl get --raw "/api/v1/nodes/NODE_NAME/proxy/configz" | jq .kubeletconfig.memorySwap
    

监控内存交换使用情况

您可以使用 Cloud Monitoring 或 kubectl 监控节点内存。

监控

默认情况下,以下系统指标可用于观察交换区使用情况:

  • kubernetes.io/node/memory/swap_used_bytes
  • kubernetes.io/container/memory/swap_used_bytes

GKE 还通过 cAdvisor 提供容器级交换区使用情况指标。如需使用这些指标,请在集群上启用 cAdvisor

  • prometheus.googleapis.com/container_memory_swap/gauge

kubectl

通过完成以下步骤,使用 kubectl 命令监控交换空间使用情况:

  1. 运行以下命令,检查节点对象上的 SwapDetected 条件:

    kubectl get node NODE_NAME -o jsonpath='{.status.conditions[?(@.type=="Swap")]}' | jq .
    

    输出类似于以下内容:

    {
      "lastHeartbeatTime": "2025-07-11T00:14:52Z",
      "lastTransitionTime": "2025-06-25T05:20:10Z",
      "message": "Swap is active: Total=49Gi Used=0B Free=49Gi",
      "reason": "SwapDetected",
      "status": "True",
      "type": "Swap"
    }
    
  2. 运行以下命令,检查交换容量:

    kubectl get node NODE_NAME -o jsonpath='{.status.nodeInfo.swap}'
    

    输出类似于以下内容:

    {"capacity":53687087104}
    

停用节点内存交换

如需停用节点内存交换,请通过完成以下步骤来更新 system-config.yaml 文件:

  1. 更新 system-config.yaml 文件以将 swapConfig.enabled 设置为 false

    linuxNodeConfig:
      swapConfig:
        enabled: false
    
  2. 使用新配置更新节点池:

    gcloud beta container node-pools update NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=LOCATION \
        --system-config-from-file=system-config.yaml
    

后续步骤