Google Cloud Platform
体験して理解しよう!マイクロサービスの開発、ビルド、デプロイ、運用
デモ用のマイクロサービスアプリケーションを使って実際に、マイクロサービスアプリケーションの開発、ビルド、デプロイ、運用を体験してみましょう。
このアプリケーションは、10 のサービスで構成されている「Hipster Shop」と呼ばれるデモ用の EC サイトです。ユーザーは、製品を選択し、カートに追加し購入することができます。各サービスは、Go, C#, Node.js, Python, Java といった言語で独自に書かれおり、下記のように、gRPC でコミュニケーションします。また、開発者は skaffold を使用し、1 コマンドでアプリケーションのビルド、デプロイが可能です。実行環境は、Google Kubernetes Engine (GKE) や、Local の Kubernetes 環境を選択することができます。今回は、GKE 環境を使って体験してみたいと思います。準備
プロジェクトを作成し、Cloud Shell を起動し、デモ用のマイクロサービスアプリケーションをクローンします。
- GCP アカウントと、GitHub アカウントを作成(既にアカウントを持っている方は必要ありません)
- GCP Console にログオンし、プロジェクトを作成
- [Cloud Shell をアクティブにする] をクリック
- [Cloud Shell 環境] から、Cloud Shell を起動
- gcloud コマンドの初期設定
❯ gcloud config list
[component_manager]
disable_update_check = True
[compute]
gce_metadata_read_timeout_sec = 5
[core]
account = <You Account Name>
disable_usage_reporting = False
project = <YOUR PROJECT ID>
[metrics]
environment = devshell
❯ gcloud projects list
PROJECT_ID NAME PROJECT_NUMBER
<YOUR PROJECT ID> <YOUR PROJECT NAME> <YOUR PROJECT NUMBER>
❯ gcloud config set project <YOUR PROJECT ID>
- Cloud Shell にて、Falk した マイクロサービスアプリケーションを Clone
❯ git init
❯ git config --global user.name "<YOUR NAME>"
❯ git config --global user.email <YOUR EMAIL>
❯ git clone https://github.com/<YOUR GITHUB ID>/microservices-demo.git
❯ cd microservices-demo
- 必要な GCP のサービスを有効に
❯ gcloud services enable cloudbuild.googleapis.com sourcerepo.googleapis.com containerregistry.googleapis.com container.googleapis.com cloudtrace.googleapis.com cloudprofiler.googleapis.com logging.googleapis.com compute.googleapis.com
- Container Registry を Docker registry として利用するために、gcloud を Docker 認証ヘルパーとして登録
❯ gcloud auth configure-docker -q
アプリケーションのデプロイ
GKE クラスタを作成し、アプリケーションをデプロイします。
GKE クラスタを作成
❯ gcloud container clusters create demo --enable-autoupgrade --enable-autoscaling --min-nodes=3 --max-nodes=10 --num-nodes=5 --zone=asia-northeast1-a
❯ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-demo-default-pool-31dcfbba-02j8 Ready <none> 17h v1.13.11-gke.14
gke-demo-default-pool-31dcfbba-bw3r Ready <none> 17h v1.13.11-gke.14
gke-demo-default-pool-31dcfbba-hx3f Ready <none> 25h v1.13.11-gke.14
gke-demo-default-pool-31dcfbba-n21g Ready <none> 25h v1.13.11-gke.14
gke-demo-default-pool-31dcfbba-t4b5 Ready <none> 25h v1.13.11-gke.14
- アプリケーションのビルドとデプロイ - skaffold を使用し、1 コマンドで、ビルドからデプロイメントまで行います。(全てのサービスをビルドするので、30 分程度かかります。)
❯ skaffold run -p gcb --default-repo=gcr.io/<YOUR PROJECT ID>
❯ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
adservice ClusterIP 10.7.240.120 <none> 9555/TCP 100m
cartservice ClusterIP 10.7.246.125 <none> 7070/TCP 100m
checkoutservice ClusterIP 10.7.255.114 <none> 5050/TCP 100m
currencyservice ClusterIP 10.7.245.160 <none> 7000/TCP 100m
emailservice ClusterIP 10.7.242.238 <none> 5000/TCP 100m
frontend ClusterIP 10.7.241.1 <none> 80/TCP 100m
frontend-external LoadBalancer 10.7.252.1 35.200.98.25 80:32213/TCP 100m
kubernetes ClusterIP 10.7.240.1 <none> 443/TCP 107m
paymentservice ClusterIP 10.7.250.63 <none> 50051/TCP 100m
productcatalogservice ClusterIP 10.7.241.118 <none> 3550/TCP 100m
recommendationservice ClusterIP 10.7.253.135 <none> 8080/TCP 100m
redis-cart ClusterIP 10.7.253.110 <none> 6379/TCP 100m
- ブラウザを起動し、fronted-external の EXTERNAL-IP にアクセスし、アプリケーションが正常に動作していることを確認
- Cloud Build のログを確認
- Container Registry にあるビルドされたコンテナを確認
ソースコードの修正
ソースコードを修正し、GKE クラスタにアプリケーションを再度デプロイします。
microservices-demo/src/frontend/templates/header.html の <header> を修正し、再ビルド
❯ git diff
diff --git a/src/frontend/templates/header.html b/src/frontend/templates/header.html
index 62444cf..17d6e65 100644
--- a/src/frontend/templates/header.html
+++ b/src/frontend/templates/header.html
@@ -14,7 +14,7 @@
<div class="navbar navbar-dark bg-dark box-shadow">
<div class="container d-flex justify-content-between">
<a href="/" class="navbar-brand d-flex align-items-center">
- Hipster Shop
+ CloudNative Shop
</a>
{{ if $.currencies }}
<form class="form-inline ml-auto" method="POST" action="/setCurrency"
id="currency_form">
❯ skaffold run -p gcb --default-repo=gcr.io/<YOUR PROJECT ID>
- ブラウザを起動し、frontend-external の EXTERNAL-IP にアクセスし、Header 部分が変わっていることを確認
- Build ログの確認
- コンテナの確認
レプリケーションとオートヒーリング
Kubernetes の特徴は「アプリケーションのあるべき姿」を設定ファイル(yaml ファイル)で宣言できるという事です。障害があった場合でも、設定ファイルに書いたとおりのインフラを維持(オートヒーリング)するように設計されています。ここでは、adservice サービスに障害が起きたとき、正しくオートヒーリングするか確認します。また、Node がダウンした場合でも影響を与えたくない frontend サービスにはレプリケーションの設定を行います。
クラスタ環境の確認
❯ kubectl get nodes; kubectl get pods; kubectl get deployments
NAME STATUS ROLES AGE VERSION
gke-demo-default-pool-f11743f4-3sqz Ready <none> 9m21s v1.13.11-gke.14
gke-demo-default-pool-f11743f4-k407 Ready <none> 9m21s v1.13.11-gke.14
gke-demo-default-pool-f11743f4-nmms Ready <none> 9m22s v1.13.11-gke.14
gke-demo-default-pool-f11743f4-vpr3 Ready <none> 9m20s v1.13.11-gke.14
gke-demo-default-pool-f11743f4-w32q Ready <none> 9m21s v1.13.11-gke.14
NAME READY STATUS RESTARTS AGE
adservice-98447d4c5-77tnm 1/1 Running 0 2m22s
cartservice-5c67bcf9cd-9z8nf 1/1 Running 2 2m21s
checkoutservice-d98558fd4-fqtnp 1/1 Running 0 2m21s
currencyservice-6bc9cdf975-7mxfz 1/1 Running 0 2m21s
emailservice-56858878b9-dc688 1/1 Running 0 2m20s
frontend-56cc98d94f-c6bnq 1/1 Running 0 2m20s
loadgenerator-7f6885986-r5kz2 1/1 Running 4 2m19s
paymentservice-7774b87dc-6zbfr 1/1 Running 0 2m19s
productcatalogservice-59cdb4dfb-t8w8g 1/1 Running 0 2m19s
recommendationservice-765499f89f-wl4gd 1/1 Running 0 2m19s
redis-cart-85589759fc-qdvm2 1/1 Running 0 2m18s
shippingservice-c9f7f88ff-q62rb 1/1 Running 0 2m18s
NAME READY UP-TO-DATE AVAILABLE AGE
adservice 1/1 1 1 5h22m
cartservice 1/1 1 1 5h22m
checkoutservice 1/1 1 1 5h22m
currencyservice 1/1 1 1 5h22m
emailservice 1/1 1 1 5h22m
frontend 1/1 1 1 5h22m
loadgenerator 1/1 1 1 5h22m
paymentservice 1/1 1 1 5h22m
productcatalogservice 1/1 1 1 5h22m
recommendationservice 1/1 1 1 5h22m
redis-cart 1/1 1 1 5h22m
shippingservice 1/1 1 1 5h22m
- Replica の設定: kubectl scale を使用するには、--replicas フラグを設定して新しいレプリカ数を指定します。たとえば frontend を 3 つのレプリカにスケーリングするには、次のコマンドを実行します。
❯ kubectl scale deployment frontend --replicas 3
deployment.extensions/frontend scaled
❯ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
adservice 1/1 1 1 5h26m
cartservice 1/1 1 1 5h26m
checkoutservice 1/1 1 1 5h26m
currencyservice 1/1 1 1 5h26m
emailservice 1/1 1 1 5h26m
frontend 3/3 3 3 5h26m
loadgenerator 1/1 1 1 5h26m
paymentservice 1/1 1 1 5h26m
productcatalogservice 1/1 1 1 5h26m
recommendationservice 1/1 1 1 5h26m
redis-cart 1/1 1 1 5h26m
shippingservice 1/1 1 1 5h26m
- コンソールからも設定可能: [Kubernetes Engine] - [ワークロード] で Replica の設定を行いたいサービスを選択し、 [操作] - [スケール] を選択し Replica 数を設定
- クラスタの状態を監視: Cloud Shell で、Ctrl + b → % キーを押し、セッションウィンドウを分割し分割したウインドウで下記コマンドを実行(移動は Ctrl + b → o 、解除は Ctrl + b → x です。)
❯ watch -n1 "kubectl get Node; kubectl get pods; kubectl get deployment; kubectl get hpa"
NAME STATUS ROLES AGE VERSION
gke-demo-default-pool-31dcfbba-02j8 Ready <none> 12h v1.13.11-gke.14
gke-demo-default-pool-31dcfbba-bw3r Ready <none> 12h v1.13.11-gke.14
gke-demo-default-pool-31dcfbba-hx3f Ready <none> 20h v1.13.11-gke.14
gke-demo-default-pool-31dcfbba-n21g Ready <none> 20h v1.13.11-gke.14
gke-demo-default-pool-31dcfbba-t4b5 Ready <none> 20h v1.13.11-gke.14
NAME READY STATUS RESTARTS AGE
adservice-6ddc9946c8-bdmqb 1/1 Running 0 11h
cartservice-586ff4f58f-2hf8h 1/1 Running 0 11h
checkoutservice-7f65db74db-q4zxf 1/1 Running 0 11h
currencyservice-85974f87bd-9xg6h 1/1 Running 1 11h
emailservice-584b5f69f8-t94gk 1/1 Running 0 11h
frontend-6c6b8fdbf-5mjsd 1/1 Running 0 2m54s
frontend-6c6b8fdbf-7jsfx 1/1 Running 0 2m54s
frontend-6c6b8fdbf-fnt4x 1/1 Running 0 11h
loadgenerator-7475f6d475-j65ln 1/1 Running 0 11h
paymentservice-99b7787bb-j5xwg 1/1 Running 0 11h
productcatalogservice-74df8697c-gggs2 1/1 Running 0 11h
recommendationservice-7cd77d46b9-lz6bt 1/1 Running 0 11h
redis-cart-6d689df55-v4dlv 1/1 Running 0 11h
shippingservice-7ffd8d5db8-f75t4 1/1 Running 0 11h
NAME READY UP-TO-DATE AVAILABLE AGE
adservice 1/1 1 1 19h
cartservice 1/1 1 1 19h
checkoutservice 1/1 1 1 19h
currencyservice 1/1 1 1 19h
emailservice 1/1 1 1 19h
frontend 3/3 3 3 19h
loadgenerator 1/1 1 1 19h
paymentservice 1/1 1 1 19h
productcatalogservice 1/1 1 1 19h
recommendationservice 1/1 1 1 19h
redis-cart 1/1 1 1 19h
shippingservice 1/1 1 1 19h
No resources found.
- オートヒーリングのテスト: 元のウインドウに戻り(Ctrl + b → o)、Pod が落ちたときでも、自動的に新しくコンテナを作成されることを確認します。(分割ウインドウの状態を確認)
❯ kubectl delete pod <adservice POD NAME>
- オートヒーリングのテスト: Node が落ちたときでも、自動的に Node が再起動されることを確認します。(分割ウインドウを確認)
❯ kubectl describe pod <adservice pod name> | grep Node
Node: gke-demo-default-pool-f11743f4-7ddf/99.99.99.99
Node-Selectors: <none>
❯ kubectl delete Node <NODE NAME e.g. gke-demo-default-pool-f11743f4-7ddf>
- adservice とサイト全体の状態をブラウザで確認: adservice は ページ下部に広告を表示するサービスです。adservice の Pod や Node が落ちると、一時的に広告が表示されなくなりますが、サイト全体は落ちません。また、オートヒーリングにより、すぐに adservice が再作成され、広告も正常に表示されます。
オートスケーリング
Horizontal Pod Autoscaler (HPA) により、各サービスの CPU 使用率に応じて、Pod を自動的にスケールすることができます。ここでは、負荷がかかりやすい frontend サービスを自動的にスケールするように設定したいと思います。
オートスケーリングの設定: kubectl autoscale を使用するときは、アプリケーションの最大レプリカ数と最小レプリカ数、CPU 使用率の目標を指定します。たとえば、レプリカの最大数を 6、最小数を 3 にして、CPU 使用率の目標を 50% に設定するには、下記コマンドを実行します。(オートスケーリングの設定を解除する場合は、kubectl delete hpa frontend)
❯ kubectl autoscale deployment frontend --max 6 --min 3 --cpu-percent 50
❯ kubectl get hpa frontend
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
frontend Deployment/frontend 3%/50% 3 6 3 48m
- コンソールからも設定可能: [Kubernetes Engine] - [ワークロード] で autoscale の設定を行いたいサービスを選択し、 [操作] - [自動スケーリング] を選択し設定。
- オートスケーリングのテスト: Apache Bench によるストレステストを行い、正しくオートスケールされるか確かめてみます。frontend サービスの CPU 使用率が 50% を超えたあたりから、pod 数が自動的に増加することを確認します。
❯ sudo apt-get install apache2-utils
❯ ab -n 50000 -c 500 http://<EXTERNAL-IP>/
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 34.84.68.23 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
クリーンアップ
利用したリソースを今後利用しない場合は、課金を避けるためにも削除しましょう。
アプリケーションを削除する場合: skaffold run コマンドを使ってデプロイした場合は、skaffold delete コマンドで、デプロイしたアプリケーションをクリーンアップすることができます。kubectl apply -f [...] コマンドを使ってデプロイした場合は、kubectl delete -f [...] コマンドで、デプロイしたアプリケーションをクリーンアップしてください。
❯ skaffold delete
Cleaning up...
- deployment.apps "adservice" deleted
- service "adservice" deleted
- deployment.apps "cartservice" deleted
- service "cartservice" deleted
- deployment.apps "checkoutservice" deleted
- service "checkoutservice" deleted
- deployment.apps "currencyservice" deleted
- service "currencyservice" deleted
- deployment.apps "emailservice" deleted
- service "emailservice" deleted
- deployment.apps "frontend" deleted
- service "frontend" deleted
- service "frontend-external" deleted
- deployment.apps "loadgenerator" deleted
- deployment.apps "paymentservice" deleted
- service "paymentservice" deleted
- deployment.apps "productcatalogservice" deleted
- service "productcatalogservice" deleted
- deployment.apps "recommendationservice" deleted
- service "recommendationservice" deleted
- deployment.apps "redis-cart" deleted
- service "redis-cart" deleted
- deployment.apps "shippingservice" deleted
- service "shippingservice" deleted
- クラスタ毎削除する場合
❯ gcloud container clusters list
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
standard-cluster-1 us-central1-a 1.13.11-gke.14 99.99.99.99 n1-standard-1 1.13.11-gke.14 3 RUNNING
❯ gcloud container clusters delete <CLUSTER NAME e.g. standard-cluster-1> --zone <ZONE NAME e.g. us-central1-a>
The following clusters will be deleted.
- [standard-cluster-1] in [us-central1-a]
Do you want to continue (Y/n)? y
Deleting cluster standard-cluster-1...done.
Deleted [https://container.googleapis.com/v1/projects/digital-heading-264207/zones/us-central1-a/clusters/standard-cluster-1].
- プロジェクト毎削除する場合
❯ gcloud projects list
curious-athlete-264501 My Project 30444 858566370586
❯ gcloud projects delete <PROJECT NAME e.g. curious-athlete-264501>
Your project will be deleted.
Do you want to continue (Y/n)? Y
Deleted [https://cloudresourcemanager.googleapis.com/v1/projects/curious-athlete-264501].
You can undo this operation for a limited period by running the commands below.
$ gcloud projects undelete curious-athlete-264501
いかがでしょうか。マイクロサービスの開発、ビルド、デプロイ、運用を体験できたでしょうか。本来のマイクロサービスアプリケーションは、もっと大規模なものになるとは思いますが、少しでも実感が湧いてもらえればと思います。