オンラインワークロードは通常、ピーク時の推定値に基づいて CPU およびメモリを予約しますが、実際の使用量はそれより大幅に低くなることが多くあります。これにより、割り当て済みだがアイドル状態のリソースが大量に残り、標準の BestEffort Pod が共有できますが、スケジューリング保証や公平性制御はありません。動的リソース過剰割り当ては、この両方の課題を解決します。ack-koordinator コンポーネントがノードの負荷をリアルタイムで監視し、回収可能な容量を計算して、BestEffort Pod が明示的に要求できる Batch 拡張リソース(kubernetes.io/batch-cpu および kubernetes.io/batch-memory)として公開します。
本機能を最大限に活用するには、Kubernetes ドキュメントの「Pod のサービス品質クラス」および「コンテナおよび Pod へのメモリリソースの割り当て」をご参照ください。
仕組み
ack-koordinator は各ノードの負荷を継続的に追跡し、回収可能な容量を各ノード上で拡張リソースとして公開します。BestEffort Pod はこれらの Batch リソースに対して明示的なリクエストおよび制限を宣言するため、ACK スケジューラは適切な配置判断を行い、ノードの cgroup 階層を通じてリソース制限を適用できます。
以下の図は、標準的なリソース過剰割り当ての課題を示しています。
動的過剰割り当てが有効でない場合、スケジューラは実際のノード負荷を把握できないため、既に過負荷状態のノードに BestEffort Pod を配置してしまう可能性があります。また、Pod ごとに異なるリソース量を指定する方法がないため、BestEffort Pod 間でのリソース配分の公平性も確保できません。
ack-koordinator では、回収可能なリソース容量を説明するために以下の 3 つの用語が導入されています。
| 用語 | 説明 |
|---|---|
| 回収可能(Reclaimed) | 現時点で動的に過剰割り当て可能なリソース |
| バッファ(Buffered) | 回収から除外されるように予約されたリソース |
| 使用法 | 実際のリソース消費量 |
QoS クラスと Batch リソース
Kubernetes は、Pod のリソース構成に基づいて各 Pod にサービス品質(QoS)クラスを割り当てます。Batch リソースは、特に BestEffort クラス向けに設計されています。
| QoS クラス | リソース構成 | 利用シーン |
|---|---|---|
| Guaranteed | requests == limits(すべてのコンテナで) |
レイテンシーに敏感な本番サービス |
| Burstable | requests < limits(少なくとも 1 つのコンテナで) |
一般的なオンラインワークロード |
| BestEffort | requests および limits を設定しない代わりに、Batch リソースを使用 |
バッチジョブおよびオフラインタスク |
動的リソース過剰割り当てを利用するには、Pod に koordinator.sh/qosClass: "BE" のラベルを設定し、標準のリソースフィールドを kubernetes.io/batch-cpu および kubernetes.io/batch-memory に置き換えます。
課金
ack-koordinator コンポーネントのインストールおよび利用に料金は発生しません。ただし、以下の点にご注意ください。
-
ack-koordinator は非マネージドコンポーネントです。インストール後はワーカーノードのリソースを占有します。インストール時に、各モジュールのリソースリクエストを指定してください。
-
ack-koordinator は、リソースプロファイリングや詳細なスケジューリングなどの機能に対して Prometheus メトリックを公開できます。ack-koordinator の Prometheus メトリックを有効にし、Managed Service for Prometheus を使用する場合、これらのメトリックは カスタムメトリック と見なされ、それに応じて課金されます。有効にする前に、Managed Service for Prometheus の 課金 トピックを確認し、観測可能なデータ量と請求書を照会する を読んで、コストがどのように計算されるかを理解してください。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
-
ACK Pro マネージドクラスターが存在すること。詳細については、「ACK Pro マネージドクラスターの作成」をご参照ください。
-
ack-koordinator コンポーネントのバージョン 0.8.0 以降がインストール済みであること。詳細については、「ack-koordinator」をご参照ください。
動的リソース過剰割り当ての有効化
kube-system 名前空間で ConfigMap を作成または更新することで、機能を有効にして設定します。
手順 1:ConfigMap の作成
以下の内容で configmap.yaml というファイルを作成します。
apiVersion: v1
kind: ConfigMap
metadata:
name: ack-slo-config
namespace: kube-system
data:
# colocation-config は、動的 Batch リソースの計算および更新を制御します。
# 関連機能:動的リソース過剰割り当て、負荷感知スケジューリング。
colocation-config: |
{
"enable": true, # 必須:Batch リソースの更新を有効化します。false に設定すると、回収可能なリソースは 0 にリセットされます。
"metricAggregateDurationSeconds": 60, # ノードメトリックを集計する間隔(秒)。デフォルト値を使用してください。
"cpuReclaimThresholdPercent": 60, # batch-cpu の回収しきい値(割り当て可能な CPU のパーセンテージ)。デフォルト:65。
"memoryReclaimThresholdPercent": 70, # batch-memory の回収しきい値(割り当て可能なメモリのパーセンテージ)。デフォルト:65。
"memoryCalculatePolicy": "usage" # batch-memory 容量の計算方法:"usage"(デフォルト)または "request"。
}
この例のcpuReclaimThresholdPercentおよびmemoryReclaimThresholdPercentの値(60 および 70)はサンプル値です。実際のデフォルト値は、いずれも 65 です。
以下の表では、各パラメーターについて詳しく説明します。
| パラメーター | 型 | デフォルト | 説明 |
|---|---|---|---|
enable |
ブール値 | false |
動的 Batch リソースの更新を有効化します。false に設定すると、回収可能なリソースは 0 にリセットされます。 |
metricAggregateDurationSeconds |
整数 | 60 |
Batch リソース容量の再計算のために、システムがノードメトリックを集計する頻度(秒単位)。デフォルト値を使用してください。 |
cpuReclaimThresholdPercent |
整数 | 65 |
batch-cpu リソースの回収しきい値(割り当て可能な CPU のパーセンテージ)。Batch リソース容量の計算をご参照ください。 |
memoryReclaimThresholdPercent |
整数 | 65 |
batch-memory リソースの回収しきい値(割り当て可能なメモリのパーセンテージ)。Batch リソース容量の計算をご参照ください。 |
memoryCalculatePolicy |
文字列 | "usage" |
batch-memory 容量の計算方法。"usage":未割り当てリソースおよび割り当て済みだがアイドル状態のリソース(Guaranteed および Burstable Pod の実際の使用量に基づく)を含む。"request":未割り当てリソースのみ(Guaranteed および Burstable Pod のメモリリクエストに基づく)を含む。 |
Batch リソース容量の計算
ack-koordinator は、各ノードで利用可能な Batch リソース量を算出するために、以下の数式を適用します。
使用量ベースの計算(デフォルト、memoryCalculatePolicy: "usage"):
nodeBatchAllocatable = nodeAllocatable × thresholdPercent − podUsage(non-BE) − systemUsage
リクエストベースの計算(memoryCalculatePolicy: "request"、batch-memory のみに適用):
nodeBatchAllocatable = nodeAllocatable × thresholdPercent − podRequest(non-BE) − systemUsage
ここで、
| 変数 | 説明 |
|---|---|
nodeAllocatable |
ノード全体の割り当て可能な CPU またはメモリの合計 |
thresholdPercent |
設定された回収しきい値のパーセンテージ |
podUsage(non-BE) |
Guaranteed および Burstable Pod の実際のリソース使用量 |
podRequest(non-BE) |
Guaranteed および Burstable Pod のリソースリクエストの合計 |
systemUsage |
ノードにおけるシステムレベルのリソース消費量 |
手順 2:ConfigMap の適用
ack-slo-config ConfigMap が kube-system 名前空間内にすでに存在するか確認します。
-
存在する場合、他の設定を上書きせずに変更をマージするには、
kubectl patchを使用します。kubectl patch cm -n kube-system ack-slo-config --patch "$(cat configmap.yaml)" -
存在しない場合、以下のように作成します。
kubectl apply -f configmap.yaml
Batch リソースの申請
動的リソース過剰割り当てを有効化した後、Pod が Batch リソースを要求するよう構成します。
-
Pod は、Batch リソースと標準リソースを同時に要求することはできません。
-
Deployment などのワークロードでは、
template.metadataにラベルを設定してください。ワークロードオブジェクト自体には設定しないでください。 -
ack-koordinator は、リアルタイムのノード負荷に基づいて利用可能な Batch 容量を動的に調整します。まれに、kubelet がノードステータスの報告に遅れを生じ、リソース不足により Pod のスケジューリングが失敗することがあります。その場合は、該当する Pod を削除して再作成してください。
-
Batch リソースの数量は整数で指定する必要があります。batch-cpu はミリコア単位(1 コア = 1000 ミリコア)を使用します。
手順 1:ノード上の利用可能な Batch リソースの確認
# $nodeName を実際のノード名に置き換えてください。
kubectl get node $nodeName -o yaml
出力内の status.allocatable セクションを確認します。
status:
allocatable:
# 単位:ミリコア。次の例では、50 コアが利用可能であることを示しています。
kubernetes.io/batch-cpu: 50000
# 単位:バイト。次の例では、50 GB が利用可能であることを示しています。
kubernetes.io/batch-memory: 53687091200
手順 2:Pod による Batch リソースの利用構成
Pod のメタデータに koordinator.sh/qosClass: "BE" のラベルを追加し、コンテナの resources フィールドに kubernetes.io/batch-cpu および kubernetes.io/batch-memory を設定します。
metadata:
labels:
# 必須:Pod の QoS クラスを BestEffort に設定します。
koordinator.sh/qosClass: "BE"
spec:
containers:
- resources:
requests:
# 単位:ミリコア。「1k」=1000 ミリコア=1 コア。
kubernetes.io/batch-cpu: "1k"
# 単位:バイト。
kubernetes.io/batch-memory: "1Gi"
limits:
kubernetes.io/batch-cpu: "1k"
kubernetes.io/batch-memory: "1Gi"
例
この例では、Batch リソースを使用する BestEffort テスト Pod をデプロイし、ノードの cgroup でリソース制限が適用されていることを検証します。
-
ノード上の利用可能な Batch リソースを確認します。
kubectl get node $nodeName -o yaml期待される出力:
status: allocatable: kubernetes.io/batch-cpu: 50000 kubernetes.io/batch-memory: 53687091200 -
be-pod-demo.yamlというファイルを作成します。apiVersion: v1 kind: Pod metadata: labels: koordinator.sh/qosClass: "BE" name: be-demo spec: containers: - command: - "sleep" - "100h" image: registry-cn-beijing.ack.aliyuncs.com/acs/stress:v1.0.4 imagePullPolicy: Always name: be-demo resources: limits: kubernetes.io/batch-cpu: "50k" kubernetes.io/batch-memory: "10Gi" requests: kubernetes.io/batch-cpu: "50k" kubernetes.io/batch-memory: "10Gi" schedulerName: default-scheduler -
Pod をデプロイします。
kubectl apply -f be-pod-demo.yaml -
リソース制限がノードの cgroup に正しく反映されていることを検証します。CPU 制限を確認します。
cat /sys/fs/cgroup/cpu,cpuacct/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod4b6e96c8_042d_471c_b6ef_b7e0686a****.slice/cri-containerd-11111c202adfefdd63d7d002ccde8907d08291e706671438c4ccedfecba5****.scope/cpu.cfs_quota_us期待される出力(50 コア):
5000000メモリ制限を確認します。
cat /sys/fs/cgroup/memory/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod4b6e96c8_042d_471c_b6ef_b7e0686a****.slice/cri-containerd-11111c202adfefdd63d7d002ccde8907d08291e706671438c4ccedfecba5****.scope/memory.limit_in_bytes期待される出力(10 GB):
10737418240
Batch リソース使用量のモニタリング
ACK クラスターは Managed Service for Prometheus と統合されています。Batch リソース使用量を表示するには、以下の手順を実行します。
-
クラスター ページで、対象のクラスター名をクリックします。左側のペインで、運用 > Prometheus モニタリング を選択します。
-
その他 タブをクリックし、k8s-reclaimed-resource タブをクリックします。このダッシュボードでは、クラスターの混合収益およびクラスター、ノード、Pod 各レベルでのリソース容量を表示できます。詳細については、「コロケーションモニタリング機能の有効化」をご参照ください。
カスタム Prometheus ダッシュボードを構築している場合、以下のメトリックを使用して Batch リソースデータをクエリできます。
# ノード上の割り当て可能な batch-cpu
koordlet_node_resource_allocatable{resource="kubernetes.io/batch-cpu",node="$node"}
# ノード上で既に割り当てられた batch-cpu
koordlet_container_resource_requests{resource="kubernetes.io/batch-cpu",node="$node"}
# ノード上の割り当て可能な batch-memory
kube_node_status_allocatable{resource="kubernetes.io/batch-memory",node="$node"}
# ノード上で既に割り当てられた batch-memory
koordlet_container_resource_requests{resource="kubernetes.io/batch-memory",node="$node"}
よくある質問
ack-slo-manager から ack-koordinator へアップグレードした後、従来の過剰割り当て構成は引き続き有効ですか?
はい。ack-koordinator は、以前の ack-slo-manager プロトコルと下位互換性があります。ACK Pro クラスタースケジューラは、旧形式および新形式の両方のプロトコルでリクエストおよび利用可能なリソースを計算できるため、既存のワークロードを再構成することなくアップグレードできます。
以前のプロトコルでは、以下の要素が使用されます。
-
alibabacloud.com/qosClassの Pod アノテーション -
alibabacloud.com/reclaimedフィールドによるリソースリクエストおよび制限
ack-koordinator は、2023 年 7 月 30 日以前のプロトコルバージョンまでサポートしています。既存のワークロードを koordinator.sh プロトコルへ移行するのは、都合のよいタイミングで行ってください。
以下の表は、コンポーネントバージョン間の互換性を示しています。
| スケジューラバージョン | ack-koordinator | alibabacloud.com プロトコル | koordinator.sh プロトコル |
|---|---|---|---|
| ≥1.18 かつ <1.22.15-ack-2.0 | ≥0.3.0 | 対応 | 非対応 |
| ≥1.22.15-ack-2.0 | ≥0.8.0 | 対応 | 対応 |
Pod 起動直後にメモリ使用量が急増するのはなぜですか?
症状: コンテナ起動直後にメモリ使用量が急上昇し、kubernetes.io/batch-memory の制限を超えることがあります。
原因: コンテナが作成されると、ack-koordinator は cgroup のメモリ制限を kubernetes.io/batch-memory に基づいて設定します。一部のアプリケーションでは、起動時に cgroup 制限を読み取り、内部で割り当てるメモリ量を決定します。アプリケーションが ack-koordinator による制限の書き込み前に cgroup を読み取ると、意図した以上のメモリを割り当ててしまうことがあります。オペレーティングシステムは即座にそのメモリを回収しないため、設定された制限を下回るまで使用量が高止まりのままになります。
確認方法: コンテナ内で以下のコマンドを実行し、メモリ制限が正しく設定されているか確認します。
# 単位:バイト
cat /sys/fs/cgroup/memory/memory.limit_in_bytes
# 期待される出力例
1048576000
修正方法: アプリケーションのメインプロセス開始前に、起動スクリプト内でアプリケーションのメモリ制限を構成します。これにより、アプリケーションが cgroup を読み取る前に制限が適用されます。
BestEffort Pod が Pending 状態のままであるのはなぜですか?
症状: Batch リソースを構成した Pod が Pending 状態のままとなり、スケジューリングできません。
確認方法: kubectl describe pod <pod-name> を実行し、スケジューリング失敗イベントを確認します。
主な原因と修正方法:
| 原因 | 修正方法 |
|---|---|
| すべてのノードで Batch リソースが不足している | kubectl get node <node> -o yaml を実行し、status.allocatable の batch-cpu および batch-memory を確認します。Pod のリクエストを減らすか、リソースが回収されるのを待ってください。 |
| kubelet がまだノードステータスを同期していない | Pod を削除して再作成します。ack-koordinator は Batch 容量を動的に調整しますが、kubelet が更新された割り当て可能なリソースを報告するまでに遅延が生じることがあります。 |
| Pod が Batch リソースと標準リソースの両方を要求している | Pod は Batch リソースと標準リソースを同時に要求できません。いずれか一方のリソースフィールドを削除してください。 |
次のステップ
ack-koordinator は、BestEffort Pod によるオンラインワークロードへの干渉を防ぐための追加制御機能を提供します。以下のトピックをご参照ください。