借助 Google Kubernetes Engine (GKE) 节点内存交换,GKE 节点可以在物理内存耗尽时将磁盘可用空间用作虚拟内存。节点内存交换有助于提高应用弹性,并防止某些工作负载出现内存不足 (OOM) 错误。
何时使用节点内存交换
使用节点内存交换可为内存密集型应用提供针对 OOM 错误的缓冲区,尤其是在意外使用高峰期间。节点内存交换有助于提高工作负载弹性,例如在以下场景中:
- 运行具有不可预测内存模式的工作负载。
- 降低应用因节点内存耗尽而崩溃的风险。
- 避免为应对偶尔出现的峰值而过度预配内存,从而优化费用。
节点内存交换的工作原理
启用节点内存交换后,GKE 会将节点的操作系统配置为使用磁盘可用空间作为虚拟内存。此过程可为遇到临时内存压力的应用提供缓冲区。
GKE 会根据容器的内存资源限制和节点的总内存计算容器交换限制。
您可以在不同的存储类型上配置交换,以平衡性能和费用:
- 启动磁盘:使用节点的启动磁盘作为交换空间。
- 临时本地 SSD:使用也与 Pod 临时存储共享的本地 SSD。如果节点使用混合本地 SSD 容量,则交换空间仅使用本地 SSD 的临时存储部分。
- 专用本地 SSD:预留一个或多个本地 SSD 专门用于交换。
为了保护敏感数据,GKE 默认使用临时密钥对交换空间进行加密。
要求和限制
节点内存交换具有以下要求和限制:
- GKE 集群必须为
1.34.1-gke.1341000版或更高版本。 - 只有具有
Burstable服务质量 (QoS) 类的 Pod 才能使用节点内存交换。如需详细了解 QoS 类,请参阅 Kubernetes 文档中的 Pod 服务质量类。 - 如需调整容器的内存资源大小,您必须将容器大小调整政策设置为
RestartContainer。 - 如果您将节点内存交换配置为使用启动磁盘,则交换大小不能超过启动磁盘总容量的 50%。
如果您将节点内存交换配置为使用本地 SSD,则必须确保满足以下要求:
- 机器类型必须支持本地 SSD。您只能使用预配为临时存储空间或混合存储空间的本地 SSD。您无法使用预配为原始块存储设备的本地 SSD。如需查看此模式下支持的交换配置文件列表,请参阅具有混合本地 SSD 容量的节点内存交换。
- 节点必须预配本地 SSD。预配方法取决于机器系列:
- 对于第一代或第二代机器系列,请设置
--ephemeral-storage-local-ssd=count标志。 - 对于第三代或第四代机器系列,请选择捆绑了本地 SSD 的机器类型。
- 对于第一代或第二代机器系列,请设置
- 默认的
e2-medium机器类型不支持本地 SSD,因此您必须选择其他机器类型。 - 如需了解如何创建或更新集群以预配本地 SSD,请参阅预配和使用本地 SSD 支持的临时存储空间。
最佳做法
节点内存交换旨在作为不可预测的内存峰值的安全网,而不是替代足够的物理内存。如需有关优化工作负载的指导,请参阅大规模合理调整 GKE 工作负载容量。
使用节点内存交换时,您还应考虑以下最佳实践:
- 通过向节点池应用污点(例如
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 文件。以下示例使用默认设置启用节点内存交换:
linuxConfig:
swapConfig:
enabled: true
您还可以配置其他设置。以下示例将未加密的交换空间配置为使用临时本地 SSD 存储空间的 30%:
linuxConfig:
swapConfig:
enabled: true
encryptionConfig:
disabled: true
ephemeralLocalSsdProfile:
swapSizePercent: 30
如需查看您可以配置的可选字段列表,请参阅 LinuxNodeConfig API 文档。
在集群上启用节点内存交换
如需在集群上启用节点内存交换,请完成以下任一步骤:
如需创建启用了节点内存交换的新集群,请运行以下命令:
gcloud 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 container clusters update CLUSTER_NAME \ --location=LOCATION \ --system-config-from-file=system-config.yaml替换以下内容:
CLUSTER_NAME:新集群的名称。LOCATION:集群所在的区域或可用区。
在节点池池上启用节点内存交换
如需在节点池池上启用节点内存交换,请完成以下任一步骤:
如需创建启用了节点内存交换的新节点池,请运行以下命令:
gcloud 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 \ --machine-type=MACHINE_TYPE替换以下内容:
NODEPOOL_NAME:新节点池的名称。CLUSTER_NAME:您的集群的名称。LOCATION:集群所在的区域或可用区。MACHINE_TYPE:兼容的机器类型。对于本地 SSD,请确保选择捆绑了本地 SSD 的机器类型,例如n1-standard-1。
如需更新现有节点池以启用节点内存交换,请运行以下命令:
gcloud container node-pools update NODEPOOL_NAME \ --cluster=CLUSTER_NAME \ --location=LOCATION \ --system-config-from-file=system-config.yaml替换以下内容:
NODEPOOL_NAME:节点池的名称。CLUSTER_NAME:您的集群的名称。LOCATION:集群所在的区域或可用区。
验证配置
如需验证是否已启用节点内存交换,请完成以下步骤:
通过运行以下命令,验证是否已使用
swapConfig设置应用system-config.yaml:gcloud 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}
具有混合本地 SSD 容量的节点内存交换
您可以在预配混合本地 SSD 的节点池上启用节点内存交换。GKE 支持以下交换配置文件:
- 启动磁盘 (
bootDiskProfile) - 临时本地 SSD (
ephemeralLocalSsdProfile):GKE 从本地 SSD 的临时存储部分(而非原始块分区)分配交换空间。
GKE 不支持将专用本地 SSD 交换配置文件 (dedicatedLocalSsdProfile) 与混合本地 SSD 搭配使用。
如果您使用临时本地 SSD 配置文件,请注意以下事项:
swapSizePercent字段是您使用capacity子字段设置的临时容量的百分比,而不是物理本地 SSD 总容量。例如,如果设置了capacity=200GB和swapSizePercent: 20,GKE 会分配 40 GiB 的交换空间。- 交换空间会减少 Pod 可用的临时存储空间。 GKE 会根据临时容量减去交换空间大小来计算预留的临时存储空间。
- 交换空间大小不能超过临时容量的 80% 减去 GKE 为系统预留的临时存储空间。如果临时容量太小,无法容纳交换,则请求会失败。
以下示例 system-config.yaml 文件将 20% 的临时容量分配给交换空间:
linuxConfig:
swapConfig:
enabled: true
ephemeralLocalSsdProfile:
swapSizePercent: 20
如需创建具有混合本地 SSD 容量和节点内存交换的节点池,请运行以下命令:
gcloud container node-pools create POOL_NAME \
--cluster=CLUSTER_NAME \
--machine-type=MACHINE_TYPE \
--ephemeral-storage-local-ssd count=NUMBER_OF_DISKS,capacity=CAPACITY \
--system-config-from-file=system-config.yaml
替换以下内容:
POOL_NAME:要创建的新节点池的名称。CLUSTER_NAME:集群的名称。MACHINE_TYPE:要使用的机器类型。您无法将本地 SSD 与默认的e2-medium机器类型搭配使用,因为共享核心机器类型不支持本地 SSD。NUMBER_OF_DISKS:每个节点上预配的本地固态硬盘的数量。CAPACITY:要格式化以用作临时存储的本地 SSD 总容量。此值必须大于 0 且严格小于本地 SSD 物理总容量(磁盘数量 × 每个磁盘的大小),例如200GB。
停用节点内存交换
如需停用节点内存交换,请完成以下步骤来更新 system-config.yaml 文件:
更新
system-config.yaml文件,将swapConfig.enabled设置为false:linuxConfig: swapConfig: enabled: false使用新配置更新节点池:
gcloud container node-pools update NODEPOOL_NAME \ --cluster=CLUSTER_NAME \ --location=LOCATION \ --system-config-from-file=system-config.yaml