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

Container Service for Kubernetes:Enable container memory QoS

最終更新日:Mar 27, 2026

ack-koordinator コンポーネントは、ACK クラスターで実行されているコンテナにメモリサービス品質 (QoS) を提供します。コンテナに異なる QoS クラスを割り当てることで、ack-koordinator は遅延の影響を受けやすいワークロードのメモリを優先し、メモリ競合時のメモリ不足 (OOM) エラーを削減します。

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

仕組み

Kubernetes は、各 Pod にメモリリクエストとメモリ制限を割り当てます。メモリが制約されている場合、2つの障害モードが発生します。

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

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

image

ack-koordinator は、各コンテナのメモリ制御グループ (memcg) を自動的に構成することで、両方の障害モードに対処します。これにより、3つの Alibaba Cloud Linux カーネル機能が有効になります。

その結果、コンテナ間でより公平なメモリ分散が実現され、オーバーコミット時のアプリケーションのレイテンシが低減されます。

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

アップストリーム Kubernetes の メモリ QoS 機能は Kubernetes 1.22 以降でサポートされており、cgroup v2 のみをサポートし、手動の kubelet 構成が必要です。これはクラスター内のすべての Pod とノードに適用され、Podごとまたは名前空間ごとの詳細な構成はサポートしていません。

ack-koordinator メモリ QoS 機能は、2つの主要な点でアップストリームの実装を改善しています。

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

  • 詳細な構成: Pod アノテーションまたは ConfigMap を使用して、特定の Pod、名前空間、またはクラスター全体のメモリ QoS を個別に構成します。

構成メカニズム

ack-koordinator は、4つの cgroup パラメーターを使用してメモリ QoS ポリシーを適用します。次の表は、各パラメーターが「高度なパラメーター」で説明されている構成オプションにどのようにマッピングされるかを示しています。

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 以降を実行している ACK クラスター。アップグレードについては、「ACK クラスターの手動更新」をご参照ください。

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

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

特定の Pod のメモリ QoS を有効にする

Pod スペックに次のアノテーションを追加します。

annotations:
  # Enable memory QoS with recommended settings
  koordinator.sh/memoryQOS: '{"policy": "auto"}'
  # Disable memory 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. koordinator.sh/qosClass ラベルを使用して、各 Pod の QoS クラスを設定します。

    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 のレイテンシをどのように削減し、スループットを向上させるかを示します。テストでは以下を使用します。

  • 8 vCPU と 32 GB のメモリを持つ 2つのノードを備えた 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: # Set to the name of the node running 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: # Set to the same node as redis-demo.
  4. ストレスワークロードをデプロイします。

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

    重要

    メモリオーバーコミットのシナリオでは、グローバル最小ウォーターマークが低いと、メモリ再利用の前に OOM キラーが実行されます。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: # Set to the name of the node sending requests.
  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」列は、パラメーターがアノテーションおよび ConfigMap を介して設定可能かどうかを示します。対応 は対応を示し、非対応 は非対応を示します。
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>: クラスター内のすべてのコンテナに対してメモリ QoS を有効にします。コンテナの QoS クラスに対する推奨 memcg 設定が使用されます。</p></li> <li><p><code>false</code>: クラスター内のすべてのコンテナに対してメモリ QoS を無効にします。コンテナの 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>: Pod 内のコンテナに対してメモリ QoS を有効にし、推奨設定を使用します。推奨設定は ack-slo-pod-config ConfigMap で指定された設定よりも優先されます。</p></li> <li><p><code>default</code>: Pod が ack-slo-pod-config ConfigMap で指定された設定を継承することを指定します。</p></li> <li><p><code>none</code>: Pod に対してメモリ 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 のメモリ要求における解放不可の割合を指定します。このパラメーターは、アプリケーションがページキャッシュに敏感なシナリオに適しています。このパラメーターを使用してファイルをキャッシュし、読み書き性能を最適化できます。詳細については、Alibaba Cloud Linux のトピック「<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 のメモリ要求における比較的解放不可の割合を指定します。詳細については、Alibaba Cloud Linux のトピック「<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>このパラメーターは、コンテナのメモリ使用量とコンテナのメモリ制限の比率に対するメモリ速度制限しきい値を指定します。コンテナのメモリ使用量がメモリ速度制限しきい値を超えると、そのコンテナで使用されているメモリが解放されます。このパラメーターは、コンテナのメモリ過剰割り当てシナリオに適しています。このパラメーターを使用して、cgroups による OOM の発生を防止できます。詳細については、Alibaba Cloud Linux のトピック「<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> の値への非同期メモリ解放しきい値を指定します。詳細については、Alibaba Cloud Linux のトピック「<a href="https://www.alibabacloud.com/help/en/document_detail/169535.html#task-2487938">Memcg バックエンドの非同期解放</a>」をご参照ください。</p><p>throttlingPercent が無効の場合、メモリ使用量に対するメモリ解放しきい値は、次の数式に基づいて計算されます: memory.wmark_high の値 = メモリ制限 × wmarkRatio / 100。throttlingPercent が有効の場合、メモリ使用量に対するメモリ解放しきい値は、次の数式に基づいて計算されます: <code>memory.wmark_high の値 = 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>このパラメーターは、コンテナに対するグローバル最小ウォーターマークの調整を指定します。負の値はグローバル最小ウォーターマークを低下させ、そのためコンテナのメモリ解放を遅らせます。正の値はグローバル最小ウォーターマークを増加させ、そのためコンテナのメモリ解放を早めます。詳細については、Alibaba Cloud Linux のトピック「<a href="https://www.alibabacloud.com/help/en/document_detail/169537.html#task-2492619">Memcg グローバル最小ウォーターマーク評価</a>」をご参照ください。</p><p>たとえば、QoS クラスが LS の Pod を作成した場合、このパラメーターのデフォルト設定は <code>memory.wmark_min_adj=-25</code> となり、これは Pod 内のコンテナの最小ウォーターマークが 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 and < 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 の課金ルールを確認してください。使用量をモニターするには、「観測可能なデータ量と請求書の照会」をご参照ください。

次のステップ