arrow_back

GKE 自動スケーリング戦略の理解と組み合わせ

ログイン 参加
知識をテストして、コミュニティで共有しましょう
done
700 を超えるハンズオンラボ、スキルバッジ、コースへのアクセス

GKE 自動スケーリング戦略の理解と組み合わせ

ラボ 1時間 30分 universal_currency_alt クレジット: 5 show_chart 中級
info このラボでは、学習をサポートする AI ツールが組み込まれている場合があります。
知識をテストして、コミュニティで共有しましょう
done
700 を超えるハンズオンラボ、スキルバッジ、コースへのアクセス

GSP768

Google Cloud セルフペース ラボ

概要

Google Kubernetes Engine には、Pod およびインフラストラクチャを水平方向または垂直方向に自動スケーリングするソリューションがあります。この仕組みにより、ワークロードを可能な限り効率的に実行し、支払いを使用分だけに抑えることができるので、コストの最適化に大きな効果を発揮します。

このラボでは、Pod レベルのスケーリングについて、水平 Pod 自動スケーリング垂直 Pod 自動スケーリングを設定して動作を確認します。また、ノードレベルのスケーリングについて、クラスタ オートスケーラー(インフラストラクチャの水平方向のソリューション)とノードの自動プロビジョニング(インフラストラクチャの垂直方向のソリューション)を設定して動作を確認します。まず、これらの自動スケーリング ツールを使って、需要が低い期間にリソースをできるだけ節約し、クラスタのサイズを縮小します。その後、クラスタの需要を増加させ、自動スケーリングによって可用性が維持される様子を見ていきます。

目標

このラボでは、次の方法について学びます。

  • HorizontalPodAutoscaler を使って、Deployment のレプリカ数を減らす
  • VerticalPodAutoscaler を使って、Deployment の CPU リクエストを減少させる
  • クラスタ オートスケーラーを使って、クラスタで使用するノード数を減らす
  • ノードの自動プロビジョニングを使って、ワークロードに最適なノードプールを自動的に作成する
  • 需要急増時の自動スケーリングの動作をテストする
  • 一時停止 Pod を使って、クラスタのオーバープロビジョニングを行う

設定と要件

[ラボを開始] ボタンをクリックする前に

こちらの手順をお読みください。ラボの時間は記録されており、一時停止することはできません。[ラボを開始] をクリックするとスタートするタイマーは、Google Cloud のリソースを利用できる時間を示しています。

このハンズオンラボでは、シミュレーションやデモ環境ではなく、実際のクラウド環境を使ってご自身でラボのアクティビティを行うことができます。そのため、ラボの受講中に Google Cloud にログインおよびアクセスするための、新しい一時的な認証情報が提供されます。

このラボを完了するためには、下記が必要です。

  • 標準的なインターネット ブラウザ(Chrome を推奨)
注: このラボの実行には、シークレット モードまたはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウント間の競合を防ぎ、個人アカウントに追加料金が発生することを防ぎます。
  • ラボを完了するために十分な時間を確保してください。ラボをいったん開始すると一時停止することはできません。
注: すでに個人の Google Cloud アカウントやプロジェクトをお持ちの場合でも、このラボでは使用しないでください。アカウントへの追加料金が発生する可能性があります。

ラボを開始して Google Cloud コンソールにログインする方法

  1. [ラボを開始] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるポップアップでお支払い方法を選択してください。 左側の [ラボの詳細] パネルには、以下が表示されます。

    • [Google Cloud コンソールを開く] ボタン
    • 残り時間
    • このラボで使用する必要がある一時的な認証情報
    • このラボを行うために必要なその他の情報(ある場合)
  2. [Google Cloud コンソールを開く] をクリックします(Chrome ブラウザを使用している場合は、右クリックして [シークレット ウィンドウでリンクを開く] を選択します)。

    ラボでリソースが起動し、別のタブで [ログイン] ページが表示されます。

    ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。

    注: [アカウントの選択] ダイアログが表示されたら、[別のアカウントを使用] をクリックします。
  3. 必要に応じて、下のユーザー名をコピーして、[ログイン] ダイアログに貼り付けます。

    {{{user_0.username | "Username"}}}

    [ラボの詳細] パネルでも [ユーザー名] を確認できます。

  4. [次へ] をクリックします。

  5. 以下のパスワードをコピーして、[ようこそ] ダイアログに貼り付けます。

    {{{user_0.password | "Password"}}}

    [ラボの詳細] パネルでも [パスワード] を確認できます。

  6. [次へ] をクリックします。

    重要: ラボで提供された認証情報を使用する必要があります。Google Cloud アカウントの認証情報は使用しないでください。 注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
  7. その後次のように進みます。

    • 利用規約に同意してください。
    • 一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
    • 無料トライアルには登録しないでください。

その後、このタブで Google Cloud コンソールが開きます。

注: Google Cloud のプロダクトやサービスのリストを含むメニューを表示するには、左上のナビゲーション メニューをクリックします。ナビゲーション メニュー アイコン

Cloud Shell をアクティブにする

Cloud Shell は、開発ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Cloud Shell を使用すると、コマンドラインで Google Cloud リソースにアクセスできます。

  1. Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする」アイコン 「Cloud Shell をアクティブにする」アイコン をクリックします。

接続した時点で認証が完了しており、プロジェクトに各自の PROJECT_ID が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。

Your Cloud Platform project in this session is set to YOUR_PROJECT_ID

gcloud は Google Cloud のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。

  1. (省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
gcloud auth list
  1. [承認] をクリックします。

  2. 出力は次のようになります。

出力:

ACTIVE: * ACCOUNT: student-01-xxxxxxxxxxxx@qwiklabs.net To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (省略可)次のコマンドを使用すると、プロジェクト ID を一覧表示できます。
gcloud config list project

出力:

[core] project = <project_ID>

出力例:

[core] project = qwiklabs-gcp-44776a13dea667a6 注: Google Cloud における gcloud ドキュメントの全文については、gcloud CLI の概要ガイドをご覧ください。

テスト環境のプロビジョニング

  1. デフォルト ゾーンを に設定します。
gcloud config set compute/zone {{{project_0.default_zone | zone}}}
  1. 次のコマンドを実行して、 ゾーンに 3 つのノードクラスタを作成します。
gcloud container clusters create scaling-demo --num-nodes=3 --enable-vertical-pod-autoscaling

このラボでは、水平 Pod 自動スケーリングについて説明するために、php-apache イメージに基づくカスタム Docker イメージを使用します。このイメージは、CPU 使用率の高い計算を実行する index.php ページを定義します。このイメージの Deployment をモニタリングします。

  1. php-apache Deployment のマニフェストを以下のように作成します。
cat << EOF > php-apache.yaml apiVersion: apps/v1 kind: Deployment metadata: name: php-apache spec: selector: matchLabels: run: php-apache replicas: 3 template: metadata: labels: run: php-apache spec: containers: - name: php-apache image: k8s.gcr.io/hpa-example ports: - containerPort: 80 resources: limits: cpu: 500m requests: cpu: 200m --- apiVersion: v1 kind: Service metadata: name: php-apache labels: run: php-apache spec: ports: - port: 80 selector: run: php-apache EOF
  1. 新しく作成したマニフェストをクラスタに適用します。
kubectl apply -f php-apache.yaml

[進行状況を確認] をクリックして、上記のタスクを実行したことを確認します。 テスト環境のプロビジョニング

タスク 1. 水平 Pod 自動スケーリングで Pod をスケールする

水平 Pod 自動スケーリングとは、Pod の数を自動的に調整して Kubernetes ワークロードの形状を変化させる仕組みです。この調整は、ワークロードの CPU やメモリの消費量、Kubernetes から報告されるカスタム指標、クラスタ外部のソースから取得した外部指標に応じて行われます。

  1. Cloud Shell で以下のコマンドを実行し、クラスタの Deployment を検査します。
kubectl get deployment

以下のように、php-apache Deployment で 3/3 Pod が実行されていることを確認できます。

NAME READY UP-TO-DATE AVAILABLE AGE php-apache 3/3 3 3 91s 注: 使用可能な Pod が 3 つ表示されない場合は、Pod が作成されるまで 1 分ほど待ってから前のコマンドを再度試行してください。使用可能な Pod が 1/1 と表示された場合は、一定の時間が経過して Deployment がスケールダウンした可能性があります。
  1. php-apache Deployment に水平自動スケーリングを適用します。
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10

[進行状況を確認] をクリックして、上記のタスクを実行したことを確認します。 水平 Pod 自動スケーリングで Pod をスケールする

上記の autoscale コマンドでは、php-apache Deployment によって制御される Pod のレプリカの数が 1~10 個に維持されるように、HorizontalPodAutoscaler が構成されます。cpu-percent フラグでは、リクエストされた CPU のうち、すべての Pod の目標 CPU 使用率が平均で 50% となるように指定しています。HPA は、すべての Pod の平均 CPU 使用率が 50% に維持されるように、(Deployment を介して)レプリカの数を調整します。

  1. HorizontalPodAutoscaler の現在のステータスを確認します。
kubectl get hpa

[Targets] 列に 1%/50% と表示されていることを確認します。

これは、Deployment 内の Pod において、現在の平均 CPU 使用率が、目標値に対して 1% であることを表しています。この時点では php-apache アプリでトラフィックを受信していないため、これは想定どおりの結果です。

注: <unknown>/50% と表示される場合は、少し待ってから kubectl get hpa コマンドを再実行します。この場合、HPA によって評価がまだ作成されていません。

また、[Replicas] 列も確認します。最初は、この値は 3 になっています。この数は、必要な Pod 数が変わるにつれてオートスケーラーによって調整されます。

この場合は、autoscale コマンドの実行時に指定した Pod の最小数に Deployment がスケールダウンされます。水平 Pod 自動スケーリングには 5~10 分ほどかかり、スケーリングの方法によっては Pod のシャットダウンや新しい Pod の起動が必要です。

ラボの次の手順に進んでください。オートスケーラー結果は後ほど確認します。

注: このラボでは、cpu-percent をオートスケーラーの目標指標として使用していますが、カスタム指標を定義することも可能です。カスタム指標を定義すると、ログに取り込まれたその他の有用な指標に基づいて Pod をスケールできます。

タスク 2. 垂直 Pod 自動スケーリングで Pod サイズをスケールする

垂直 Pod 自動スケーリングを使用すると、コンテナの CPU リクエストやメモリ リクエストの値を考える必要がなくなります。オートスケーラーは、CPU およびメモリのリクエストと上限の値を推奨します。また、それらの値を自動的に更新できます。

注: CPU とメモリに対しては、垂直 Pod 自動スケーリングと水平 Pod 自動スケーリングを併用しないでください。両方のオートスケーラーが同じ指標で需要の変化に対応するため、競合が発生します。ただし、重複を回避するため、CPU またはメモリに基づく VPA と、カスタム指標に基づく HPA を併用するのはかまいません。

垂直 Pod 自動スケーリングは、scaling-demo クラスタですでに有効になっています。

  1. 確認のために、以下のコマンドを実行します。
gcloud container clusters describe scaling-demo | grep ^verticalPodAutoscaling -A 1

enabled: true と出力されるはずです。

注: 既存のクラスタで垂直 Pod 自動スケーリングを有効にするには、gcloud container clusters update scaling-demo --enable-vertical-pod-autoscaling を実行します。

VPA のデモを行うために、hello-server アプリをデプロイします。

  1. hello-server Deployment をクラスタに適用します。
kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:1.0
  1. Deployment が正しく作成されたことを確認します。
kubectl get deployment hello-server
  1. この Deployment に、450m の CPU リソース リクエストを割り当てます。
kubectl set resources deployment hello-server --requests=cpu=450m
  1. 続けて、以下のコマンドを実行して、hello-server Pod のコンテナの詳細を確認します。
kubectl describe pod hello-server | sed -n "/Containers:$/,/Conditions:/p"
  • 出力で、Requests を確認します。先ほど割り当てた 450m CPU をこの Pod が現在リクエストしていることがわかります。
  1. 次に、VerticalPodAutoscalerのマニフェストを以下のように作成します。
cat << EOF > hello-vpa.yaml apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: name: hello-server-vpa spec: targetRef: apiVersion: "apps/v1" kind: Deployment name: hello-server updatePolicy: updateMode: "Off" EOF

上記のコマンドにより、更新ポリシーが Off に設定された、hello-server Deployment をターゲットとする VerticalPodAutoscaler マニフェストが生成されます。VPA には、以下の 3 つの更新ポリシーの中からアプリケーションに適したものを設定できます。

  • Off: 過去のデータに基づいて VPA が推奨値を生成します。過去のデータは手動で適用できます。
  • Initial: VPA の推奨値を使用して新しい Pod が作成されます。作成された Pod のサイズは変わりません。
  • Auto: Pod が定期的に削除され、推奨値のサイズと一致するように再作成されます。
  1. hello-vpa のマニフェストを適用します。
kubectl apply -f hello-vpa.yaml
  1. 少し待ってから、VerticalPodAutoscaler を確認します。
kubectl describe vpa hello-server-vpa

出力の末尾にある「Container Recommendations」を見つけます。見つからない場合は、もう少し待ってから上記のコマンドを再度実行してください。ここには以下のタイプの推奨値が表示され、それぞれに CPU とメモリの値が示されます。

  • Lower Bound: サイズ変更をトリガーするために VPA が確認する下限値です。Pod の使用量がこの値に達しない場合、VPA はその Pod を削除してスケールダウンします。
  • Target: Pod のサイズ変更時に VPA が使用する値です。
  • Uncapped Target: VPA に最小容量または最大容量が割り当てられていない場合、これが VPA の目標使用量になります。
  • Upper Bound: サイズ変更をトリガーするために VPA が確認する上限値です。Pod の使用量がこの値を超えた場合、VPA はその Pod を削除してスケールアップします。

これらの値を確認すると、VPA はこのコンテナの CPU リクエストを以前の 100m ではなく 25m に設定することを推奨していることがわかります。また、メモリのリクエスト量に関する推奨値も提示しています。この時点で、これらの推奨値を hello-server Deployment に手動で適用できます。

注: 垂直 Pod 自動スケーリングでは、コンテナの過去のデータに基づいて推奨値が算出されます。実際には、少なくとも 24 時間待機してこの推奨データを収集してから、変更を加えることをおすすめします。
  1. このラボでは、VPA の動作とその効果を確認するために、hello-vpa の更新ポリシーを Auto に変更してスケーリングを観察します。

  2. マニフェストを編集し、ポリシーを Auto に設定してこの構成を適用します。

sed -i 's/Off/Auto/g' hello-vpa.yaml kubectl apply -f hello-vpa.yaml

Pod のサイズを変更するには、VerticalPodAutoscaler が Pod を削除し、新しいサイズで再作成する必要があります。ダウンタイムを回避するため、VPA はデフォルトで最後のアクティブな Pod の削除とサイズ変更を行いません。そのため、VPA による変更を確認するには、少なくとも 2 つのレプリカが必要です。

  1. hello-server Deployment を 2 つのレプリカにスケールします。
kubectl scale deployment hello-server --replicas=2
  1. Pod を確認します。
kubectl get pods -w
  1. hello-server-xxx Pod が terminating または pending ステータスになるまで待ちます(または、[Kubernetes Engine] > [ワークロード] に移動します)。

出力

これは、VPA が Pod の削除とサイズ変更を行っていることを示しています。これが確認できたら、Ctrl+c キーを押してコマンドを終了します。

[進行状況を確認] をクリックして、上記のタスクを実行したことを確認します。 垂直 Pod 自動スケーリングで Pod サイズをスケールする

タスク 3. HPA の結果

この時点で、HorizontalPodAutoscaler による php-apache Deployment のスケールダウンが完了しているはずです。

  1. 以下のコマンドを実行して HPA を確認します。
kubectl get hpa
  • [Replicas] 列を調べます。php-apache Deployment が 1 Pod にスケールダウンされたことがわかります。
注: php-apache Deployment のレプリカ数がまだ 3 である場合は、オートスケーラーの処理が完了するまでもう少し待ってください。
  • HPA は、現在アプリがアクティブでないことを確認したうえで、未使用のリソースをすべて削除します。さらに、php-apache アプリへの需要が増加した場合は、その負荷に対応できるように再びスケールアップします。
注: アプリケーションの可用性を重視している場合は、スケールにかかる時間を考慮して、HorizontalPodAutoscaler の最小 Pod 数を少し多めに設定しておくことをおすすめします。

この方法は、コストの最適化について検討する際に非常に便利です。オートスケーラーを適切に調整することで、需要の変動に関わらず、アプリケーションの高可用性を維持しながら不要なリソースへの出費を削減することが可能になります。

タスク 4. VPA の結果

この時点で、VPA による hello-server Deployment の Pod のサイズ変更が終了しているはずです。

  1. Pod を確認します。
kubectl describe pod hello-server | sed -n "/Containers:$/,/Conditions:/p"
  1. [Requests:] フィールドを確認します。
  • VerticalPodAutoscaler によって、目標使用量に基づき Pod が再作成されています。リクエストしている CPU 量が減っており、一定量のメモリをリクエストしていることがわかります。
Requests: cpu: 25m memory: 262144k 注: Pod のいずれかについて CPU リクエストが依然として 450m と表示されているなら、kubectl set resources deployment hello-server --requests=cpu=25m コマンドを使用して、CPU リソースを目標値に手動で設定します。自動モードの VPA では長い時間を要するか、正確なデータを収集する時間なしに不正確な上限または下限の値を設定することがあります。このラボでは、時間を無駄にしないために、便宜上、「Off」モードに設定されているものとして推奨値を使用します。

この場合、VPA はリソース使用の最適化に高い効果を発揮し、実際にコストの節約に役立ちます。CPU リクエストの元の値は 400m で、コンテナが必要とする量を上回っていました。これを推奨値の 25m に調整することで、ノードプールで使用する CPU を減らせるだけでなく、クラスタ内でプロビジョニングされるノード数を減らせる可能性も出てきます。

更新ポリシーを Auto に設定すると、hello-server Deployment の有効期間中、VPA はその Pod の削除とサイズ変更を続けます。トラフィック量が多い場合はリクエスト量を増やして Pod をスケールアップし、ダウンタイム中は再びスケールダウンするといった具合です。この方法は、アプリケーションへの需要が徐々に増加する場合は効果的ですが、需要が急増したときは、可用性を失う恐れがあります。

アプリケーションによっては、更新ポリシーを Off に設定して VPA を使用し、必要に応じて推奨値に従うのが一般的には最も安全な方法です。これにより、リソース使用量を最適化し、同時にクラスタの可用性を最大化できます。

次のセクションでは、クラスタ オートスケーラーとノードの自動プロビジョニングを使用して、リソースの使用をさらに最適化する方法について説明します。

タスク 5. クラスタ オートスケーラー

クラスタ オートスケーラーは、需要に応じてノードを追加または削除するように設計されています。ノードの需要が高い場合、クラスタ オートスケーラーはノードプールにノードを追加して需要に対応します。需要が少ない場合、ノードを削除してクラスタを再びスケールダウンします。この仕組みにより、クラスタの高可用性を維持しながら、マシンの追加に伴う余計なコストを抑えることができます。

  1. クラスタの自動スケーリングを有効にします。
gcloud beta container clusters update scaling-demo --enable-autoscaling --min-nodes 1 --max-nodes 5

完了までに数分かかります。

クラスタのスケーリングでは、ノードを削除するタイミングを決定することにより、使用率の最適化とリソースの可用性との間でトレードオフが発生します。使用率の低いノードを削除するとクラスタの使用率は向上しますが、新しいワークロードの実行の際に、リソースが再度プロビジョニングされるのを待機しなければならない状況が生じる可能性があります。

このような決定を行うときに使用する自動スケーリング プロファイルを指定できます。現在使用できるプロファイルは次のとおりです。

  • Balanced: デフォルトのプロファイルです。
  • Optimize-utilization: クラスタ内で余剰リソースを保持するよりも使用率の最適化を優先させます。これを選択すると、クラスタ オートスケーラーはクラスタをより積極的にスケールダウンします。つまり、ノードをより多く、より迅速に削除できます。このプロファイルは、起動レイテンシに影響されないバッチ ワークロードで使用できるように最適化されています。
  1. スケーリングの効果を詳しく確認できるように、optimize-utilization 自動スケーリング プロファイルに切り替えます。
gcloud beta container clusters update scaling-demo \ --autoscaling-profile optimize-utilization
  1. 自動スケーリングを有効にした状態で、Google Cloud コンソールでクラスタを確認します。左上の 3 本線をクリックし、ナビゲーション メニューを開きます。

  2. ナビゲーション メニューで、[Kubernetes Engine] > [クラスタ] を選択します。

  3. [クラスタ] ページで、scaling-demo クラスタを選択します。

  4. scaling-demo クラスタのページで、[ノード] タブを選択します。

[ノード] タブ

  1. 3 つのノードのリソース使用量の概要を確認します。
注: 実際に表示される数値は、この画像とは異なる場合があります。Kubernetes では、リソースのプロビジョニングと割り当てが毎回同じように行われるわけではありません。

3 つのノードの [リクエストされた CPU] と [割り当て可能な CPU] の値を合計すると、それぞれ 1,555m と 2,820m になります。つまり、クラスタ全体で合計 1,265m CPU が利用可能であることがわかります。これは、1 つのノードで提供可能な量を上回っています。

現在のワークロードと需要を前提とすると、クラスタの使用率を最適化するには、ノードを 3 つではなく 2 つにまとめることができます。しかし、クラスタの自動的なスケールダウンはまだ行われていません。これは、システム Pod がクラスタ全体に分散しているからです。

このクラスタでは、kube-system Namespace で多数の Deployment が実行されるため、ロギング、モニタリング、自動スケーリングなどのさまざまな GKE サービスが動作可能です。

  1. このことは、Cloud Shell で以下のコマンドを実行して確認できます。
kubectl get deployment -n kube-system

デフォルトでは、これらの Deployment のシステム Pod のほとんどは、クラスタ オートスケーラーによって完全にオフラインにされ再スケジュールされることを回避します。これらの Pod は、他の Deployment や Service で使用されるデータを収集しているものが多いので、一般的にこれは期待通りの動作と言えます。たとえば、metrics-agent が一時的にダウンすると、VPA と HPA の収集データに抜けが生じる可能性があります。同様に、fluentd Pod がダウンすると、クラウドのログに抜けが生じる可能性があります。

このラボでは、kube-system Pod に Pod Distribution Budget を適用し、クラスタ オートスケーラーが Pod を別のノードに安全にリスケジュールできるようにします。こうすることで、クラスタをスケールダウンする余裕を確保できます。

Pod Distribution Budget(PDB)とは、アップグレードや Pod の削除、リソース不足などによる Pod の一時的な中断を Kubernetes で処理する方法を定義するものです。PDB では、Deployment の Pod 数について max-unavailablemin-available の両方、またはいずれかを定義できます。

  1. 以下のコマンドを実行して、各 kube-system Pod の Pod Disruption Budget を作成します。
kubectl create poddisruptionbudget kube-dns-pdb --namespace=kube-system --selector k8s-app=kube-dns --max-unavailable 1 kubectl create poddisruptionbudget prometheus-pdb --namespace=kube-system --selector k8s-app=prometheus-to-sd --max-unavailable 1 kubectl create poddisruptionbudget kube-proxy-pdb --namespace=kube-system --selector component=kube-proxy --max-unavailable 1 kubectl create poddisruptionbudget metrics-agent-pdb --namespace=kube-system --selector k8s-app=gke-metrics-agent --max-unavailable 1 kubectl create poddisruptionbudget metrics-server-pdb --namespace=kube-system --selector k8s-app=metrics-server --max-unavailable 1 kubectl create poddisruptionbudget fluentd-pdb --namespace=kube-system --selector k8s-app=fluentd-gke --max-unavailable 1 kubectl create poddisruptionbudget backend-pdb --namespace=kube-system --selector k8s-app=glbc --max-unavailable 1 kubectl create poddisruptionbudget kube-dns-autoscaler-pdb --namespace=kube-system --selector k8s-app=kube-dns-autoscaler --max-unavailable 1 kubectl create poddisruptionbudget stackdriver-pdb --namespace=kube-system --selector app=stackdriver-metadata-agent --max-unavailable 1 kubectl create poddisruptionbudget event-pdb --namespace=kube-system --selector k8s-app=event-exporter --max-unavailable 1

[進行状況を確認] をクリックして、上記のタスクを実行したことを確認します。 クラスタ オートスケーラー

各コマンドでは、それぞれ異なる kube-system Deployment の Pod をラベル(作成時に定義されたもの)を基に選択し、Deployment ごとに使用不可の Pod を 1 つ許可するように指定しています。これによって、オートスケーラーはシステム Pod をリスケジュールできるようになります。

PDB を設定すると、数分でクラスタのノードが 3 つから 2 つにスケールダウンされます。

  1. ノード数が全部で 2 つになるまで、Cloud Shell で以下のコマンドを繰り返し実行します。
kubectl get nodes

Google Cloud コンソールで、scaling-demo の [ノード] タブを更新し、リソースがどのようにパックされたかを調べます。

scaling-demo の [ノード] タブ

クラスタのノードを 3 つから 2 つに自動的にスケールダウンするように設定できました。

コストの面では、ノードプールをスケールダウンすることにより、クラスタへの需要が低い期間に課金対象のマシンを削減できるというメリットがあります。1 日のうちに需要が大きく変動する場合、このスケーリングがさらに顕著になることがあります。

重要なことは、クラスタ オートスケーラーでは不要なノードが削除され、垂直 Pod 自動スケーリング水平 Pod 自動スケーリングでは、需要に応じて CPU 使用率を減らすことでノードが不要になる、ということです。全体的なコストとリソースの使用量を最適化するうえで、これらのツールを併用することは効果的です。

このように、Pod をスケジュールする必要が生じると、それに応じてクラスタ オートスケーラーがノードの追加と削除を行います。ただし、GKE には、ノードの自動プロビジョニングと呼ばれる、垂直方向にスケールする別の機能もあります。

タスク 6. ノードの自動プロビジョニング

ノードの自動プロビジョニング(NAP)では、需要に一致するようにサイズ設定された新しいノードプールが実際に追加されます。ノードの自動プロビジョニングを使用しないと、クラスタ オートスケーラーはユーザーが指定したノードプール内にのみ新しいノードを作成します。つまり、新しいノードのマシンタイプは、そのプールの他のノードのものと同じになります。大規模なスケーリングが不要なバッチ ワークロードやその他のアプリ向けにリソースの使用量を最適化する場合は、この方法が適しています。なぜなら、ユースケース用に最適化されたノードプールを作成するのは、既存のプールにノードを追加するよりも時間がかかることがあるからです。

  • ノードの自動プロビジョニングを有効にします。
gcloud container clusters update scaling-demo \ --enable-autoprovisioning \ --min-cpu 1 \ --min-memory 2 \ --max-cpu 45 \ --max-memory 160

このコマンドでは、CPU とメモリリソースの最小数と最大数を指定しています。これは、クラスタ全体に対しての値です。

NAP の処理には少し時間がかかる場合があります。また、scaling-demo クラスタの現在の状態では、新しいノードプールが作成されない可能性があります。

次のセクションでは、クラスタの需要を増加させ、オートスケーラーと NAP の動作を確認します。

[進行状況を確認] をクリックして、上記のタスクを実行したことを確認します。 ノードの自動プロビジョニング

タスク 7. 需要を増大させてテストする

ここまでは、アプリケーションの需要が低いときに、HPA、VPA、クラスタ オートスケーラーでどのようにリソースとコストを節約できるのか確認しました。次に、需要を増大させて、これらのツールがどのように可用性に対処するのか見ていきましょう。

  1. Cloud Shell で以下の + アイコンを押して、新しいタブを開きます。

Cloud Shell の追加アイコン

  1. 新しいタブで以下のコマンドを実行し、クエリの無限ループを php-apache サービスに送信します。
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
  1. 元の Cloud Shell タブに戻ります。

  2. 少し経ってから以下のコマンドを実行すると、HPA に対する CPU 負荷が高くなっていることがわかります。

kubectl get hpa

少し待ってから同じコマンドを再度実行して、目標が 100% を上回るのを確認します。

出力

  1. 以下のコマンドを定期的に実行して、負荷の増加にクラスタがどのように対処しているのかモニタリングします。
kubectl get deployment php-apache

Google Cloud コンソールの [ノード] タブを更新して、クラスタをモニタリングすることもできます。

数分後、以下のことが起きます。

  • まず、負荷の増大に対応するために、HPA によって php-apache Deployment が自動的にスケールアップされます。
  • 次に、需要の増大に対応するために、クラスタ オートスケーラーで新しいノードをプロビジョニングする必要が生じます。
  • 最後に、ノードの自動プロビジョニングによって、クラスタのワークロードの CPU リクエストとメモリ リクエスト用に最適化されたノードプールが作成されます。この負荷テストでは CPU を上限まで使用しているので、CPU が高く、メモリが少ないノードプールになります。

php-apache Deployment が 7 レプリカにスケールアップされ、[ノード] タブに次のように表示されるまで待ちます。

ノードリスト

  1. 負荷テストを実行した Cloud Shell タブに戻り、Ctrl+c キーを押してテストをキャンセルします。需要が再び低下するにつれ、最終的にクラスタは再度スケールダウンします。

需要の増大に合わせて、クラスタが効率的にスケールアップしました。ただし、この需要の急増に対応するために要した時間に注意する必要があります。新しいリソースのプロビジョニング中に可用性が失われることは、多くのアプリケーションにとって問題となります。

タスク 8. 負荷の増大に合わせて最適化する

負荷が増大してスケールアップするときには、水平 Pod 自動スケーリングによって新しい Pod が追加され、垂直 Pod 自動スケーリングによって Pod のサイズが変更されます。これらは、ユーザーの設定に応じて行われます。既存のノードにスペースがある場合は、イメージの pull を省いて、新しい Pod で即座にアプリケーションの実行を開始できることがあります。アプリケーションをまだデプロイしていないノードを操作している場合、アプリケーションを実行する前にコンテナ イメージをダウンロードする時間が追加で発生することがあります。

つまり、既存のノードに十分なスペースがない状態でクラスタ オートスケーラーを使用している場合、処理の時間が長くなる可能性があります。具体的には、新しいノードのプロビジョニングと設定を行ってから、イメージをダウンロードして Pod を起動するという処理が必要となります。クラスタで行われたように、ノードの自動プロビジョナーによって新しいノードプールが作成される場合、ユーザーはまず新しいノードプールをプロビジョニングしてから、新しいノードに対して同じ手順を踏むことになるので、さらに時間がかかります。

注: 実際には、アプリで使用するコンテナ イメージをできるだけ小さくすることが重要です。イメージを小さくすると、Pod のコールド スタート時間が短くなります。なぜなら、クラスタ オートスケーラーがクラスタの新しいノードをプロビジョニングするときに、イメージが小さいほど短時間でノードにダウンロードできるからです。また、イメージが大きいと Pod の起動時間が長くなります。これにより、トラフィックの急増時に新しいノードをプロビジョニングするときのパフォーマンスが低下します。

自動スケーリングに伴うこうしたレイテンシに対処するには、少しだけオーバープロビジョニングしておくと、自動スケーリング時にアプリにかかる負担を減らすことができます。これは、コストを最適化するうえで非常に重要です。なぜなら、支払いを必要なリソース分のみに抑えるのに越したことはないですが、一方で、アプリのパフォーマンスも犠牲にしたくはないからです。

オーバープロビジョニングの量を調べるには、以下の式を使用します。

数式:(1 - バッファ)÷(1 + トラフィック)

クラスタの CPU 利用率を例にとって考えましょう。100% に達しないようにするため、安全な幅を維持するための 15% のバッファを選択するとします。次に、この式に含まれるトラフィックの変数は、2~3 分後のトラフィックの伸び率の予測値を表しています。先ほど行った負荷テストでは、0~150% という極端な伸び率の例を取り上げましたが、ここでは、より平均的なトラフィックの伸び率として 30% を設定します。

数式:(1 - 15% バッファ)÷(1 + 30% トラフィック増加)= 65%

これらの値をあてはめると、安全バッファが約 65% として求められます。これは、スケールアップを処理しながらレイテンシの問題を最小限に抑えるには、リソースを約 65% オーバープロビジョニングしておくのが望ましい、ということを意味します。

クラスタの自動スケーリングを有効にしながら、クラスタをオーバープロビジョニングするには、一時停止 Pod の使用が効果的です。

一時停止 Pod とは優先順位の低い Deployment であり、削除したり、優先順位の高い Deployment と置き換えたりすることが可能です。つまり、バッファ スペースを確保する以外は何もしない、優先度の低い Pod を作成できます。優先順位の高い Pod でスペースが必要になると、一時停止 Pod が削除され、別のノードまたは新しいノードにリスケジュールされます。そして、優先順位の高い Pod に必要なスペースが確保され、すばやくスケジュールされるという仕組みになっています。

  1. 一時停止 Pod のマニフェストを作成します。
cat << EOF > pause-pod.yaml --- apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: overprovisioning value: -1 globalDefault: false description: "Priority class used by overprovisioning." --- apiVersion: apps/v1 kind: Deployment metadata: name: overprovisioning namespace: kube-system spec: replicas: 1 selector: matchLabels: run: overprovisioning template: metadata: labels: run: overprovisioning spec: priorityClassName: overprovisioning containers: - name: reserve-resources image: k8s.gcr.io/pause resources: requests: cpu: 1 memory: 4Gi EOF
  1. このマニフェストをクラスタに適用します。
kubectl apply -f pause-pod.yaml
  1. 少し待ってから、scaling-demo クラスタの [ノード] タブを更新します。

新しいノードが作成されたことを確認してください。おそらく、新しく作成された一時停止 Pod に合わせて、新しいノードプール内に作成されているはずです。ここで負荷テストを再度実行すると、php-apache Deployment に追加のノードが必要なときに、一時停止 Pod があるノードにスケジュールされ、一時停止 Pod は新しいノードに移されます。この方法の優れているところは、ダミーの一時停止 Pod によりクラスタが事前に新しいノードをプロビジョニングできるため、実際のアプリケーションをより迅速にスケールアップできるという点です。トラフィック量の増加が想定される場合は一時停止 Pod を追加できますが、1 つのノードにつき 1 個にとどめることをおすすめします。

[進行状況を確認] をクリックして、上記のタスクを実行したことを確認します。 負荷の増大に合わせて最適化する

お疲れさまでした

これで完了です。このラボでは、クラスタが需要に応じて自動的かつ効率的にスケールアップまたはスケールダウンするように構成しました。水平 Pod 自動スケーリングと垂直 Pod 自動スケーリングでは、クラスタの Deployment を自動的にスケールするためのソリューションを提供し、クラスタ オートスケーラーとノードの自動プロビジョニングでは、クラスタのインフラストラクチャを自動的にスケールするためのソリューションを提供しました。

この場合も、どのツールが適しているかはワークロードによって異なります。これらのオートスケーラーを注意して使用することで、必要なときは可用性を最大化する一方で、需要が低いときは必要なものだけに支払いを抑えることが可能となります。コストの面では、リソースの使用量を最適化してコストを節約できます。

次のステップと詳細情報

このラボで取り上げたトピックの詳細については、次のリソースをご確認ください。

Google Cloud トレーニングと認定資格

Google Cloud トレーニングと認定資格を通して、Google Cloud 技術を最大限に活用できるようになります。必要な技術スキルとベスト プラクティスについて取り扱うクラスでは、学習を継続的に進めることができます。トレーニングは基礎レベルから上級レベルまであり、オンデマンド、ライブ、バーチャル参加など、多忙なスケジュールにも対応できるオプションが用意されています。認定資格を取得することで、Google Cloud テクノロジーに関するスキルと知識を証明できます。

マニュアルの最終更新日: 2024 年 2 月 1 日

ラボの最終テスト日: 2023 年 9 月 20 日

Copyright 2024 Google LLC All rights reserved. Google および Google のロゴは Google LLC の商標です。その他すべての企業名および商品名はそれぞれ各社の商標または登録商標です。

このコンテンツは現在ご利用いただけません

利用可能になりましたら、メールでお知らせいたします

ありがとうございます。

利用可能になりましたら、メールでご連絡いたします