Kubernetesは、ResourceQuotaオブジェクトを使用してリソースを静的に割り当てます。 この方法では、Kubernetesクラスターのリソース使用率が高くなりません。 Container Service for Kubernetes (ACK) クラスターのリソース使用率を向上させるために、Alibaba CloudはYarn容量スケジューラとKubernetesスケジューリングフレームワークに基づく容量スケジューリング機能を開発しました。 この機能は、弾性クォータグループを使用してACKクラスターのリソース要求を満たし、リソースを共有してリソースの使用率を向上させます。 このトピックでは、容量スケジューリング機能の使用方法について説明します。
前提条件
Kubernetes 1.20以降を実行するACK Proクラスターが作成されます。 詳細については、「ACK管理クラスターの作成」をご参照ください。
背景情報
クラスターが複数のユーザーによって使用されている場合、ユーザーがリソースを求めて競合する場合に備えて、各ユーザーに一定量のリソースを割り当てる必要があります。 従来の方法では、Kubernetesリソースクォータを使用して、各ユーザーに固定量のリソースを割り当てます。 これらのユーザは、異なる時間に異なる方法でリソースを使用し得る。 その結果、一部のユーザは、他のユーザに割り当てられたリソースが使用されない間に、リソース不足に遭遇し得る。 この場合、クラスタのリソース利用は減少し、かなりの量のリソースが浪費される。
主な機能
この問題に対処するために、Alibaba CloudはKubernetesスケジューリングフレームワークに基づく容量スケジューリング機能を提供し、リソース割り当てを最適化します。 この機能により、ACKクラスター内のリソース要求に対応し、リソースを共有することでリソース使用率を向上させることができます。 容量スケジューリング機能は、次の機能を提供します。
階層リソースの割り当てをサポートします。 次の図に示すように、要件に基づいて階層的なリソースクォータを設定できます (企業内の部門のリソースクォータの作成など) 。 エラスティッククォータグループでは、各名前空間は1つのリーフにのみ属し、リーフには複数の名前空間を含めることができます。
リソース割り当て間のリソース共有と再利用をサポートします。
最小:使用が保証されているリソースの最小量。 クラスターのリソースが不足した場合、すべてのユーザーの最小リソースの合計量は、クラスターのリソースの合計量よりも少なくする必要があります。
最大:使用できるリソースの最大量。
説明他のユーザーのアイドルリソースクォータは、ワークロードによって一時的に使用できます。 ただし、ワークロードで使用されるリソースの合計量は、対応するリソースクォータの最大量を超えることはできません。
ワークロードに割り当てられた最小量のリソースがアイドル状態の場合、他のユーザーが一時的に使用できます。 これらのリソースが必要な場合は、ワークロードによって再利用され、プリエンプトされます。
複数のリソースタイプをサポートします。 CPUとメモリリソースのクォータを設定できます。 KubernetesでサポートされているGPUなどの拡張リソースのリソースクォータを設定することもできます。
容量スケジューリングの例
このトピックでは、ECS. sn2.13xlargeタイプ (56 vCPUおよび224 GiB) のElastic Compute Service (ecs) インスタンスを使用して、リソースクォータを設定する方法を示します。
次のコマンドを実行して、名前空間を作成します。
kubectl create ns namespace1 kubectl create ns namespace2 kubectl create ns namespace3 kubectl create ns namespace4
次のYAMLテンプレートを使用してエラスティッククォータグループを作成します。
上記のYAMLテンプレートでは、名前空間は
名前空間
の下に設定されています。 リーフのエラスティッククォータは、子
の下に設定されます。 クォータ設定は、次の要件を満たす必要があります。リーフのリソースの最小量は、リーフのリソースの最大量を超えることはできません。
親リーフの下のすべてのリーフの最小リソースの合計量は、親リーフの最小リソース量を超えることはできません。
ルートのリソースの最小量は、ルートのリソースの最大量と等しくなければなりません。 この量は、クラスターのリソースの総量を超えることはできません。
各名前空間は1つのリーフのみに属します。 リーフには複数の名前空間を含めることができます。
次のコマンドを実行して、エラスティッククォータグループが作成されているかどうかを確認します。
kubectl get ElasticQuotaTree -n kube-system
を取得
期待される出力:
NAME AGE elasticquotatree 68s
次のYAMLテンプレートを使用して、
namespace1
にデプロイを作成します。 デプロイは5つのポッドを実行し、各ポッドは5つのCPUコアを要求します。次のコマンドを実行して、ポッドのステータスを照会します。
kubectl get pods -n namespace1
期待される出力:
NAME READY STATUS RESTARTS AGE nginx1-744b889544-52dbg 1/1 Running 0 70s nginx1-744b889544-6l4s9 1/1 Running 0 70s nginx1-744b889544-cgzlr 1/1 Running 0 70s nginx1-744b889544-w2gr7 1/1 Running 0 70s nginx1-744b889544-zr5xz 0/1 Pending 0 70s
namespace1
内のポッドのCPUリソース要求の合計が10 (min.cpu=10
) を超えています。これは、root.a.1
のCPUコアの最小数です。 ルートのCPUコアの最大数は40です (root.max.cpu=40
) 。 したがって、これらのポッドはクラスター内のアイドルCPUコアを使用できます。 これらのポッドで使用されるCPUコアの最大数は20 (max.cpu=20
) を超えることはできません。これはroot.a.1
のCPUコアの最大数です。namespace1内のポッドによって使用されるCPUコアの数が20 (
max.cpu=20
) に達すると、次にスケジュールされるポッドは保留になります。 この展開の5つのポッドのうち、4つは実行中状態であり、1つは保留状態である。
次のYAMLテンプレートを使用して、
namespace2
に2つ目のデプロイを作成します。 デプロイは5つのポッドを実行し、各ポッドは5つのCPUコアを要求します。次のコマンドを実行して、ポッドのステータスを照会します。
kubectl get pods -n namespace1
期待される出力:
NAME READY STATUS RESTARTS AGE nginx1-744b889544-52dbg 1/1 Running 0 111s nginx1-744b889544-6l4s9 1/1 Running 0 111s nginx1-744b889544-cgzlr 1/1 Running 0 111s nginx1-744b889544-w2gr7 1/1 Running 0 111s nginx1-744b889544-zr5xz 0/1 Pending 0 111s
kubectl get pods -n namespace2
期待される出力:
NAME READY STATUS RESTARTS AGE nginx2-556f95449f-4gl8s 1/1 Running 0 111s nginx2-556f95449f-crwk4 1/1 Running 0 111s nginx2-556f95449f-gg6q2 0/1 Pending 0 111s nginx2-556f95449f-pnz5k 1/1 Running 0 111s nginx2-556f95449f-vjpmq 1/1 Running 0 111s
この配置は、
nginx1
配置に似ています。namespace2
内のポッドのCPUリソース要求の合計が10 (min.cpu=10
) を超えています。これは、root.a.2
のCPUコアの最小数です。 ルートのCPUコアの最大数は40です (root.max.cpu=40
) 。 したがって、これらのポッドはクラスター内のアイドルCPUコアを使用できます。 これらのポッドで使用されるCPUコアの最大数は20 (max.cpu=20
) を超えることはできません。これはroot.a.2
のCPUコアの最大数です。namespace2のポッドで使用されるCPUコアの数が20 (
max.cpu=20
) に達すると、次にスケジュールされるポッドは保留になります。 この展開の5つのポッドのうち、4つは実行中状態であり、1つは保留状態である。上記の2つのデプロイメントを作成した後、
namespace1
とnamespace2
のポッドは40 (root.max.cpu=40
) のCPUコアを使用しました。これはroot
ノードのCPUコアの最大数です。
次のYAMLテンプレートを使用して、
namespace3
に3つ目のデプロイを作成します。 このデプロイは5つのポッドを実行し、各ポッドは5つのCPUコアを要求します。次のコマンドを実行して、ポッドのステータスを照会します。
kubectl get pods -n namespace1
期待される出力:
NAME READY STATUS RESTARTS AGE nginx1-744b889544-52dbg 1/1 Running 0 6m17s nginx1-744b889544-cgzlr 1/1 Running 0 6m17s nginx1-744b889544-nknns 0/1 Pending 0 3m45s nginx1-744b889544-w2gr7 1/1 Running 0 6m17s nginx1-744b889544-zr5xz 0/1 Pending 0 6m17s
kubectl get pods -n namespace2
期待される出力:
NAME READY STATUS RESTARTS AGE nginx2-556f95449f-crwk4 1/1 Running 0 4m22s nginx2-556f95449f-ft42z 1/1 Running 0 4m22s nginx2-556f95449f-gg6q2 0/1 Pending 0 4m22s nginx2-556f95449f-hfr2g 1/1 Running 0 3m29s nginx2-556f95449f-pvgrl 0/1 Pending 0 3m29s
kubectl get pods -n namespace3
期待される出力:
NAME READY STATUS RESTARTS AGE nginx3-578877666-msd7f 1/1 Running 0 4m nginx3-578877666-nfdwv 0/1 Pending 0 4m10s nginx3-578877666-psszr 0/1 Pending 0 4m11s nginx3-578877666-xfsss 1/1 Running 0 4m22s nginx3-578877666-xpl2p 0/1 Pending 0 4m10s
root.b.1
のmin
は10
に設定されます。 したがって、nginx3
デプロイが作成されると、ポッドにはmin
リソースが必要になります。 スケジューラは、root.b
に属し、root.a
によって一時的に使用されるCPUコアを再要求します。 これにより、nginx3
のポッドスケジューリングに最低10 (min.cpu=10
) のCPUコアが確保されます。スケジューラは、一時的に使用された10個のCPUコアを再要求する前に、
root.a
のワークロードの優先度クラス、可用性、作成時間などの他の要因も考慮します。 したがって、nginx3
のポッドが再利用された10 (min.cpu=10
) CPUコアに基づいてスケジュールされた後、2つのポッドは実行中状態になり、他の3つは保留状態になります。次のYAMLテンプレートを使用して、
namespace4
に4つ目のデプロイnginx4
を作成します。 このデプロイは5つのポッドを実行し、各ポッドは5つのCPUコアを要求します。次のコマンドを実行して、ポッドのステータスを照会します。
kubectl get pods -n namespace1
期待される出力:
NAME READY STATUS RESTARTS AGE nginx1-744b889544-cgzlr 1/1 Running 0 8m20s nginx1-744b889544-cwx8l 0/1 Pending 0 55s nginx1-744b889544-gjkx2 0/1 Pending 0 55s nginx1-744b889544-nknns 0/1 Pending 0 5m48s nginx1-744b889544-zr5xz 1/1 Running 0 8m20s
kubectl get pods -n namespace2
期待される出力:
NAME READY STATUS RESTARTS AGE nginx2-556f95449f-cglpv 0/1 Pending 0 3m45s nginx2-556f95449f-crwk4 1/1 Running 0 9m31s nginx2-556f95449f-gg6q2 1/1 Running 0 9m31s nginx2-556f95449f-pvgrl 0/1 Pending 0 8m38s nginx2-556f95449f-zv8wn 0/1 Pending 0 3m45s
kubectl get pods -n namespace3
期待される出力:
NAME READY STATUS RESTARTS AGE nginx3-578877666-msd7f 1/1 Running 0 8m46s nginx3-578877666-nfdwv 0/1 Pending 0 8m56s nginx3-578877666-psszr 0/1 Pending 0 8m57s nginx3-578877666-xfsss 1/1 Running 0 9m8s nginx3-578877666-xpl2p 0/1 Pending 0 8m56s
kubectl get pods -n namespace4
期待される出力:
nginx4-754b767f45-g9954 1/1 Running 0 4m32s nginx4-754b767f45-j4v7v 0/1 Pending 0 4m32s nginx4-754b767f45-jk2t7 0/1 Pending 0 4m32s nginx4-754b767f45-nhzpf 0/1 Pending 0 4m32s nginx4-754b767f45-tv5jj 1/1 Running 0 4m32s
同様に、
root.b.2
のmin
は10
に設定されます。 したがって、nginx4
が作成されると、ポッドにはmin
リソースが必要になります。 スケジューラは、root.b
に属し、root.a
によって一時的に使用されるCPUコアを再要求します。 これにより、nginx4
のポッドスケジューリングに対して、最低10 (min.cpu=10
) のCPUコアが確保されます。スケジューラは、一時的に使用された10個のCPUコアを再要求する前に、
root.a
のワークロードの優先度クラス、可用性、作成時間などの他の要素も考慮します。 したがって、nginx4
のポッドが再利用された10 (min.cpu=10
) CPUコアに基づいてスケジュールされた後、2つのポッドは実行状態になり、他の3つは保留状態になります。4つのデプロイメントがすべて作成されると、各名前空間のすべてのポッドは、リソースクォータに対して保証された
最小量のリソース
で実行されます。
関連ドキュメント
kube-schedulerのリリースノートの詳細については、「kube-scheduler」をご参照ください。
ACKは、kube-schedulerフレームワークに基づいて開発されたギャングスケジューリング機能をサポートしています。 ギャングスケジューリングは、相関ポッドのグループが同時にスケジュールされることを保証する。 スケジューリング要件が満たされない場合、どのポッドもスケジューリングされません。 Gangスケジューリングは、All-or-Nothingシナリオでのジョブスケジューリングのソリューションを提供します。 Gangスケジューリングは、SparkやHadoopジョブなど、すべてのビッグデータコンピューティングジョブのリソースを同時にスケジュールまたは共有する必要がある分散アプリケーションに適しています。 詳細については、「ギャングスケジューリングの操作」をご参照ください。