arrow_back

GKE Workload Optimization

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

GKE Workload Optimization

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

GSP769

Google Cloud セルフペース ラボ

概要

使用するリソースに対してのみ請求が発生する課金モデルは、Google Cloud の多くの利点の一つです。この点を考慮すると、アプリとインフラストラクチャに対して適切な量のリソースを割り当てるだけでなく、そのリソースを最も効率的な方法で使用することが非常に重要です。GKE には、さまざまなリソースやサービスの使用量を減らしながら、アプリケーションの可用性も向上できるツールや手法が多くあります。

このラボでは、リソースの効率性やワークロードの可用性の向上に役立つ、いくつかのコンセプトについて説明します。クラスタのワークロードを理解して微調整することで、必要なリソースのみを使用して、クラスタのコストを最適化できます。

目標

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

  • Ingress によるコンテナ ネイティブのロードバランサを作成する
  • アプリケーションの負荷テストを行う
  • liveness と readiness のプローブを構成する
  • Pod Disruption Budget を作成する

設定と要件

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

こちらの手順をお読みください。ラボの時間は記録されており、一時停止することはできません。[ラボを開始] をクリックするとスタートするタイマーは、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. [承認] をクリックします。

  2. 3 つのノードを含むクラスタを作成します。

gcloud container clusters create test-cluster --num-nodes=3 --enable-ip-alias

--enable-ip-alias フラグは、Ingress によるコンテナ ネイティブのロード バランシングに必要な Pod のエイリアス IP を使用できるようにするために含まれています。

このラボでは、シンプルな HTTP ウェブアプリを、最初は単一の Pod としてデプロイします。

  1. gb-frontend Pod のマニフェストを作成します。
cat << EOF > gb_frontend_pod.yaml apiVersion: v1 kind: Pod metadata: labels: app: gb-frontend name: gb-frontend spec: containers: - name: gb-frontend image: gcr.io/google-samples/gb-frontend-amd64:v5 resources: requests: cpu: 100m memory: 256Mi ports: - containerPort: 80 EOF
  1. 新しく作成したマニフェストをクラスタに適用します。
kubectl apply -f gb_frontend_pod.yaml 注: このタスクのスコアが表示されるまで、1~2 分かかる場合があります。

[進行状況を確認] をクリックして、目標に沿って進行していることを確認します。 ラボ環境のプロビジョニング

タスク 1. Ingress によるコンテナ ネイティブのロード バランシング

コンテナ ネイティブのロード バランシングにより、ロードバランサは Kubernetes Pod を直接ターゲットにすることも、トラフィックを Pod に均等に分配することもできます。

コンテナ ネイティブのロード バランシングを使用しない場合、ロードバランサのトラフィックはノード インスタンス グループに送られ、iptables ルールを介して Pod にルーティングされます。しかし、これらの Pod は同じノードにあるとは限りません。

ロードバランサのトラフィック フロー

コンテナ ネイティブのロード バランシングにより、Pod はロード バランシングのコア オブジェクトになることができるため、ネットワーク ホップ数を削減できる可能性があります。

ロードバランサのトラフィック フロー

コンテナ ネイティブのロード バランシングを使用すると、より効率的なルーティングだけでなく、ネットワーク使用率の大幅な減少、パフォーマンスの向上、Pod 間での均等なトラフィック分配、アプリケーション レベルのヘルスチェックが実現します。

コンテナ ネイティブなロード バランシングを利用するには、VPC ネイティブの設定をクラスタで有効にする必要があります。これは、クラスタを作成して --enable-ip-alias フラグを含めたときにも説明しました。

  1. 次のマニフェストでは、ClusterIP Service を構成します。ClusterIP Service は、アプリケーション Pod にトラフィックをルーティングして、GKE がネットワーク エンドポイント グループを作成できるようにするために使用されます。
cat << EOF > gb_frontend_cluster_ip.yaml apiVersion: v1 kind: Service metadata: name: gb-frontend-svc annotations: cloud.google.com/neg: '{"ingress": true}' spec: type: ClusterIP selector: app: gb-frontend ports: - port: 80 protocol: TCP targetPort: 80 EOF

マニフェストには annotations フィールドが含まれています。このフィールドでは、cloud.google.com/neg のアノテーションにより、Ingress が作成されたときにアプリケーションでコンテナ ネイティブのロード バランシングが有効になります。

  1. 変更をクラスタに適用します。
kubectl apply -f gb_frontend_cluster_ip.yaml
  1. 次に、アプリケーションで Ingress を作成します。
cat << EOF > gb_frontend_ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: gb-frontend-ingress spec: defaultBackend: service: name: gb-frontend-svc port: number: 80 EOF
  1. 変更をクラスタに適用します。
kubectl apply -f gb_frontend_ingress.yaml

Ingress が作成されると、クラスタが実行される各ゾーンにネットワーク エンドポイント グループ(NEG)とともに HTTP(S) ロードバランサが作成されます。数分経過すると、Ingress に外部 IP が割り当てられます。

作成されたロードバランサには、プロジェクトで実行されるバックエンド サービスが含まれます。このバックエンド サービスは、Cloud Load Balancing によるトラフィックの分散方法を定義します。また、このバックエンド サービスにはヘルス ステータスが関連付けられています。

  1. バックエンド サービスのヘルス ステータスを確認するには、最初に名前を取得します。
BACKEND_SERVICE=$(gcloud compute backend-services list | grep NAME | cut -d ' ' -f2)
  1. サービスのヘルス ステータスを取得します。
gcloud compute backend-services get-health $BACKEND_SERVICE --global

ヘルスチェックで正常なステータスが返されるまでに数分かかります。

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

--- backend: https://www.googleapis.com/compute/v1/projects/qwiklabs-gcp-00-27ced9534cde/zones/us-central1-a/networkEndpointGroups/k8s1-95c051f0-default-gb-frontend-svc-80-9b127192 status: healthStatus: - healthState: HEALTHY instance: https://www.googleapis.com/compute/v1/projects/qwiklabs-gcp-00-27ced9534cde/zones/us-central1-a/instances/gke-test-cluster-default-pool-7e74f027-47qp ipAddress: 10.8.0.6 port: 80 kind: compute#backendServiceGroupHealth 注: このヘルスチェックは Google Cloud ロードバランサの一部であり、個々の Pod のヘルスチェックに使用できる liveness プローブと readiness プローブ(Kubernetes API によって提供)とは異なります。Google Cloud ロードバランサのヘルスチェックでは、プロジェクトの VPC の外部にある特別なルートを使用してヘルスチェックを実行し、バックエンドが正常かどうかを判断します。

各インスタンスのヘルス ステータスが正常であると報告されると、外部 IP 経由でアプリケーションにアクセスできます。

  1. 次のコマンドで取得します。
kubectl get ingress gb-frontend-ingress
  1. ブラウザ ウィンドウで外部 IP を入力すると、アプリケーションが読み込まれます。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 Ingress によるコンテナ ネイティブのロード バランシング

タスク 2. アプリケーションの負荷テスト

アプリケーションのキャパシティを把握することは、アプリケーションの Pod に対するリソースのリクエストと制限を選択するときや、最適な自動スケーリング戦略を決定するときに重要なステップです。

ラボの開始時に、アプリケーションを単一の Pod としてデプロイしました。自動スケーリングが構成されていない単一の Pod で実行されているアプリケーションの負荷テストを行うと、そのアプリケーションが処理できる同時リクエストの数、必要な CPU とメモリの量、高い負荷が発生した場合の影響を確認できます。

Pod の負荷テストを行うには、オープンソースの負荷テスト フレームワークである Locust を使用します。

  1. Cloud Shell で Locus の Docker イメージ ファイルをダウンロードします。
gsutil -m cp -r gs://spls/gsp769/locust-image .

提供された locust-image ディレクトリのファイルには、Locust 構成ファイルが含まれています。

  1. Locust の Docker イメージをビルドし、プロジェクトの Container Registry に保存します。
gcloud builds submit \ --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/locust-tasks:latest locust-image
  1. Docker イメージがプロジェクトの Container Registry にあることを確認します。
gcloud container images list

予想される出力:

出力: gcr.io/qwiklabs-gcp-01-343cd312530e 内のイメージのみリストされる

Locust は、負荷を生成するための単一のメインマシンと複数のワーカーマシンで構成されています。

  1. マニフェストをコピーして適用すると、メインのマシン用に単一 Pod の Deployment が作成され、ワーカーマシン用に 5 つのレプリカ Deployment が作成されます。
gsutil cp gs://spls/gsp769/locust_deploy_v2.yaml . sed 's/${GOOGLE_CLOUD_PROJECT}/'$GOOGLE_CLOUD_PROJECT'/g' locust_deploy_v2.yaml | kubectl apply -f -
  1. Locust の UI にアクセスするには、対応する LoadBalancer Service の外部 IP アドレスを取得します。
kubectl get service locust-main

外部 IP の値に <pending> が表示される場合は、1 分後に上記のコマンドを再実行し、有効な値が表示されるまで待ちます。

  1. 新しいブラウザ ウィンドウで [EXTERNAL_IP_ADDRESS]:8089 に移動して Locust のウェブページを開きます。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 アプリケーションの負荷テスト

Locust を使用すると、多くの同時ユーザーによってリクエストを発生させ、アプリケーションに負荷をかけることができます。ユーザー数を指定して一定のレートで生成させることで、トラフィックをシミュレートできます。

  1. この例では、標準的な負荷を表現するために、シミュレーションするユーザー数に「200」、生成レートに「20」を指定します。

  2. [Start swarming] をクリックします。

数秒後、ステータス RUNNING と表示され、200 のユーザーが生成されて 1 秒あたり 150 件のリクエスト(RPS)が発生していることがわかります。

  1. Cloud コンソールに切り替え、ナビゲーション メニュー(ナビゲーション メニュー)> [Kubernetes Engine] をクリックします。

  2. 左側のペインから [ワークロード] を選択します。

  3. 次に、デプロイした gb-frontend Pod をクリックします。

[Pod の詳細] ページが表示されます。ここでは、Pod に関する CPU やメモリの使用率のグラフを確認できます。[Used] の値と [Requested] の値を確認します。

Pod の詳細

注: グラフの下にリストされている指標値を表示するには、グラフ右上にあるその他アイコンをクリックし、プルダウンから [グラフの凡例を開く] を選択します。

現在の負荷テスト(1 秒あたり 150 件のリクエスト)の場合、CPU 使用率の値は通常 .04 から .06 程度となります。これは、1 つの Pod の CPU リクエストの 40~60% に相当します。一方で、メモリ使用率は約 80Mi にとどまり、要求されている 256Mi をはるかに下回っています。これが Pod ごとのキャパシティです。この情報は、クラスタ オートスケーラーを構成するときや、リソースのリクエストと制限を構成するとき、さらに、HorizontalPodAutoscaler または VerticalPodAutoscaler のどちらをどのように実装するかを選択するときに役立ちます。

ベースラインに加えて、突然のバーストや使用量の急激な増加が起こった後のアプリケーションの動作についても考慮する必要があります。

  1. Locust のブラウザ ウィンドウに戻り、ページの上部のステータスの下にある [Edit] をクリックします。

  2. 今度は、シミュレーションするユーザー数に「900」、生成率に「300」を入力します。

  3. [Start swarming] をクリックします。

Pod は 2~3 秒のうちに 700 件の追加リクエストを受信します。RPS の値が 150 に達し、ステータスが 900 ユーザーと表示されたら、[Pod の詳細] ページに戻り、グラフで変化を確認します。

Pod の詳細

メモリは変化していませんが、CPU は .07 近く(Pod の CPU リクエストの 70%)に達していることがわかります。このアプリが Deployment の場合はおそらく、メモリ リクエストの合計を減らし、CPU 使用率に基づいてトリガーするように水平オートスケーラーを構成するのが適切といえるでしょう。

タスク 3. readiness プローブと liveness プローブ

liveness プローブを設定する

Kubernetes Pod または Deployment 仕様で構成されている場合、liveness プローブは継続的に実行され、コンテナの再起動が必要かどうかを判断したり、再起動をトリガーしたりします。これは、デッドロックが発生した実行状態のアプリケーションを自動的に再起動するのに役立ちます。たとえば、Kubernetes が管理するロードバランサ(Service など)は、すべてのコンテナが liveness プローブに合格した場合にのみ、トラフィックを Pod バックエンドに送信します。

  1. liveness プローブを理解するために、liveness プローブが含まれる Pod のマニフェストを次のように生成します。これは、ファイル作成時にファイルに対して実行される cat コマンドに基づくものです。
cat << EOF > liveness-demo.yaml apiVersion: v1 kind: Pod metadata: labels: demo: liveness-probe name: liveness-demo-pod spec: containers: - name: liveness-demo-pod image: centos args: - /bin/sh - -c - touch /tmp/alive; sleep infinity livenessProbe: exec: command: - cat - /tmp/alive initialDelaySeconds: 5 periodSeconds: 10 EOF
  1. マニフェストをクラスタに適用して、Pod を作成します。
kubectl apply -f liveness-demo.yaml

initialDelaySeconds の値は、コンテナの起動後、最初のプローブが実行されるまでの時間を示します。periodSeconds の値はプローブが実行される頻度を示します。

注: Pod は、コンテナ内のアプリケーションが開始されているかどうかを示す startupProbe を含めるように構成することもできます。startupProbe が存在する場合、ステータスが「Success」になるまで他のプローブは実行されません。これは、起動時間が変動する可能性のあるアプリケーションで、liveness プローブによる中断を回避する方法として推奨されています。

この例では liveness プローブは基本的に、ファイル /tmp/alive がコンテナのファイル システムに存在するかどうかを確認しています。

  1. Pod のイベントを確認することで、Pod のコンテナのヘルス ステータスを検証できます。
kubectl describe pod liveness-demo-pod

出力内容の下部に [Events] セクションがあり、Pod の最新 5 件のイベントが表示されます。この時点では、Pod の作成と起動に関連するイベントのみが Pod のイベントに含まれます。

Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 19s default-scheduler Successfully assigned default/liveness-demo-pod to gke-load-test-default-pool-abd43157-rgg0 Normal Pulling 18s kubelet Pulling image "centos" Normal Pulled 18s kubelet Successfully pulled image "centos" Normal Created 18s kubelet Created container liveness-demo-pod Normal Started 18s kubelet Started container liveness-demo-pod

このイベントログには、liveness プローブの失敗と、その結果トリガーされた再起動が含まれます。

  1. liveness プローブで使用されているファイルを手動で削除します。
kubectl exec liveness-demo-pod -- rm /tmp/alive
  1. ファイルが削除されると、liveness プローブで使用されている cat コマンドによって、ゼロ以外の終了コードが返されます。

  2. もう一度、Pod のイベントを確認します。

kubectl describe pod liveness-demo-pod

liveness プローブが失敗するとイベントがログに追加され、開始された一連の手順が表示されます。ログは liveness プローブの失敗(Liveness probe failed: cat: /tmp/alive: No such file or directory)から始まり、コンテナの再起動(Started container)で終了します。

Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m21s default-scheduler Successfully assigned default/liveness-demo-pod to gke-load-test-default-pool-abd43157-rgg0 Warning Unhealthy 36s (x3 over 56s) kubelet Liveness probe failed: cat: /tmp/alive: No such file or directory Normal Killing 36s kubelet Container liveness-demo-pod failed liveness probe, will be restarted Normal Pulling 6s (x2 over 2m20s) kubelet Pulling image "centos" Normal Pulled 6s (x2 over 2m20s) kubelet Successfully pulled image "centos" Normal Created 6s (x2 over 2m20s) kubelet Created container liveness-demo-pod Normal Started 6s (x2 over 2m20s) kubelet Started container liveness-demo-pod 注: このラボの例では、指定されたコマンドの終了コードに依存するコマンド プローブが livenessProbe に使用されています。コマンド プローブの他にも、livenessProbe は HTTP レスポンスに依存する HTTP プローブや特定のポートで TCP 接続を確立できるかどうかに依存する TCP プローブとして構成できます。

readiness プローブを設定する

Pod が正常に起動し liveness プローブによって正常と判断されても、その時点ではトラフィックを受信できる準備が整っていない可能性もあります。これは、ロードバランサなどの Service のバックエンドとして機能する Deployment にはよくあることです。readiness プローブは、Pod とコンテナでトラフィックを受信できる準備が整っているかどうかを判断するために使用されます。

  1. readiness プローブを理解するために、マニフェストを作成し、ロードバランサとともにテスト ウェブサーバーとして機能する単一の Pod を作成します。
cat << EOF > readiness-demo.yaml apiVersion: v1 kind: Pod metadata: labels: demo: readiness-probe name: readiness-demo-pod spec: containers: - name: readiness-demo-pod image: nginx ports: - containerPort: 80 readinessProbe: exec: command: - cat - /tmp/healthz initialDelaySeconds: 5 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: readiness-demo-svc labels: demo: readiness-probe spec: type: LoadBalancer ports: - port: 80 targetPort: 80 protocol: TCP selector: demo: readiness-probe EOF
  1. マニフェストをクラスタに適用し、それを使用してロードバランサを作成します。
kubectl apply -f readiness-demo.yaml
  1. ロードバランサに割り当てられた外部 IP アドレスを取得します(上記のコマンド実行後、アドレスが割り当てられるまでに 1 分ほどかかる場合があります)。
kubectl get service readiness-demo-svc
  1. ブラウザ ウィンドウに IP アドレスを入力すると、サイトにアクセスできないことを示すエラー メッセージが表示されます。

  2. Pod のイベントを確認します。

kubectl describe pod readiness-demo-pod

出力は次のようになり、readiness プローブが失敗したことが示されます。

Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m24s default-scheduler Successfully assigned default/readiness-demo-pod to gke-load-test-default-pool-abd43157-rgg0 Normal Pulling 2m23s kubelet Pulling image "nginx" Normal Pulled 2m23s kubelet Successfully pulled image "nginx" Normal Created 2m23s kubelet Created container readiness-demo-pod Normal Started 2m23s kubelet Started container readiness-demo-pod Warning Unhealthy 35s (x21 over 2m15s) kubelet Readiness probe failed: cat: /tmp/healthz: No such file or directory

liveness プローブと異なり、readiness プローブでは結果が正常でなくても Pod の再起動はトリガーされません。

  1. 次のコマンドを使用して、readiness プローブが存在を確認しようとしているファイルを生成します。
kubectl exec readiness-demo-pod -- touch /tmp/healthz

Pod の説明の Conditions セクションで、Ready の値に True が表示されます。

kubectl describe pod readiness-demo-pod | grep ^Conditions -A 5

出力:

Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True
  1. 次に、readiness-demo-svc 外部 IP が設定されているブラウザタブを更新します。「Welcome to nginx!」というメッセージが表示されるはずです。

アプリケーション コンテナに有意な readiness プローブを設定すると、Pod がトラフィックを受信できる準備が整っているときにのみ、トラフィックを受信するようになります。有意な readiness プローブの例としては、アプリケーションが依存するキャッシュが起動時に読み込まれているかどうかを確認することが挙げられます。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 readiness プローブと liveness プローブ

タスク 4. Pod Disruption Budget

GKE アプリケーションの信頼性と稼働時間の確保は、Pod Disruption Budget(PDB)の活用に一部依存しています。PodDisruptionBudget は Kubernetes リソースであり、自発的な中断により同時に削除できる、複製済みアプリケーションの Pod の数を制限します。

自発的な中断には、Deployment の削除、Deployment の Pod テンプレートの更新とローリング アップデートの実行、アプリケーションの Pod が存在するノードのドレイン、別のノードへの Pod の移動などの管理アクションが含まれます。

まず、アプリケーションを Deployment としてデプロイする必要があります。

  1. 単一の Pod からなるアプリケーションを削除します。
kubectl delete pod gb-frontend
  1. 次に、5 つのレプリカの Deployment としてアプリケーションを作成するマニフェストを生成します。
cat << EOF > gb_frontend_deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: gb-frontend labels: run: gb-frontend spec: replicas: 5 selector: matchLabels: run: gb-frontend template: metadata: labels: run: gb-frontend spec: containers: - name: gb-frontend image: gcr.io/google-samples/gb-frontend-amd64:v5 resources: requests: cpu: 100m memory: 128Mi ports: - containerPort: 80 protocol: TCP EOF
  1. この Deployment をクラスタに適用します。
kubectl apply -f gb_frontend_deployment.yaml

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 Pod Disruption Budget を作成する

PDB を作成する前に、クラスタのノードをドレインし、PDB を設定せずにアプリケーションの動作を確認します。

  1. default-pool のノードの出力をループして、kubectl drain コマンドを個々のノードで実行することで、ノードをドレインします。
for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do kubectl drain --force --ignore-daemonsets --grace-period=10 "$node"; done

上記のコマンドは、指定されたノードから Pod を削除し、ノードを閉鎖して、新しい Pod がそのノードに作成されないようにします。利用可能なリソースがあれば、Pod は別のノードに再デプロイされます。

  1. ノードがドレインされたら、gb-frontend Deployment のレプリカ数を確認します。
kubectl describe deployment gb-frontend | grep ^Replicas

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

Replicas: 5 desired | 5 updated | 5 total | 0 available | 5 unavailable

上記の出力で示されているように、ノードのドレイン後は、Deployment で利用可能なレプリカの数は 0 になる可能性があります。利用可能な Pod がない場合、アプリケーションは事実上ダウンします。次は Pod Disruption Budget をアプリケーションに設定して、ノードのドレインを試してみてください。

  1. まず、ドレインされたノードの閉鎖を解除して元に戻します。次のコマンドを使用すると、このノードで Pod を再度スケジュールできます。
for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do kubectl uncordon "$node"; done
  1. もう一度、Deployment のステータスを確認します。
kubectl describe deployment gb-frontend | grep ^Replicas

出力は次のようになり、5 つのレプリカすべてが利用可能になります。

Replicas: 5 desired | 5 updated | 5 total | 5 available | 0 unavailable
  1. 利用可能な Pod の最小数を 4 と宣言する Pod Disruption Budget を作成します。
kubectl create poddisruptionbudget gb-pdb --selector run=gb-frontend --min-available 4
  1. もう一度、クラスタのノードの 1 つをドレインし、その出力を確認します。
for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do kubectl drain --timeout=30s --ignore-daemonsets --grace-period=10 "$node"; done

アプリケーションの Pod のうち 1 つが正常に削除されると、次のようなループ処理が行われます。

evicting pod default/gb-frontend-597d4d746c-fxsdg evicting pod default/gb-frontend-597d4d746c-tcrf2 evicting pod default/gb-frontend-597d4d746c-kwvmv evicting pod default/gb-frontend-597d4d746c-6jdx5 error when evicting pod "gb-frontend-597d4d746c-fxsdg" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget. error when evicting pod "gb-frontend-597d4d746c-tcrf2" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget. error when evicting pod "gb-frontend-597d4d746c-6jdx5" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget. error when evicting pod "gb-frontend-597d4d746c-kwvmv" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
  1. コマンドを停止するには、CTRL+C キーを押します。

  2. もう一度、Deployment のステータスを確認します。

kubectl describe deployment gb-frontend | grep ^Replicas

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

Replicas: 5 desired | 5 updated | 5 total | 4 available | 1 unavailable

Kubernetes が 5 番目の Pod を別のノードでデプロイして、次の Pod を削除できるようになるまで、残りの Pod は PDB に従って引き続き利用できます。この例では、Pod Disruption Budget は min-available を示すように構成されていますが、max-unavailable を定義するように構成することもできます。どちらの値も、Pod 数を表す整数、または合計 Pod 数のパーセンテージで示すことができます。

お疲れさまでした

より効率的なロード バランシングとルーティングを利用するために、Ingress によるコンテナ ネイティブのロードバランサを作成する方法を学習しました。GKE アプリケーションでシンプルな負荷テストを実行し、ベースラインとなる CPU やメモリの使用率に加えて、トラフィックの急激な増加にアプリケーションがどのように反応するかについても確認しました。さらに、アプリケーションの可用性を確保するために、liveness プローブ、readiness プローブ、Pod Disruption Budget を構成しました。これらのツールと手法を組み合わせて、無駄なネットワーク トラフィックを最小限に抑え、正常に動作しているアプリケーションの有意な指標を定義し、アプリケーションの可用性を高めることにより、GKE におけるアプリケーションの総合的な実行効率が改善されます。

次のステップと詳細情報

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

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

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

マニュアルの最終更新日: 2024 年 3 月 12 日

ラボの最終テスト日: 2024 年 3 月 12 日

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

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

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

ありがとうございます。

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