ディスク容量を仮想メモリとして使用するようにノードを構成する

Google Kubernetes Engine(GKE)のノードのメモリスワップを使用すると、物理メモリが不足した場合に、GKE ノードでディスク容量を仮想メモリとして使用できます。ノードのメモリスワップは、アプリケーションの復元力を高め、特定のワークロードでメモリ不足(OOM)エラーを防ぐのに役立ちます。

ノードのメモリスワップを使用するタイミング

ノードのメモリスワップを使用して、メモリ使用量の多いアプリケーションの OOM エラーに対するバッファを提供します。特に、予期しない使用量の急増時に有効です。ノードのメモリスワップは、次のようなシナリオでワークロードの復元力を高めるのに役立ちます。

  • メモリのパターンが予測不可能なワークロードを実行する。
  • ノードのメモリ不足によりアプリケーションがクラッシュするリスクを軽減する。
  • 一時的なピークのためにメモリを過剰にプロビジョニングする必要がないため、費用を最適化する。

ノードのメモリスワップの仕組み

ノードのメモリスワップを有効にすると、GKE はディスク容量を仮想メモリとして使用するようにノードのオペレーティング システムを構成します。このプロセスにより、一時的なメモリ負荷が発生したアプリケーションにバッファが提供されます。

GKE は、コンテナのメモリリソースの上限とノードの総メモリ量に基づいて、コンテナ スワップの上限を計算します。

さまざまなストレージ タイプでスワップを構成して、パフォーマンスと費用のバランスを取ることができます。

  • ブートディスク: スワップ領域にノードのブートディスクを使用します。
  • エフェメラル ローカル SSD: Pod のエフェメラル ストレージとも共有されるローカル SSD を使用します。ノードが混合ローカル SSD 容量を使用している場合、スワップはローカル SSD のエフェメラル ストレージ部分のみを使用します。
  • 専用ローカル SSD: 1 つ以上のローカル SSD をスワップ専用に予約します。

機密データを保護するため、GKE はデフォルトでエフェメラル鍵を使用してスワップ領域を暗号化します。

要件と制限事項

ノードのメモリスワップには、次の要件と制限事項があります。

  • GKE クラスタはバージョン 1.34.1-gke.1341000 以降である必要があります。
  • Burstable クラスの Quality of Service(QoS)を持つ Pod のみがノードのメモリスワップを使用できます。QoS クラスの詳細については、Kubernetes ドキュメントの Pod の Quality of Serviceをご覧ください。
  • コンテナのメモリリソースのサイズを変更するには、コンテナのサイズ変更ポリシーを RestartContainer に設定する必要があります。
  • ブートディスクを使用するようにノードのメモリスワップを構成する場合、スワップサイズはブートディスクの総容量の 50% を超えることはできません。

ローカル SSD を使用するようにノードのメモリスワップを構成する場合は、次の要件が満たされていることを確認する必要があります。

  • ローカル SSD をサポートするマシンタイプでなければなりません。使用できるのは、エフェメラル ストレージまたは混合ストレージとしてプロビジョニングされたローカル SSD のみです。raw ブロック デバイス ストレージとしてプロビジョニングされたローカル SSD は使用できません。このモードでサポートされているスワップ プロファイルの一覧については、ローカル SSD の容量が混在するノードのメモリスワップをご覧ください。
  • ノードはローカル SSD でプロビジョニングする必要があります。プロビジョニング方法は、マシンシリーズによって異なります。
    • 第 1 世代または第 2 世代のマシンシリーズの場合は、--ephemeral-storage-local-ssd=count フラグを設定します。
    • 第 3 世代または第 4 世代のマシンシリーズの場合は、ローカル SSD をバンドルするマシンタイプを選択します。
  • デフォルトの e2-medium マシンタイプはローカル SSD をサポートしていないため、別のマシンタイプを選択する必要があります。
  • ローカル SSD をプロビジョニングするようにクラスタを作成または更新する手順については、ローカル SSD を使用するエフェメラル ストレージをプロビジョニングして使用するをご覧ください。

ベスト プラクティス

ノードのメモリスワップは、十分な物理メモリの代わりではなく、予測不可能なメモリのスパイクに対する安全ネットとして使用することを目的としています。ワークロードの最適化に関するガイダンスについては、GKE ワークロードのサイズ適正化を大規模に行うをご覧ください。

ノードのメモリスワップを使用する場合は、次のベスト プラクティスも考慮する必要があります。

  • ノードプールに taint を適用(gke-swap=enabled:NoSchedule など)し、スワップを使用するワークロードに対応する toleration を追加して、ノードのメモリスワップ対応ノードを分離します。
  • ノードのメモリスワップ領域のサイズを適切に設定します。ノードのメモリスワップ領域が不足していると、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: クラスタのリージョンまたはゾーン。

構成を確認する

ノードのメモリスワップが有効になっていることを確認するには、次の操作を行います。

  1. 次のコマンドを実行して、system-config.yaml が swapConfig 設定で適用されていることを確認します。

    gcloud 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}
    

ローカル SSD の容量が混在するノードのメモリスワップ

混合ローカル SSD をプロビジョニングするノードプールでノードのメモリスワップを有効にできます。GKE は、次のスワップ プロファイルをサポートしています。

  • ブートディスク(bootDiskProfile)
  • エフェメラル ローカル SSD(ephemeralLocalSsdProfile): GKE は、未加工ブロック パーティションではなく、ローカル SSD のエフェメラル ストレージ部分からスワップ領域を割り当てます。

GKE は、混合ローカル SSD を使用する専用のローカル SSD スワップ プロファイル(dedicatedLocalSsdProfile)をサポートしていません。

エフェメラル ローカル 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: 各ノードでプロビジョニングするローカル SSD ディスクの数。
  • CAPACITY: エフェメラル ストレージ用にフォーマットするローカル SSD の合計容量。この値は 0 より大きく、物理ローカル SSD の合計容量(ディスク数 × ディスクあたりのサイズ、例: 200GB)より小さくする必要があります。

ノードのメモリスワップを無効にする

ノードのメモリスワップを無効にするには、次の手順で system-config.yaml ファイルを更新します。

  1. system-config.yaml ファイルを更新して、swapConfig.enabled を false に設定します。

    linuxConfig:
      swapConfig:
        enabled: false
    
  2. 新しい構成でノードプールを更新します。

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

次のステップ