すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:コンテナのメモリ QoS の有効化

最終更新日:Jun 18, 2026

ack-koordinator を使用して、遅延の影響を受けやすいコンテナのメモリを優先し、競合時の OOM エラーを削減します。

説明 メモリ QoS を使用する前に、Kubernetes ドキュメントの Pod のサービス品質 (QoS) クラスおよび コンテナと Pod へのメモリリソースの割り当てをご参照ください。

仕組み

Kubernetes は各 Pod にメモリリクエストとメモリリミットを割り当てます。メモリ負荷が高い状況では、次の 2 種類の障害モードが発生します。

  • コンテナレベルの負荷:コンテナのメモリ使用量 (ページキャッシュを含む) がリミットに近づくと、OS は memcg レベルの直接再利用をトリガーし、プロセスをブロックします。割り当てが再利用を上回ると、OOM エラーが発生して Pod が終了します。

  • ノードレベルの負荷:コンテナのメモリリミットの合計がノードの物理メモリを超えると、カーネルはコンテナ間で無差別にメモリを再利用し、パフォーマンスが低下し、OOM エラーがトリガーされる可能性があります。

image

ack-koordinator は、コンテナごとにメモリコントロールグループ (memcg) を設定することで、これら両方の問題に対処します。これには、3 つの Alibaba Cloud Linux (Alinux) カーネル機能が使用されます。

  • Memcg QoS:最小メモリ量をロックし、優先度の高いコンテナがワーキングセットを保持できるようにします。

  • Memcg バックエンド非同期再利用:リミットに達する前に積極的にメモリを再利用し、直接再利用によるブロッキングを回避します。

  • Memcg グローバル最小ウォーターマーク評価:コンテナごとの再利用しきい値を調整し、遅延の影響を受けやすい (LS) コンテナが最後に再利用されるようにします。

これにより、オーバーコミット時のメモリ配分がより公平になり、レイテンシーが低下します。

オープンソースの Kubernetes メモリ QoS に対する利点

アップストリームの Kubernetes の メモリ QoS 機能 (Kubernetes 1.22 以降) は cgroup v2 のみをサポートし、手動での kubelet 設定が必要で、Pod 単位または名前空間単位の粒度には対応していません。

ack-koordinator は、次の 2 つの点でアップストリームの実装を改善しています。

  • 幅広いカーネル互換性:cgroup v1 と v2 をサポートし、memcg バックエンド非同期再利用や最小ウォーターマーク評価などの Alinux カーネル機能によって支えられています。詳細については、「カーネル機能とインターフェイスの概要」をご参照ください。

  • 詳細な設定:Pod アノテーションまたは ConfigMap を通じて、Pod、名前空間、またはクラスターごとにメモリ QoS を設定できます。

設定メカニズム

ack-koordinator は、メモリ QoS に 4 つの cgroup パラメーターを使用します。それぞれが「詳細パラメーター」の設定オプションにマッピングされます。

cgroup パラメーター 操作 設定元
memory.limit_in_bytes コンテナのハード上限 Kubernetes (limits.memory から)
memory.high スロットリングのしきい値 — ここから再利用が開始 throttlingPercent
memory.wmark_high 非同期再利用のトリガー wmarkRatio
memory.min 再利用不可能なメモリの下限 minLimitPercent / lowLimitPercent

設定の優先順位

複数の設定ソースが同じ Pod に適用される場合、ack-koordinator は次の優先順位 (高い順) を使用します。

  1. Pod アノテーション (koordinator.sh/memoryQOS)

  2. 名前空間レベルの ConfigMap (ack-slo-pod-config)

  3. クラスターレベルの ConfigMap (ack-slo-config)

QoS クラスのマッピング

Pod に koordinator.sh/qosClass ラベルがない場合、ack-koordinator は Kubernetes の QoS クラスを自動的にマッピングします。

Kubernetes QoS クラス koordinator QoS クラス
Guaranteed デフォルトのメモリ QoS 設定
Burstable LS (遅延の影響を受けやすい)
BestEffort BE (ベストエフォート)

前提条件

開始する前に、以下が準備されていることを確認してください。

  • Kubernetes 1.18 以降を実行している Container Service for Kubernetes (ACK) クラスター。詳細については、「ACK クラスターの手動更新」をご参照ください。

  • ノード OS としての Alinux。一部の高度なパラメーターは Alinux カーネル機能に依存します。詳細については、「詳細パラメーター」をご参照ください。

  • ack-koordinator 0.8.0 以降がインストールされていること。詳細については、「ack-koordinator」をご参照ください。

特定の Pod のメモリ QoS の有効化

Pod 仕様に次のアノテーションを追加します。

annotations:
  # 推奨設定でメモリ QoS を有効化
  koordinator.sh/memoryQOS: '{"policy": "auto"}'
  # メモリ QoS を無効化
  # koordinator.sh/memoryQOS: '{"policy": "none"}'

クラスターのメモリ QoS の有効化

ack-slo-config ConfigMap を使用して、クラスター内のすべての Pod にメモリ QoS を適用します。

  1. configmap.yaml という名前で、次の内容のファイルを作成します。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ack-slo-config
      namespace: kube-system
    data:
      resource-qos-config: |-
        {
          "clusterStrategy": {
            "lsClass": {
              "memoryQOS": {
                "enable": true
              }
            },
            "beClass": {
              "memoryQOS": {
                "enable": true
              }
            }
          }
        }
  2. 各 Pod の QoS クラスを koordinator.sh/qosClass ラベルで設定します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-demo
      labels:
        koordinator.sh/qosClass: 'LS'
  3. ConfigMap を適用します。

    • ack-slo-configkube-system に既に存在する場合、他の設定を保持するために更新します:``bash kubectl patch cm -n kube-system ack-slo-config --patch "$(cat configmap.yaml)" ``

    • 存在しない場合は、作成します:``bash kubectl apply -f configmap.yaml ``

  4. (オプション) 詳細パラメーターを設定します。

名前空間のメモリ QoS の有効化

ack-slo-pod-config ConfigMap を使用して、特定の名前空間の Pod のメモリ QoS を有効または無効にします。

  1. ack-slo-pod-config.yaml という名前で、次の内容のファイルを作成します。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ack-slo-pod-config
      namespace: kube-system
    data:
      memory-qos: |
        {
          "enabledNamespaces": ["allow-ns"],
          "disabledNamespaces": ["block-ns"]
        }

    allow-nsblock-ns を実際の名前空間名に置き換えます。

  2. ConfigMap を適用します。

    kubectl patch cm -n kube-system ack-slo-pod-config --patch "$(cat ack-slo-pod-config.yaml)"
  3. (オプション) 詳細パラメーターを設定します。

例:メモリオーバーコミット環境下の Redis

この例では、メモリ QoS がメモリオーバーコミット環境下で Redis のレイテンシーを削減し、スループットを向上させる方法を示します。テストでは以下を使用します。

  • 2 つのノード (それぞれ 8 vCPU、32 GB) を持つ ACK Pro マネージドクラスター

  • 1 つのノードを Redis 用に、もう 1 つをストレステスト用に

テストの実行

  1. redis-demo.yaml を作成します。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: redis-demo-config
    data:
      redis-config: |
        appendonly yes
        appendfsync no
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: redis-demo
      labels:
        koordinator.sh/qosClass: 'LS'
      annotations:
        koordinator.sh/memoryQOS: '{"policy": "auto"}'
    spec:
      containers:
      - name: redis
        image: redis:5.0.4
        command:
          - redis-server
          - "/redis-master/redis.conf"
        env:
        - name: MASTER
          value: "true"
        ports:
        - containerPort: 6379
        resources:
          limits:
            cpu: "2"
            memory: "6Gi"
          requests:
            cpu: "2"
            memory: "2Gi"
        volumeMounts:
        - mountPath: /redis-master-data
          name: data
        - mountPath: /redis-master
          name: config
      volumes:
        - name: data
          emptyDir: {}
        - name: config
          configMap:
            name: redis-demo-config
            items:
            - key: redis-config
              path: redis.conf
      nodeName: # Redis を実行しているノードの名前に設定します。
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: redis-demo
    spec:
      ports:
      - name: redis-port
        port: 6379
        protocol: TCP
        targetPort: 6379
      selector:
        name: redis-demo
      type: ClusterIP
  2. Redis をデプロイします。

    kubectl apply -f redis-demo.yaml
  3. Stress ツールでメモリオーバーコミットをシミュレートします。stress-demo.yaml を作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: stress-demo
      labels:
        koordinator.sh/qosClass: 'BE'
      annotations:
        koordinator.sh/memoryQOS: '{"policy": "auto"}'
    spec:
      containers:
        - args:
            - '--vm'
            - '2'
            - '--vm-bytes'
            - 11G
            - '-c'
            - '2'
            - '--vm-hang'
            - '2'
          command:
            - stress
          image: polinux/stress
          imagePullPolicy: Always
          name: stress
      restartPolicy: Always
      nodeName: # redis-demo と同じノードに設定します。
  4. ストレステストのワークロードをデプロイします。

    kubectl apply -f stress-demo.yaml
  5. ベンチマークを実行する前に、グローバル最小ウォーターマークを確認します。

    重要

    メモリオーバーコミットのシナリオでは、グローバル最小ウォーターマークが低いと、メモリ再利用の前に OOM killer が実行されます。32 GB のノードの場合、この値を少なくとも 4,000,000 KB に設定してください。

    cat /proc/sys/vm/min_free_kbytes

    期待される出力:

    4000000
  6. memtier-benchmark をデプロイして、Redis Pod にリクエストを送信します。

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        name: memtier-demo
      name: memtier-demo
    spec:
      containers:
        - command:
            - memtier_benchmark
            - '-s'
            - 'redis-demo'
            - '--data-size'
            - '200000'
            - "--ratio"
            - "1:4"
          image: 'redislabs/memtier_benchmark:1.3.0'
          name: memtier
      restartPolicy: Never
      nodeName: # リクエストを送信するノードの名前に設定します。
  7. ベンチマークの結果を確認します。

    kubectl logs -f memtier-demo
  8. 比較のため、両方の Pod でメモリ QoS を無効にしてテストを繰り返します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: redis-demo
      labels:
        koordinator.sh/qosClass: 'LS'
      annotations:
        koordinator.sh/memoryQOS: '{"policy": "none"}'
    spec:
      ...
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: stress-demo
      labels:
        koordinator.sh/qosClass: 'BE'
      annotations:
        koordinator.sh/memoryQOS: '{"policy": "none"}'

テスト結果

重要

結果は参考用です。実際の値はクラスターの構成とワークロードによって異なります。

メトリック メモリ QoS 無効 メモリ QoS 有効
Latency-avg 51.32 ms 47.25 ms
Throughput-avg 149.0 MB/s 161.9 MB/s

メモリ QoS を有効にすると、メモリオーバーコミット環境下で Redis のレイテンシーが 7.9% 削減され、スループットが 8.7% 向上しました。

詳細パラメーター

これらのパラメーターは、Pod アノテーションまたは ack-slo-config ConfigMap で設定します。Pod アノテーションが優先されます。

説明 [アノテーション] 列と [ConfigMap] 列は、パラメーターがアノテーションおよび ConfigMap で設定可能かどうかを示します。Supported は対応、Not supported は非対応を示します。
image

<table> <thead> <tr> <td><p><b>パラメーター</b></p></td> <td><p><b>型</b></p></td> <td><p><b>有効値</b></p></td> <td><p><b>説明</b></p></td> <td><p><b>Pod アノテーション</b></p></td> <td><p><b>ConfigMap</b></p></td> </tr> </thead> <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> <tbody> <tr> <td><p><code>enable</code></p></td> <td><p>ブール値</p></td> <td> <ul> <li><p><code>true</code></p></li> <li><p><code>false</code></p></li> </ul></td> <td> <ul> <li><p><code>true</code>: 推奨される memcg 設定ですべてのコンテナのメモリ QoS を有効にします。</p></li> <li><p><code>false</code>: すべてのコンテナのメモリ QoS を無効にし、デフォルトの memcg 設定を復元します。</p></li> </ul></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>policy</code></p></td> <td><p>文字列</p></td> <td> <ul> <li><p><code>auto</code></p></li> <li><p><code>default</code></p></li> <li><p><code>none</code></p></li> </ul></td> <td> <ul> <li><p><code>auto</code>: 推奨設定でメモリ QoS を有効にし、ack-slo-pod-config ConfigMap を上書きします。</p></li> <li><p><code>default</code>: ack-slo-pod-config ConfigMap から設定を継承します。</p></li> <li><p><code>none</code>: メモリ QoS を無効にしてデフォルトの memcg 設定を復元し、ack-slo-pod-config ConfigMap を上書きします。</p></li> </ul></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>minLimitPercent</code></p></td> <td><p>整数</p></td> <td><p>0\~100</p></td> <td><p>単位: %。 デフォルト値: <code>0</code> (無効)。 </p><p>Pod のメモリリクエストの回収不能な割合。 これを使用して、ページキャッシュの影響を受けやすいアプリケーションのファイルをキャッシュします。 詳細については、「<a href="https://www.alibabacloud.com/help/en/document_detail/169536.html#concept-2482889">cgroup v1 インターフェイスの Memcg QoS 機能</a>」をご参照ください。 </p><p>数式: <code>memory.min の値 = メモリリクエスト × minLimitPercent の値/100</code>。 たとえば、<code>Memory Request=100MiB</code> および <code>minLimitPercent=100</code> の場合、<code>memory.min の値は 104857600</code> です。 </p></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>lowLimitPercent</code></p></td> <td><p>整数</p></td> <td><p>0\~100</p></td> <td><p>単位: %。 デフォルト値: <code>0</code> (無効)。 </p><p>Pod のメモリリクエストの相対的に回収不能な割合。 詳細については、「<a href="https://www.alibabacloud.com/help/en/document_detail/169536.html#concept-2482889">cgroup v1 インターフェイスの Memcg QoS 機能</a>」をご参照ください。 </p><p>数式: <span><code>memory.low の値 = メモリリクエスト × lowLimitPercent の値/100</code></span>。 たとえば、<span><code>Memory Request=100MiB</code></span> および <span><code>lowLimitPercent=100</code></span> の場合、<span><code>memory.low の値は 104857600</code></span> です。 </p></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>throttlingPercent</code></p></td> <td><p>整数</p></td> <td><p>0\~100</p></td> <td><p>単位: %。 デフォルト値: <code>0</code> (無効)。 </p><p>コンテナの使用量の制限値に対する比率としてのメモリ速度制限のしきい値。 超過すると、メモリが回収されます。 オーバーコミットのシナリオで cgroup レベルの OOM を防ぎます。 詳細については、「<a href="https://www.alibabacloud.com/help/en/document_detail/169536.html#concept-2482889">cgroup v1 インターフェイスの Memcg QoS 機能</a>」をご参照ください。 </p><p>数式: <code>memory.high の値 = メモリ制限 × throttlingPercent の値/100</code>。 たとえば、<code>Memory Limit=100MiB</code> および <code>throttlingPercent=80</code> の場合、<code>memory.high の値は 83886080 (80 MiB)</code> です。 </p></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>wmarkRatio</code></p></td> <td><p>整数</p></td> <td><p>0\~100</p></td> <td><p>単位: %。 デフォルト値: <code>95</code>。 <code>0</code> を指定すると、このパラメーターは無効になります。 使用量がしきい値を超えると、memcg バックエンドの非同期回収がトリガーされます。 </p><p>非同期回収のしきい値: 使用量の制限値に対する比率、または <code>memory.high</code> に対する使用量の比率。 詳細については、「<a href="https://www.alibabacloud.com/help/en/document_detail/169535.html#task-2487938">Memcg バックエンドの非同期回収</a>」をご参照ください。 </p><p>throttlingPercent が無効な場合、数式は次のようになります: Value of memory.wmark_high = Memory limit × wmarkRatio/100。 throttlingPercent が有効な場合、数式は <code>Value of memory.wmark_high = Value of memory.high × wmarkRatio/100</code> です。 たとえば、<code>Memory Limit=100MiB</code>、<code>wmarkRatio=95,throttlingPercent=80</code> の場合、<code>memory.high は 83886080 (80 MiB)</code>、<code>memory.wmark_ratio は 95</code>、<code>memory.wmark_high は 79691776 (76 MiB)</code> となります。 </p></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>wmarkMinAdj</code></p></td> <td><p>整数</p></td> <td><p>-25\~50</p></td> <td><p>単位: %。 デフォルト値は、<code>LS</code> QoS クラスの場合は <code>-25</code>、<code>BE</code> QoS クラスの場合は <code>50</code> です。 <code>0</code> を指定すると、このパラメーターは無効になります。 </p><p>コンテナごとのグローバル最小ウォーターマークを調整します。 負の値を指定すると回収が延期され、正の値を指定すると回収が早まります。 詳細については、「<a href="https://www.alibabacloud.com/help/en/document_detail/169537.html#task-2492619">Memcg グローバル最小ウォーターマーク評価</a>」をご参照ください。 </p><p>たとえば、LS Pod のデフォルトは <code>memory.wmark_min_adj=-25</code> で、最小ウォーターマークを 25% 減少させます。 </p></td> <td><p><img></p></td> <td><p><img></p></td> </tr> </tbody> </table>

よくある質問

ack-koordinator にアップグレードした後も、ack-slo-manager のメモリ QoS 設定は有効ですか?

はい。ack-koordinator は、ack-slo-manager 0.8.0 以前で使用されていたアノテーションベースのプロトコルと下位互換性があります。

  • alibabacloud.com/qosClass — QoS クラスを設定します

  • alibabacloud.com/memoryQOS — メモリ QoS を設定します

次の表は、各バージョンがサポートするプロトコルを示しています。

コンポーネントバージョン alibabacloud.com プロトコル koordinator.sh プロトコル
0.3.0 以上 0.8.0 未満 ×
0.8.0 以上

alibabacloud.com プロトコルのサポートは 2023年7月30日に終了しました。koordinator.sh プロトコルに移行してください。

課金

ack-koordinator コンポーネントのインストールや使用に料金はかかりません。ただし、次の場合にコストが発生する可能性があります。

  • ノードリソース使用量:ack-koordinator はワーカーノードで実行される非マネージドコンポーネントです。インストール時に各モジュールのリソースリクエストを設定できます。

  • Prometheus メトリック: ack-koordinator の Prometheus メトリックを有効にし、Managed Service for Prometheus を使用する場合、メトリックは カスタムメトリック として課金されます。 この機能を有効にする前に、Managed Service for Prometheus の課金ルール を確認してください。 使用量をモニターするには、「観測可能なデータ量と請求書の照会」をご参照ください。

次のステップ