このチュートリアルでは、ステートフル アプリケーションを作成し、アプリケーションを実行する Google Kubernetes Engine(GKE)クラスタをアップグレードする際のおすすめの方法を説明します。このチュートリアルでは、ステートフル アプリケーションをデプロイする例として Redis を使用しますが、GKE にデプロイされた他のタイプのステートフル アプリケーションにも同じコンセプトを適用できます。
目標
このチュートリアルでは、次の手順について説明します。
- リリース チャンネルに登録される GKE クラスタを作成します。
- GKE に Redis クラスタを作成します。
- Redis クライアント アプリケーションを GKE にデプロイします。
- ノードプールのアップグレードに関する次のベスト プラクティスを実施します。
- Pod Disruption Budget(PDB)を設定します。
- メンテナンスの時間枠と除外を設定します。
- ノードのアップグレード戦略をサージ アップグレードまたは Blue/Green アップグレードに設定します。
- アプリケーションをテストします。
- クラスタをアップグレードします。
- ワークロードの中断をテストします。
次の図は、このチュートリアルのクラスタ アーキテクチャの概要を示しています。
費用
このドキュメントでは、課金対象である次の Google Cloudコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
プロジェクトを設定する
- Google Cloud アカウントにログインします。 Google Cloudを初めて使用する場合は、 アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
Roles required to create a project
To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles. -
Verify that billing is enabled for your Google Cloud project.
Enable the GKE API.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
Roles required to create a project
To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles. -
Verify that billing is enabled for your Google Cloud project.
Enable the GKE API.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.
Google Cloud CLI のデフォルト値を設定する
Google Cloud コンソールで、Cloud Shell インスタンスを起動します。
Cloud Shell を開くこのサンプルアプリのソースコードをダウンロードします。
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/quickstarts/hello-app-redis/manifestsデフォルトの環境変数を設定します。
gcloud config set project PROJECT-ID gcloud config set compute/zone COMPUTE-ZONE次の値を置き換えます。
- PROJECT_ID: Google Cloud のプロジェクト ID。
- COMPUTE_ZONE: Compute Engine ゾーン。
リリース チャンネルに登録される GKE クラスタを作成する
GKE クラスタを作成するには、次の手順を行います。
3 つのノードを持つ
redis-testという名前のクラスタを作成します。gcloud container clusters create redis-test \ --location CONTROL_PLANE_LOCATION \ --num-nodes=3 \ --release-channel regularCONTROL_PLANE_LOCATION は、クラスタのコントロール プレーンの Compute Engine のロケーションに置き換えます。リージョン クラスタの場合はリージョン、ゾーンクラスタの場合はゾーンを指定します。
クラスタが作成されると、次のような出力が表示されます。
NAME: redis-test LOCATION: us-central1-c MASTER_VERSION: 1.22.10-gke.600 MASTER_IP: 34.69.67.7 MACHINE_TYPE: e2-medium NODE_VERSION: 1.22.10-gke.600 NUM_NODES: 3 STATUS: RUNNINGクラスタと通信を行うように
kubectlを構成します。gcloud container clusters get-credentials redis-test
GKE に Redis クラスタを作成する
このセクションでは、ConfigMap、StatefulSet、ヘッドレス サービスをデプロイし、以前に作成した GKE クラスタの上に Redis クラスタを追加します。
Redis クラスタを作成するには、次の手順を完了します。
Redis 構成が格納されている ConfigMap ファイル(
redis-configmap.yaml)を参照します。以下のスニペットは、readinessProbe と livenessProbe のスクリプトを示しています。readiness.shスクリプトとliveness.shスクリプトは、redis-cli ping を使用して、Redis サーバーが実行中かどうかを確認します。PONGが返された場合、Redis サーバーは稼働しています。これらのスクリプトはredis-cluster.yamlで使用されます。この ConfigMap の Redis パラメータの詳細については、Redis クラスタ チュートリアルで Redis クラスタ構成パラメータのセクションをご覧ください。
ConfigMap をデプロイします。
kubectl apply -f redis-configmap.yamlreadinessProbe と livenessProbe の使用方法を示す StatefulSet(
redis-cluster.yaml)スニペットをご覧ください。Kubernetes でプローブを構成する方法については、プローブを構成するをご覧ください。
ノードプールをアップグレードする場合は、readinessProbe と livenessProbe を使用することを強くおすすめします。これにより、アップグレード中に Pod の準備ができます。
StatefulSet をデプロイします。
kubectl apply -f redis-cluster.yamlredis-service.yamlという名前のヘッドレス Service は、Redis ノードの接続用です。ヘッドレス Service を作成するために、clusterIPフィールドはNoneに設定されています。サービスをデプロイします。
kubectl apply -f redis-service.yaml約 2 分待ってから次のコマンドを使用して、すべての Pod が実行されていることを確認します。
kubectl get pods出力は次の例のようになります。
NAME READY STATUS RESTARTS AGE redis-0 1/1 Running 0 2m29s redis-1 1/1 Running 0 2m8s redis-2 1/1 Running 0 107s redis-3 1/1 Running 0 85s redis-4 1/1 Running 0 54s redis-5 1/1 Running 0 23s次のコマンドを実行して、永続ボリュームが作成されたことを確認します。
kubectl get pv出力は次の例のようになります。
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-HASH 1Gi RWO Delete Bound default/data-redis-5 standard 75s pvc-HASH 1Gi RWO Delete Bound default/data-redis-1 standard 2m59s pvc-HASH 1Gi RWO Delete Bound default/data-redis-3 standard 2m16s pvc-HASH 1Gi RWO Delete Bound default/data-redis-2 standard 2m38s pvc-HASH 1Gi RWO Delete Bound default/data-redis-0 standard 3m20s pvc-HASH 1Gi RWO Delete Bound default/data-redis-4 standard 104sこの出力で、HASH は各永続ボリューム名に関連付けられたハッシュを表します。
Redis クラスタにロールを割り当てる
構成が完了したら、Redis クラスタにロールを割り当てます。
次のスクリプトは、Pod の IP アドレスを取得し、各 Pod IP アドレスをコマンドに渡してリーダーとフォロワーのロールを割り当てます。
Redis クラスタにロールを割り当てるには、次の手順を完了します。
スクリプトを実行します。
chmod +x ./roles.sh ./roles.shプロンプトが表示されたら、「
yes」と入力します。Redis ノードにログインしてロールを確認します。たとえば、
redis-0にリーダーのロールが割り当てられていることを確認するには、次のコマンドを実行します。kubectl exec -it redis-0 -- redis-cli role出力は次の例のようになります。
1) "master" 2) (integer) 574 3) 1) 1) "10.28.2.3" 2) "6379" 3) "574"
Redis クライアント アプリケーションをデプロイする
作成した GKE クラスタにアプリケーションをデプロイするには、アプリケーション用の Deployment を定義します。app-deployment.yaml という名前のファイルには、アプリケーションのデプロイメント定義が含まれています。
この Deployment で使用される Probe と Pod のアフィニティ ルールの詳細については、GKE のベスト プラクティス: 高可用性クラスタの設計と構築をご覧ください。
Deployment を作成するには、次の手順を行います。
Deployment を適用します。
kubectl apply -f app-deployment.yamlロードバランサ経由でアプリケーションを公開します。
kubectl expose deployment hello-web \ --type=LoadBalancer \ --port 80 \ --target-port 8080約 1 分待ってから次のコマンドを実行して、アプリケーションの外部 IP アドレスを取得します。
kubectl get service出力から、
hello-web'sEXTERNAL-IP列に表示されている値をコピーします。NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-web LoadBalancer 10.13.10.55 EXTERNAL_IP 80:30703/TCP 166mウェブブラウザに EXTERNAL_IP を貼り付けて、アプリケーションが機能していることを確認します。出力は次の例のようになります。
I have been hit [1] times since deployment!アクセス数をメモしておきます。これは、アプリケーションの中断テストで必要になります。
コピーした EXTERNAL_IP の変数を設定します。この値は、次のセクションでアプリケーションのテスト スクリプトを作成するときに使用します。
export IP=EXTERNAL_IP
ノードプールのアップグレードに関するベスト プラクティスを構成する
ステートフル アプリケーションに対して以下のベスト プラクティスを実施し、ノードプールのアップグレード中の可用性を最適化します。
Pod Disruption Budget(PDB)を設定する
Pod Disruption Budget を作成して、自発的な中断中に同時に停止される複製 Pod の数を制限します。これは、アップグレード中に使用可能なレプリカの数のクォーラムが必要なステートフル アプリケーションに役立ちます。
PDB の定義では:
appは、この PDB を適用するアプリケーションを指定します。minAvailableは、中断時に使用できる Pod の最小数を設定します。値または割合(例: 30%)を指定できます。maxUnavailableは、中断中に使用できない Pod の最大数を設定します。値または割合を指定できます。
PDB を設定するには、次の手順を完了します。
PDB をデプロイします。
kubectl apply -f pdb-minavailable.yamlPDB が作成されていることを確認します。
kubectl get pdb
メンテナンスの時間枠と除外を設定する
ノードの自動アップグレードによってアップグレード プロセスが効率化され、ユーザーに代わってコントロール プレーンがアップグレードされるときに、クラスタ内のノードが最新の状態に保たれます。この機能はデフォルトで有効になっています。詳細は、ノードの自動アップグレードをご覧ください。
メンテナンスの時間枠とメンテナンスの除外を使用すると、時間枠を設定して、GKE クラスタでのメンテナンスの実行のタイミングを制御できます。
2022 年 8 月 19 日の午前 2 時(UTC)に開始し、4 時間後に終了するようにメンテナンスの時間枠を設定します。このメンテナンスの時間枠は毎日実行されます。この期間中は、自動メンテナンスが許可されます。
gcloud container clusters update redis-test \ --maintenance-window-start 2022-08-19T02:00:00Z \ --maintenance-window-duration 4H \ --maintenance-window-recurrence FREQ=DAILY除外時間枠を設定して、年末年始にメンテナンスが行われないようにします。このメンテナンスの除外は、
no_upgradesスコープを使用します。この期間中は、あらゆる種類の自動メンテナンスが禁止されます。詳細については、除外するメンテナンスの範囲をご覧ください。gcloud container clusters update redis-test \ --add-maintenance-exclusion-name new-year \ --add-maintenance-exclusion-start 2022-12-26T00:00:00Z \ --add-maintenance-exclusion-end 2023-01-02T02:00:00Z \ --add-maintenance-exclusion-scope no_upgradesメンテナンスの時間枠と除外が適用されていることを確認します。
maintenancePolicy:の下を確認します。gcloud container clusters describe redis-test
詳細については、メンテナンスの時間枠と除外を構成するをご覧ください。
ノードのアップグレード戦略を構成する
GKE クラスタ内のノードプールには、Blue/Green アップグレードとサージ アップグレードという 2 つのノード アップグレード戦略があります。詳細については、ノードのアップグレード戦略をご覧ください。
Blue/Green アップグレード
ワークロードの中断を許容できず、リソース使用量の増加によって一時的な費用の増加が許容される場合は、Blue/Green アップグレードを選択します。
次のコマンドを実行して、現在のノードプールを Blue/Green アップグレード戦略に変更します。
gcloud container node-pools update default-pool \
--cluster=redis-test \
--enable-blue-green-upgrade \
--location CONTROL_PLANE_LOCATION \
--node-pool-soak-duration=120s
このチュートリアルの目的上、ノードプール ソーク期間は、ノードプールのソークフェーズで時間を節約するために 2 分間に設定しています。このフェーズは、Blue プールノードがドレインされた後、ワークロードの正常性を確認するために使用されます。ノードプール ソーク期間を 1 時間(3,600 秒)またはアプリケーションに最適な期間に設定することをおすすめします。
Pod の割り当ての管理の詳細については、Pod を特定のノードプールにデプロイすると特定のノードプールに Service をデプロイするをご覧ください。
Blue/Green アップグレードの構成の詳細については、Blue/Green アップグレードを構成するをご覧ください。
サージ アップグレード
コストの最適化が重要であり、ワークロードが 60 分未満で正常なシャットダウンを許容できる場合は、サージ アップグレードを選択します(GKE では PDB が最大 60 分間適用されます)。
次のコマンドを実行して、現在のノードプールをサージ アップグレード戦略に変更します。
gcloud container node-pools update default-pool \
--max-surge-upgrade=1 \
--max-unavailable-upgrade=0 \
--cluster=redis-test
この構成(maxSurge=1 と maxUnavailable=0)では、アップグレード中にノードプールにサージノードを 1 つだけ追加できます。このため、一度にアップグレードできるノードは 1 つだけです。この設定では、アップグレード中の Pod の再起動が速くなります。
サージ アップグレードの構成の詳細については、サージ アップグレードを構成するをご覧ください。
現在のノードプールの構成を確認します。
gcloud container node-pools describe default-pool \
--cluster redis-test \
--location CONTROL_PLANE_LOCATION
ノードプールの表示の詳細については、クラスタ内のノードプールを表示するをご覧ください。
アプリケーションをテストする
このセクションでは、アプリケーションにリクエストを送信するスクリプトと、リクエストの成功率を測定する 2 つのスクリプトを使用します。これらのスクリプトを使用して、クラスタをアップグレードしたときに何が起こるかを測定します。
スクリプトを作成するには:
スクリプトが含まれているディレクトリに移動します。
cd cd kubernetes-engine-samples/quickstarts/hello-app-redis/scriptsgenerate_load.shという名前のスクリプトを参照します。このスクリプトは、秒間クエリ数(QPS)リクエストをアプリケーションに送信します。このスクリプトは、現在のディレクトリのoutputという名前のファイルに HTTP レスポンス コードを保存します。outputの値は、次の手順で作成するスクリプトで使用します。generate_load.shによって生成される出力に基づいて成功率を計算するprint_error_rate.shという名前のスクリプトを参照してください。スクリプトの実行権限を付与します。
chmod u+x generate_load.sh print_error_rate.shQPS の数を格納する変数を設定します。この値は、EXTERNAL_IP に設定した変数と同様に
generate_load.shスクリプトで使用されます。値に 40 を設定することをおすすめします。export QPS=40generate_load.shスクリプトを実行して QPS の送信を開始します。./generate_load.sh $IP $QPS 2>&1generate_load.shスクリプトを実行したまま、新しいターミナルを開きます。新しいターミナルで、print_error_rate.shスクリプトを実行してエラー率を確認します。cd cd kubernetes-engine-samples/quickstarts/hello-app-redis/scripts watch ./print_error_rate.shQPS が発生すると 100% の成功率と 0% エラー率が表示されます。
両方のスクリプトを実行したまま、次のセクション用に 3 つ目のターミナルを開きます。
クラスタをアップグレードする
クラスタをアップグレードするには、次の手順を完了します。
redis-testクラスタが使用している GKE のバージョンを確認します。V=$(gcloud container clusters describe redis-test | grep "version:" | sed "s/version: //") echo $V出力は
1.22.9-gke.2000のようになります。使用可能な Kubernetes バージョンのリストを取得します。
gcloud container get-server-configバージョンのリストで
validMasterVersions:セクションに移動し、前の手順で取得したredis-testバージョンを探します。ノードと互換性のないバージョンを選択して GKE バージョン スキュー ポリシーに違反しないようにするには、redis-testバージョンの直前にリストされているバージョンをコピーします。クラスタのコントロール プレーンを選択したバージョンにアップグレードします。プロンプトが表示されたら「
y」と入力します。gcloud container clusters upgrade redis-test \ --master \ --cluster-version VERSIONVERSION は、前のステップで選択したバージョンに置き換えます。
コントロール プレーンのアップグレードには数分かかります。
クラスタのノードを選択したバージョンにアップグレードします。プロンプトが表示されたら「
y」と入力します。gcloud container clusters upgrade redis-test \ --cluster-version=VERSION \ --node-pool=default-poolVERSION は、リストで選択したバージョンに置き換えます。
ワークロードの中断をテストする
このセクションでは、アプリケーションのステータスをテストして、ワークロードの中断を観察します。
./print_error_rate.shを実行しているターミナル ウィンドウに戻り、アップグレード中の成功率の変化を確認します。アップグレードのためにノードが停止すると、成功率が若干低下し、アプリのネットワーク エラー率がわずかに増加します。Success rateフィールドには、ウェブサイトに対して成功したアクセス数が表示されます。この値をメモします。関連するターミナルで「
CTRL+C」と入力して、両方のスクリプトの実行を停止します。アプリケーションの IP アドレス(Redis クライアント アプリケーションのデプロイでコピーした EXTERNAL_IP)をブラウザに入力して、アプリケーションのウェブサイトに戻ります。
アプリのアクセス数を確認します。表示された数値は次のようになるはずです。
ORIGINAL_VISIT_NUMBER + SUCCESSFUL_VISIT_NUMBERORIGINAL_VISIT_NUMBER は、Redis クライアント アプリケーションをデプロイするの最後で記録した数字です。SUCCESSFUL_VISIT_NUMBER は、このセクションの最初のステップで記録した数値です。
クリーンアップ
チュートリアルが終了したら、作成したリソースをクリーンアップして、割り当ての使用を停止し、課金されないようにできます。次のセクションで、リソースを削除または無効にする方法を説明します。
プロジェクトの削除
課金されないようにする最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。
プロジェクトを削除するには:
- Google Cloud コンソールで [リソースの管理] ページに移動します。
- プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
- ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。
クラスタの削除
このチュートリアル用に作成したクラスタを削除するには、次のコマンドを実行します。
gcloud container clusters delete redis-test