このチュートリアルでは、ステートフル アプリケーションを作成し、アプリケーションを実行する Google Kubernetes Engine(GKE)クラスタをアップグレードする際のおすすめの方法を説明します。このチュートリアルでは、Redis アプリケーションをデプロイする例を紹介しますが、GKE にデプロイされた他のタイプのステートフル アプリケーションにも同じコンセプトを適用できます。
用語集
このチュートリアルで使用する用語:
- Redis はオープンソース(BSD ライセンス)のインメモリ データ構造のストアで、データベース、キャッシュ、メッセージ ブローカーとして使用されます。
- Redis クラスタは、高可用性を提供する Redis の分散実装です。Redis クラスタは、リーダーノードとフォロワー ノードで構成されています。
- ステートフル アプリケーションは、実行されるたびにその状態情報を保存します。Redis はステートフル アプリケーション向けの一般的なインメモリ データベースです。
目標
このチュートリアルでは、次の手順について説明します。
- GKE で、3 つの GKE ノードの上に 3 つのリーダーと 3 つのフォロワーからなる Redis クラスタを作成します。
- Redis クライアント アプリケーションをデプロイします。このアプリケーションは、ウェブサイトに対するリクエストの数をカウントします。
- サージ アップグレードを使用してクラスタをアップグレードします。
- アプリケーションのワークロードの中断とステータスの中断をテストします。
次の図は、これらの目標を達成して作成したクラスタ アーキテクチャの概要を示しています。
費用
このチュートリアルでは、Google Cloud の課金対象となる以下のコンポーネントを使用します。
- GKE
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。
始める前に
次の手順で Kubernetes Engine API を有効にします。- Google Cloud Console で Kubernetes Engine ページにアクセスします。
- プロジェクトを作成または選択します。
- API と関連サービスが有効になるのを待ちます。 これには数分かかることがあります。
-
Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する。
このチュートリアルで使用されている以下のコマンドライン ツールをインストールします。
-
gcloud
は、Kubernetes Engine クラスタの作成と削除に使用されます。gcloud
は、Google Cloud SDK に含まれています。 -
kubectl
は、Kubernetes Engine で使用されるクラスタ オーケストレーション システムである Kubernetes の管理に使用されます。gcloud
を使用してkubectl
をインストールできます。gcloud components install kubectl
GKE クラスタの作成
このセクションでは、GKE に 3 つのノードからなるクラスタを作成し、そのクラスタの動作確認を行います。
gcloud コマンドライン ツールのデフォルトの設定
次のデフォルトを設定すると、gcloud
コマンドライン ツールでプロジェクト ID と Compute Engine ゾーンのオプションを入力する時間が節約されます。
gcloud config set project PROJECT-ID
gcloud config set compute/zone COMPUTE-ZONE
GKE クラスタの作成
GKE クラスタを作成するには、次の手順を行います。
3 つのノードを持つクラスタを
redis-test
という名前で作成します。gcloud container clusters create redis-test \ --num-nodes=3
クラスタが作成されると、次のような出力が表示されます。
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS redis-test COMPUTE-ZONE 1.15.12-gke.20 35.232.77.38 n1-standard-1 1.15.12-gke.20 3 RUNNING
クラスタと通信を行うように
kubectl
を構成します。gcloud container clusters get-credentials redis-test
クラスタが実行中であることを確認します。
kubectl get nodes
出力は次の例のようになります。
NAME STATUS ROLES AGE VERSION gke-redis-test-default-pool-c4e4225c-mw3w Ready <none> 2m1s v1.15.12-gke.20 gke-redis-test-default-pool-c4e4225c-pv51 Ready <none> 2m1s v1.15.12-gke.20 gke-redis-test-default-pool-c4e4225c-whl5 Ready <none> 2m1s v1.15.12-gke.20
GKE での Redis クラスタの作成
このセクションでは、ConfigMap、StatefulSet、ヘッドレス Service を作成し、前のセクションで作成した GKE クラスタの上に Redis クラスタを作成します。
サンプル マニフェストのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/hello-app-redis/manifests
redis-configmap.yaml
という名前の ConfigMap には Redis 構成が格納されます。この ConfigMap の Redis パラメータの詳細については、Redis クラスタ チュートリアルで Redis クラスタ構成パラメータのセクションをご覧ください。
次のコマンドを実行して ConfigMap をデプロイします。
kubectl apply -f redis-configmap.yaml
Statefulset
redis-cluster.yaml
には次のキーフィールドがあります。replicas
フィールドは6
に設定されています。それぞれの GKE ノードに 2 つの Pod があり、3 つの Redis リーダーと 3 つの Redis フォロワーに使用します。volumeClaimTemplates
フィールドにより、PersistentVolume を使用して安定したストレージを提供します。affinity
フィールドにより、Pod のアンチアフィニティ ルールを作成して、Kubernetes ノード間で Pod を分散させます。
次のコマンドを実行して、StatefulSet をデプロイします。
kubectl apply -f redis-cluster.yaml
redis-service.yaml
という名前のヘッドレス Service は、Redis ノードの接続用です。ヘッドレス Service を作成するには、clusterIP
フィールドをNone
に設定します。次のコマンドを実行して、Service をデプロイします。
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 クラスタにロールを割り当てます。
ロールの割り当て手順は次のとおりです。
最初の 3 つの Redis ノードをリーダー、最後の 3 つの Redis ノードをフォロワーとして設定します。
Pod の IP アドレスを取得してコピーします。
kubectl get pods -l app=redis -o jsonpath='{range.items[*]}{.status.podIP} '
各 Pod の IP アドレスを次のコマンドを貼り付け、リーダーとフォロワーのロールを割り当てます。プロンプトが表示されたら「
yes
」と入力します。kubectl exec -it redis-0 -- redis-cli --cluster create --cluster-replicas 1 \ POD-IP-1:6379 POD-IP-2:6379 POD-IP-3:6379 \ POD-IP-4:6379 POD-IP-5:6379 POD-IP-6:6379
Redis クラスタが実行中であることを確認します。
kubectl exec -it redis-0 -- redis-cli cluster info
出力は次の例のようになります。
cluster_state:ok # ...other output...
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 クライアント アプリケーションの作成
このセクションでは、Redis データベースをキャッシュ データベースとして使用し、受信したリクエストの数をカウントして、その数をウェブサイトに出力する hello-app-redis
という名前のアプリケーションを作成します。Redis Service が機能している間、ユーザー数は増え続けます。
このイメージは、Google Cloud Console の gcr.io/google-samples/hello-app-redis:1.0 から直接ダウンロードできます。
イメージを pull するには、次のコマンドを実行します。
docker pull gcr.io/google-samples/hello-app-redis:1.0
イメージのビルド方法については、コンテナ イメージのビルドをご覧ください。
Redis クライアント アプリケーションの GKE へのデプロイ
作成した GKE クラスタにアプリケーションをデプロイするには、アプリケーションを定義する Deployment が必要です。
Deployment を作成するには、次の手順を行います。
app-deployment.yaml
という名前のファイルに、アプリケーションの詳細が格納されます。この Deployment で使用される Probe と Pod のアフィニティ ルールの詳細については、GKE のベスト プラクティス: 高可用性クラスタの設計と構築をご覧ください。
次のコマンドを実行して Deployment を適用します。
kubectl apply -f app-deployment.yaml
このコマンドは、
app-deployment.yaml
と同じディレクトリで実行してください。ロードバランサ経由でアプリケーションを公開します。
kubectl expose deployment hello-web \ --type=LoadBalancer \ --port 80 \ --target-port 8080
約 1 分待ってから次のコマンドを実行して、アプリケーションの外部 IP アドレスを取得します。
kubectl get service
出力から、
hello-web's
EXTERNAL-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
GKE クラスタのアップグレードとワークロードの中断のテスト
以降のセクションでは、GKE クラスタをアップグレードし、作成したスクリプトを使用して何が起こるかを監視します。
アプリケーションのテスト
このセクションでは、アプリケーションにリクエストを送信するスクリプトと、リクエストの成功率を測定する 2 つのスクリプトを使用します。これらのスクリプトを使用して、クラスタをアップグレードしたときに何が起こるかを測定します。
スクリプトを作成するには:
スクリプトが含まれているディレクトリに移動します。
cd cd kubernetes-engine-samples/hello-app-redis/scripts
generate_load.sh
という名前のスクリプトは、秒間クエリ数(QPS)リクエストをアプリケーションに送信します。このスクリプトは、現在のディレクトリのoutput
という名前のファイルに HTTP レスポンス コードを保存します。output
の値は、次の手順で作成するスクリプトで使用します。print_error_rate.sh
という名前の 2 番目のスクリプトは、generate_load.sh
によって生成された出力に基づいて成功率を計算します。スクリプトの実行権限を付与します。
chmod u+x generate_load.sh print_error_rate.sh
QPS の数を格納する変数を設定します。この値は、EXTERNAL_IP に設定した変数と同様に
generate_load.sh
スクリプトで使用されます。値に 40 を設定することをおすすめします。export QPS=40
generate_load.sh
スクリプトを実行して QPS の送信を開始します。./generate_load.sh $IP $QPS 2>&1
generate_load.sh
スクリプトを実行したまま、新しいターミナルを開きます。新しいターミナルで、print_error_rate.sh
スクリプトを実行してエラー率を確認します。watch ./print_error_rate.sh
QPS が発生すると 100% の成功率と 0% エラー率が表示されます。
両方のスクリプトを実行したまま、次のセクション用に 3 つ目のターミナルを開きます。
クラスタのアップグレード
このセクションでは、ワークロードをアップグレードします。
さきほど開いたターミナルで、サージ アップグレードを使用してアップグレードの設定を定義します。
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 の再起動が速くなります。redis-test
クラスタが使用している GKE のバージョンを確認します。V=$(gcloud container clusters describe redis-test | grep "version:" | sed "s/version: //") echo $V
出力は
1.15.12-gke.20
のようになります。使用可能な Kubernetes バージョンのリストを取得します。
gcloud container get-server-config
バージョンのリストで
validMasterVersions:
セクションに移動し、前の手順で取得したredis-cluster
バージョンを探します。バージョン スキューを回避するため、redis-cluster
バージョンのすぐ上にあるバージョンをコピーします。クラスタのコントロール プレーンを選択したバージョンにアップグレードします。プロンプトが表示されたら「
y
」と入力します。gcloud container clusters upgrade redis-test \ --master \ --cluster-version VERSION
VERSION は、前のステップで選択したバージョンに置き換えます。
コントロール プレーンのアップグレードには数分かかります。
クラスタのノードを選択したバージョンにアップグレードします。プロンプトが表示されたら「
y
」と入力します。gcloud container clusters upgrade redis-test \ --cluster-version=VERSION \ --node-pool=default-pool
VERSION は、リストで選択したバージョンに置き換えます。
ワークロードの中断のテスト
このセクションでは、アプリケーションのステータスとワークロードの中断をテストします。
./print_error_rate.sh
を実行しているターミナル ウィンドウに戻り、アップグレード中の成功率の変化を確認します。アップグレードのためにノードが停止すると、成功率が若干低下し、アプリのネットワーク エラー率がわずかに増加します。Success rate
フィールドには、ウェブサイトに対して成功したアクセス数が表示されます。この値をメモします。関連するターミナルで「
CTRL+C
」と入力して、両方のスクリプトの実行を停止します。アプリケーションの IP アドレス(GKE へのデプロイでコピーした EXTERNAL_IP)をブラウザに入力して、アプリケーションのウェブサイトに戻ります。
アプリのアクセス数を確認します。表示された数値は次のようになるはずです。
ORIGINAL_VISIT_NUMBER + SUCCESSFUL_VISIT_NUMBER
ORIGINAL_VISIT_NUMBER は、GKE へのデプロイの最後で記録した数字です。SUCCESSFUL_VISIT_NUMBER は、このセクションの最初のステップで記録した数値です。
クリーンアップ
ステートフル ワークロードのアップグレード チュートリアルが終了したら、Google Cloud で作成したリソースをクリーンアップして、今後料金が発生しないようにします。次のセクションで、リソースを削除または無効にする方法を説明します。
プロジェクトの削除
課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。
プロジェクトを削除するには:
- Cloud Console で [リソースの管理] ページに移動します。
- プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
- ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。
クラスタの削除
このチュートリアル用に作成したクラスタを削除するには、次のコマンドを実行します。
gcloud container clusters delete redis-test
次のステップ
- Google Cloud のその他の機能を試す。チュートリアルをご覧ください。