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:集群所在的区域或可用区。
验证配置
如需验证是否已启用节点内存交换,请完成以下步骤:
运行以下命令,验证
system-config.yaml是否已应用swapConfig设置:gcloud beta container node-pools describe NODEPOOL_NAME \ --cluster=CLUSTER_NAME \ --location=LOCATION \ --format='yaml(config.linuxNodeConfig.swapConfig)'运行以下命令,验证节点上是否存在 kubelet 配置:
kubectl get --raw "/api/v1/nodes/NODE_NAME/proxy/configz" | jq .kubeletconfig.memorySwap
监控内存交换使用情况
您可以使用 Cloud Monitoring 或 kubectl 监控节点内存。
监控
默认情况下,以下系统指标可用于观察交换区使用情况:
kubernetes.io/node/memory/swap_used_byteskubernetes.io/container/memory/swap_used_bytes
GKE 还通过 cAdvisor 提供容器级交换区使用情况指标。如需使用这些指标,请在集群上启用 cAdvisor:
prometheus.googleapis.com/container_memory_swap/gauge
kubectl
通过完成以下步骤,使用 kubectl 命令监控交换空间使用情况:
运行以下命令,检查节点对象上的
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" }运行以下命令,检查交换容量:
kubectl get node NODE_NAME -o jsonpath='{.status.nodeInfo.swap}'输出类似于以下内容:
{"capacity":53687087104}
停用节点内存交换
如需停用节点内存交换,请通过完成以下步骤来更新 system-config.yaml 文件:
更新
system-config.yaml文件以将swapConfig.enabled设置为false:linuxNodeConfig: swapConfig: enabled: false使用新配置更新节点池:
gcloud beta container node-pools update NODEPOOL_NAME \ --cluster=CLUSTER_NAME \ --location=LOCATION \ --system-config-from-file=system-config.yaml