GSP769
概要
使用するリソースに対してのみ請求が発生する課金モデルは、Google Cloud の多くの利点の一つです。この点を考慮すると、アプリとインフラストラクチャに対して適切な量のリソースを割り当てるだけでなく、そのリソースを最も効率的な方法で使用することが非常に重要です。GKE には、さまざまなリソースやサービスの使用量を減らしながら、アプリケーションの可用性も向上できるツールや手法が多くあります。
このラボでは、リソースの効率性やワークロードの可用性の向上に役立つ、いくつかのコンセプトについて説明します。クラスタのワークロードを理解して微調整することで、必要なリソースのみを使用して、クラスタのコストを最適化できます。
目標
このラボでは、次の方法について学びます。
Ingress によるコンテナ ネイティブのロードバランサを作成する
アプリケーションの負荷テストを行う
liveness と readiness のプローブを構成する
Pod Disruption Budget を作成する
設定と要件
[ラボを開始] ボタンをクリックする前に
こちらの説明をお読みください。ラボには時間制限があり、一時停止することはできません。タイマーは、Google Cloud のリソースを利用できる時間を示しており、[ラボを開始 ] をクリックするとスタートします。
このハンズオンラボでは、シミュレーションやデモ環境ではなく実際のクラウド環境を使って、ラボのアクティビティを行います。そのため、ラボの受講中に Google Cloud にログインおよびアクセスするための、新しい一時的な認証情報が提供されます。
このラボを完了するためには、下記が必要です。
標準的なインターネット ブラウザ(Chrome を推奨)
注: このラボの実行には、シークレット モード(推奨)またはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウント間の競合を防ぎ、個人アカウントに追加料金が発生しないようにすることができます。
ラボを完了するための時間(開始後は一時停止できません)
注: このラボでは、受講者アカウントのみを使用してください。別の Google Cloud アカウントを使用すると、そのアカウントに料金が発生する可能性があります。
ラボを開始して Google Cloud コンソールにログインする方法
[ラボを開始 ] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるダイアログでお支払い方法を選択してください。
左側の [ラボの詳細] ペインには、以下が表示されます。
[Google Cloud コンソールを開く] ボタン
残り時間
このラボで使用する必要がある一時的な認証情報
このラボを行うために必要なその他の情報(ある場合)
[Google Cloud コンソールを開く ] をクリックします(Chrome ブラウザを使用している場合は、右クリックして [シークレット ウィンドウで開く ] を選択します)。
ラボでリソースがスピンアップし、別のタブで [ログイン] ページが表示されます。
ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。
注: [アカウントの選択 ] ダイアログが表示されたら、[別のアカウントを使用 ] をクリックします。
必要に応じて、下のユーザー名 をコピーして、[ログイン ] ダイアログに貼り付けます。
{{{user_0.username | "Username"}}}
[ラボの詳細] ペインでもユーザー名を確認できます。
[次へ ] をクリックします。
以下のパスワード をコピーして、[ようこそ ] ダイアログに貼り付けます。
{{{user_0.password | "Password"}}}
[ラボの詳細] ペインでもパスワードを確認できます。
[次へ ] をクリックします。
重要: ラボで提供された認証情報を使用する必要があります。Google Cloud アカウントの認証情報は使用しないでください。
注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
その後次のように進みます。
利用規約に同意してください。
一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
無料トライアルには登録しないでください。
その後、このタブで Google Cloud コンソールが開きます。
注: Google Cloud のプロダクトやサービスにアクセスするには、ナビゲーション メニュー をクリックするか、[検索 ] フィールドにサービス名またはプロダクト名を入力します。
Cloud Shell をアクティブにする
Cloud Shell は、開発ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Cloud Shell を使用すると、コマンドラインで Google Cloud リソースにアクセスできます。
Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする 」アイコン をクリックします。
ウィンドウで次の操作を行います。
Cloud Shell 情報ウィンドウで操作を進めます。
Cloud Shell が認証情報を使用して Google Cloud API を呼び出すことを承認します。
接続した時点で認証が完了しており、プロジェクトに各自の Project_ID 、 が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。
Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}
gcloud
は Google Cloud のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。
(省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
gcloud auth list
[承認 ] をクリックします。
出力:
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
(省略可)次のコマンドを使用すると、プロジェクト ID を一覧表示できます。
gcloud config list project
出力:
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
注: Google Cloud における gcloud
ドキュメントの全文については、gcloud CLI の概要ガイド をご覧ください。
ラボ環境のプロビジョニング
デフォルトのゾーンを「 」に設定します。
gcloud config set compute/zone {{{project_0.default_zone|ZONE}}}
[承認 ] をクリックします。
3 つのノードを含むクラスタを作成します。
gcloud container clusters create test-cluster --num-nodes=3 --enable-ip-alias
--enable-ip-alias
フラグは、Ingress によるコンテナ ネイティブのロード バランシングに必要な Pod のエイリアス IP を使用できるようにするために含まれています。
このラボでは、シンプルな HTTP ウェブアプリを、最初は単一の Pod としてデプロイします。
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
新しく作成したマニフェストをクラスタに適用します。
kubectl apply -f gb_frontend_pod.yaml
注: このタスクのスコアが表示されるまで、1~2 分
かかる場合があります。
[進行状況を確認 ] をクリックして、目標に沿って進行していることを確認します。
ラボ環境のプロビジョニング
タスク 1. Ingress によるコンテナ ネイティブのロード バランシング
コンテナ ネイティブのロード バランシングにより、ロードバランサは Kubernetes Pod を直接ターゲットにすることも、トラフィックを Pod に均等に分配することもできます。
コンテナ ネイティブのロード バランシングを使用しない場合、ロードバランサのトラフィックはノード インスタンス グループに送られ、iptables
ルールを介して Pod にルーティングされます。しかし、これらの Pod は同じノードにあるとは限りません。
コンテナ ネイティブのロード バランシングにより、Pod はロード バランシングのコア オブジェクトになることができるため、ネットワーク ホップ数を削減できる可能性があります。
コンテナ ネイティブのロード バランシングを使用すると、より効率的なルーティングだけでなく、ネットワーク使用率の大幅な減少、パフォーマンスの向上、Pod 間での均等なトラフィック分配、アプリケーション レベルのヘルスチェックが実現します。
コンテナ ネイティブなロード バランシングを利用するには、VPC ネイティブの設定をクラスタで有効にする必要があります。これは、クラスタを作成して --enable-ip-alias
フラグを含めたときにも説明しました。
次のマニフェストでは、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 が作成されたときにアプリケーションでコンテナ ネイティブのロード バランシングが有効になります。
変更をクラスタに適用します。
kubectl apply -f gb_frontend_cluster_ip.yaml
次に、アプリケーションで 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
変更をクラスタに適用します。
kubectl apply -f gb_frontend_ingress.yaml
Ingress が作成されると、クラスタが実行される各ゾーンにネットワーク エンドポイント グループ(NEG)とともに HTTP(S) ロードバランサが作成されます。数分経過すると、Ingress に外部 IP が割り当てられます。
作成されたロードバランサには、プロジェクトで実行されるバックエンド サービスが含まれます。このバックエンド サービスは、Cloud Load Balancing によるトラフィックの分散方法を定義します。また、このバックエンド サービスにはヘルス ステータスが関連付けられています。
バックエンド サービスのヘルス ステータスを確認するには、最初に名前を取得します。
BACKEND_SERVICE=$(gcloud compute backend-services list | grep NAME | cut -d ' ' -f2)
サービスのヘルス ステータスを取得します。
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 経由でアプリケーションにアクセスできます。
次のコマンドで取得します。
kubectl get ingress gb-frontend-ingress
ブラウザ ウィンドウで外部 IP を入力すると、アプリケーションが読み込まれます。
[進行状況を確認 ] をクリックして、目標に沿って進んでいることを確認します。
Ingress によるコンテナ ネイティブのロード バランシング
タスク 2. アプリケーションの負荷テスト
アプリケーションのキャパシティを把握することは、アプリケーションの Pod に対するリソースのリクエストと制限を選択するときや、最適な自動スケーリング戦略を決定するときに重要なステップです。
ラボの開始時に、アプリケーションを単一の Pod としてデプロイしました。自動スケーリングが構成されていない単一の Pod で実行されているアプリケーションの負荷テストを行うと、そのアプリケーションが処理できる同時リクエストの数、必要な CPU とメモリの量、高い負荷が発生した場合の影響を確認できます。
Pod の負荷テストを行うには、オープンソースの負荷テスト フレームワークである Locust を使用します。
Cloud Shell で Locus の Docker イメージ ファイルをダウンロードします。
gsutil -m cp -r gs://spls/gsp769/locust-image .
提供された locust-image
ディレクトリのファイルには、Locust 構成ファイルが含まれています。
Locust の Docker イメージをビルドし、プロジェクトの Container Registry に保存します。
gcloud builds submit \
--tag gcr.io/${GOOGLE_CLOUD_PROJECT}/locust-tasks:latest locust-image
Docker イメージがプロジェクトの Container Registry にあることを確認します。
gcloud container images list
予想される出力:
Locust は、負荷を生成するための単一のメインマシンと複数のワーカーマシンで構成されています。
マニフェストをコピーして適用すると、メインのマシン用に単一 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 -
Locust の UI にアクセスするには、対応する LoadBalancer Service の外部 IP アドレスを取得します。
kubectl get service locust-main
外部 IP の値に <pending> が表示される場合は、1 分後に上記のコマンドを再実行し、有効な値が表示されるまで待ちます。
新しいブラウザ ウィンドウで [EXTERNAL_IP_ADDRESS]:8089
に移動して Locust のウェブページを開きます。
[進行状況を確認 ] をクリックして、目標に沿って進んでいることを確認します。
アプリケーションの負荷テスト
Locust を使用すると、多くの同時ユーザーによってリクエストを発生させ、アプリケーションに負荷をかけることができます。 ユーザー数を指定して一定のレートで生成させることで、トラフィックをシミュレートできます。
この例では、標準的な負荷を表現するために、シミュレーションするユーザー数に「200 」、生成レートに「20 」を指定します。
[Start swarming ] をクリックします。
数秒後、ステータス に RUNNING と表示され、200 のユーザーが生成されて 1 秒あたり 150 件のリクエスト(RPS)が発生していることがわかります。
Cloud コンソールに切り替え、ナビゲーション メニュー( )> [Kubernetes Engine] をクリックします。
左側のペインから [ワークロード ] を選択します。
次に、デプロイした gb-frontend Pod をクリックします。
[Pod の詳細] ページが表示されます。ここでは、Pod に関する CPU やメモリの使用率のグラフを確認できます。[Used ] の値と [Requested ] の値を確認します。
注: グラフの下にリストされている指標値を表示するには、グラフ右上にあるその他アイコンをクリックし、プルダウンから [グラフの凡例を開く ] を選択します。
現在の負荷テスト(1 秒あたり 150 件のリクエスト)の場合、CPU 使用率の値は通常 .04 から .06 程度となります。これは、1 つの Pod の CPU リクエストの 40~60% に相当します。一方で、メモリ使用率は約 80Mi にとどまり、要求されている 256Mi をはるかに下回っています。これが Pod ごとのキャパシティ です。この情報は、クラスタ オートスケーラーを構成するときや、リソースのリクエストと制限を構成するとき、さらに、HorizontalPodAutoscaler または VerticalPodAutoscaler のどちらをどのように実装するかを選択するときに役立ちます。
ベースラインに加えて、突然のバーストや使用量の急激な増加が起こった後のアプリケーションの動作についても考慮する必要があります。
Locust のブラウザ ウィンドウに戻り、ページの上部のステータスの下にある [Edit ] をクリックします。
今度は、シミュレーションするユーザー数に「900 」、生成率に「300 」を入力します。
[Start swarming ] をクリックします。
Pod は 2~3 秒のうちに 700 件の追加リクエストを受信します。RPS の値が 150 に達し、ステータスが 900 ユーザーと表示されたら、[Pod の詳細 ] ページに戻り、グラフで変化を確認します。
メモリは変化していませんが、CPU は .07 近く(Pod の CPU リクエストの 70%)に達していることがわかります。このアプリが Deployment の場合はおそらく、メモリ リクエストの合計を減らし、CPU 使用率に基づいてトリガーするように水平オートスケーラーを構成するのが適切といえるでしょう。
タスク 3. readiness プローブと liveness プローブ
liveness プローブを設定する
Kubernetes Pod または Deployment 仕様で構成されている場合、liveness プローブは継続的に実行され、コンテナの再起動が必要かどうかを判断したり、再起動をトリガーしたりします。これは、デッドロックが発生した実行状態のアプリケーションを自動的に再起動するのに役立ちます。たとえば、Kubernetes が管理するロードバランサ(Service など)は、すべてのコンテナが liveness プローブに合格した場合にのみ、トラフィックを Pod バックエンドに送信します。
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
マニフェストをクラスタに適用して、Pod を作成します。
kubectl apply -f liveness-demo.yaml
initialDelaySeconds
の値は、コンテナの起動後、最初のプローブが実行されるまでの時間を示します。periodSeconds の値はプローブが実行される頻度を示します。
注: Pod は、コンテナ内のアプリケーションが開始されているかどうかを示す startupProbe
を含めるように構成することもできます。startupProbe
が存在する場合、ステータスが「Success
」になるまで他のプローブは実行されません。これは、起動時間が変動する可能性のあるアプリケーションで、liveness プローブによる中断を回避する方法として推奨されています。
この例では liveness プローブは基本的に、ファイル /tmp/alive がコンテナのファイル システムに存在するかどうかを確認しています。
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 プローブの失敗と、その結果トリガーされた再起動が含まれます。
liveness プローブで使用されているファイルを手動で削除します。
kubectl exec liveness-demo-pod -- rm /tmp/alive
ファイルが削除されると、liveness プローブで使用されている cat
コマンドによって、ゼロ以外の終了コードが返されます。
もう一度、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 とコンテナでトラフィックを受信できる準備が整っているかどうかを判断するために使用されます。
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
マニフェストをクラスタに適用し、それを使用してロードバランサを作成します。
kubectl apply -f readiness-demo.yaml
ロードバランサに割り当てられた外部 IP アドレスを取得します(上記のコマンド実行後、アドレスが割り当てられるまでに 1 分ほどかかる場合があります)。
kubectl get service readiness-demo-svc
ブラウザ ウィンドウに IP アドレスを入力すると、サイトにアクセスできないことを示すエラー メッセージが表示されます。
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 の再起動はトリガーされません。
次のコマンドを使用して、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
次に、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 としてデプロイする必要があります。
単一の Pod からなるアプリケーションを削除します。
kubectl delete pod gb-frontend
次に、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
この Deployment をクラスタに適用します。
kubectl apply -f gb_frontend_deployment.yaml
[進行状況を確認 ] をクリックして、目標に沿って進んでいることを確認します。
Pod Disruption Budget を作成する
PDB を作成する前に、クラスタのノードをドレインし、PDB を設定せずにアプリケーションの動作を確認します。
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 は別のノードに再デプロイされます。
ノードがドレインされたら、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 をアプリケーションに設定して、ノードのドレインを試してみてください。
まず、ドレインされたノードの閉鎖を解除して元に戻します。次のコマンドを使用すると、このノードで Pod を再度スケジュールできます。
for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
kubectl uncordon "$node";
done
もう一度、Deployment のステータスを確認します。
kubectl describe deployment gb-frontend | grep ^Replicas
出力は次のようになり、5 つのレプリカすべてが利用可能になります。
Replicas: 5 desired | 5 updated | 5 total | 5 available | 0 unavailable
利用可能な Pod の最小数を 4 と宣言する Pod Disruption Budget を作成します。
kubectl create poddisruptionbudget gb-pdb --selector run=gb-frontend --min-available 4
もう一度、クラスタのノードの 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.
コマンドを停止するには、CTRL+C キーを押します。
もう一度、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 2025 Google LLC. All rights reserved. Google および Google のロゴは Google LLC の商標です。その他すべての企業名および商品名はそれぞれ各社の商標または登録商標です。