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 = Falseproject = <YOUR PROJECT ID>[metrics]environment = devshell❯ gcloud projects listPROJECT_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 nodesNAME STATUS ROLES AGE VERSIONgke-demo-default-pool-31dcfbba-02j8 Ready <none> 17h v1.13.11-gke.14gke-demo-default-pool-31dcfbba-bw3r Ready <none> 17h v1.13.11-gke.14gke-demo-default-pool-31dcfbba-hx3f Ready <none> 25h v1.13.11-gke.14gke-demo-default-pool-31dcfbba-n21g Ready <none> 25h v1.13.11-gke.14gke-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 servicesNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEadservice ClusterIP 10.7.240.120 <none> 9555/TCP 100mcartservice ClusterIP 10.7.246.125 <none> 7070/TCP 100mcheckoutservice ClusterIP 10.7.255.114 <none> 5050/TCP 100mcurrencyservice ClusterIP 10.7.245.160 <none> 7000/TCP 100memailservice ClusterIP 10.7.242.238 <none> 5000/TCP 100mfrontend ClusterIP 10.7.241.1 <none> 80/TCP 100mfrontend-external LoadBalancer 10.7.252.1 35.200.98.25 80:32213/TCP 100mkubernetes ClusterIP 10.7.240.1 <none> 443/TCP 107mpaymentservice ClusterIP 10.7.250.63 <none> 50051/TCP 100mproductcatalogservice ClusterIP 10.7.241.118 <none> 3550/TCP 100mrecommendationservice ClusterIP 10.7.253.135 <none> 8080/TCP 100mredis-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 diffdiff --git a/src/frontend/templates/header.html b/src/frontend/templates/header.htmlindex 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 deploymentsNAME STATUS ROLES AGE VERSIONgke-demo-default-pool-f11743f4-3sqz Ready <none> 9m21s v1.13.11-gke.14gke-demo-default-pool-f11743f4-k407 Ready <none> 9m21s v1.13.11-gke.14gke-demo-default-pool-f11743f4-nmms Ready <none> 9m22s v1.13.11-gke.14gke-demo-default-pool-f11743f4-vpr3 Ready <none> 9m20s v1.13.11-gke.14gke-demo-default-pool-f11743f4-w32q Ready <none> 9m21s v1.13.11-gke.14NAME READY STATUS RESTARTS AGEadservice-98447d4c5-77tnm 1/1 Running 0 2m22scartservice-5c67bcf9cd-9z8nf 1/1 Running 2 2m21scheckoutservice-d98558fd4-fqtnp 1/1 Running 0 2m21scurrencyservice-6bc9cdf975-7mxfz 1/1 Running 0 2m21semailservice-56858878b9-dc688 1/1 Running 0 2m20sfrontend-56cc98d94f-c6bnq 1/1 Running 0 2m20sloadgenerator-7f6885986-r5kz2 1/1 Running 4 2m19spaymentservice-7774b87dc-6zbfr 1/1 Running 0 2m19sproductcatalogservice-59cdb4dfb-t8w8g 1/1 Running 0 2m19srecommendationservice-765499f89f-wl4gd 1/1 Running 0 2m19sredis-cart-85589759fc-qdvm2 1/1 Running 0 2m18sshippingservice-c9f7f88ff-q62rb 1/1 Running 0 2m18sNAME READY UP-TO-DATE AVAILABLE AGEadservice 1/1 1 1 5h22mcartservice 1/1 1 1 5h22mcheckoutservice 1/1 1 1 5h22mcurrencyservice 1/1 1 1 5h22memailservice 1/1 1 1 5h22mfrontend 1/1 1 1 5h22mloadgenerator 1/1 1 1 5h22mpaymentservice 1/1 1 1 5h22mproductcatalogservice 1/1 1 1 5h22mrecommendationservice 1/1 1 1 5h22mredis-cart 1/1 1 1 5h22mshippingservice 1/1 1 1 5h22m
- Replica の設定: kubectl scale を使用するには、--replicas フラグを設定して新しいレプリカ数を指定します。たとえば frontend を 3 つのレプリカにスケーリングするには、次のコマンドを実行します。
❯ kubectl scale deployment frontend --replicas 3deployment.extensions/frontend scaled❯ kubectl get deploymentsNAME READY UP-TO-DATE AVAILABLE AGEadservice 1/1 1 1 5h26mcartservice 1/1 1 1 5h26mcheckoutservice 1/1 1 1 5h26mcurrencyservice 1/1 1 1 5h26memailservice 1/1 1 1 5h26mfrontend 3/3 3 3 5h26mloadgenerator 1/1 1 1 5h26mpaymentservice 1/1 1 1 5h26mproductcatalogservice 1/1 1 1 5h26mrecommendationservice 1/1 1 1 5h26mredis-cart 1/1 1 1 5h26mshippingservice 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 VERSIONgke-demo-default-pool-31dcfbba-02j8 Ready <none> 12h v1.13.11-gke.14gke-demo-default-pool-31dcfbba-bw3r Ready <none> 12h v1.13.11-gke.14gke-demo-default-pool-31dcfbba-hx3f Ready <none> 20h v1.13.11-gke.14gke-demo-default-pool-31dcfbba-n21g Ready <none> 20h v1.13.11-gke.14gke-demo-default-pool-31dcfbba-t4b5 Ready <none> 20h v1.13.11-gke.14NAME READY STATUS RESTARTS AGEadservice-6ddc9946c8-bdmqb 1/1 Running 0 11hcartservice-586ff4f58f-2hf8h 1/1 Running 0 11hcheckoutservice-7f65db74db-q4zxf 1/1 Running 0 11hcurrencyservice-85974f87bd-9xg6h 1/1 Running 1 11hemailservice-584b5f69f8-t94gk 1/1 Running 0 11hfrontend-6c6b8fdbf-5mjsd 1/1 Running 0 2m54sfrontend-6c6b8fdbf-7jsfx 1/1 Running 0 2m54sfrontend-6c6b8fdbf-fnt4x 1/1 Running 0 11hloadgenerator-7475f6d475-j65ln 1/1 Running 0 11hpaymentservice-99b7787bb-j5xwg 1/1 Running 0 11hproductcatalogservice-74df8697c-gggs2 1/1 Running 0 11hrecommendationservice-7cd77d46b9-lz6bt 1/1 Running 0 11hredis-cart-6d689df55-v4dlv 1/1 Running 0 11hshippingservice-7ffd8d5db8-f75t4 1/1 Running 0 11hNAME READY UP-TO-DATE AVAILABLE AGEadservice 1/1 1 1 19hcartservice 1/1 1 1 19hcheckoutservice 1/1 1 1 19hcurrencyservice 1/1 1 1 19hemailservice 1/1 1 1 19hfrontend 3/3 3 3 19hloadgenerator 1/1 1 1 19hpaymentservice 1/1 1 1 19hproductcatalogservice 1/1 1 1 19hrecommendationservice 1/1 1 1 19hredis-cart 1/1 1 1 19hshippingservice 1/1 1 1 19hNo resources found.
- オートヒーリングのテスト: 元のウインドウに戻り(Ctrl + b → o)、Pod が落ちたときでも、自動的に新しくコンテナを作成されることを確認します。(分割ウインドウの状態を確認)
❯ kubectl delete pod <adservice POD NAME>
- オートヒーリングのテスト: Node が落ちたときでも、自動的に Node が再起動されることを確認します。(分割ウインドウを確認)
❯ kubectl describe pod <adservice pod name> | grep NodeNode: gke-demo-default-pool-f11743f4-7ddf/99.99.99.99Node-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 frontendNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEfrontend 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 requestsCompleted 10000 requestsCompleted 15000 requestsCompleted 20000 requestsCompleted 25000 requests
クリーンアップ
利用したリソースを今後利用しない場合は、課金を避けるためにも削除しましょう。
アプリケーションを削除する場合: skaffold run コマンドを使ってデプロイした場合は、skaffold delete コマンドで、デプロイしたアプリケーションをクリーンアップすることができます。kubectl apply -f [...] コマンドを使ってデプロイした場合は、kubectl delete -f [...] コマンドで、デプロイしたアプリケーションをクリーンアップしてください。
❯ skaffold deleteCleaning 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 listNAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUSstandard-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)? yDeleting 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 listcurious-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)? YDeleted [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
いかがでしょうか。マイクロサービスの開発、ビルド、デプロイ、運用を体験できたでしょうか。本来のマイクロサービスアプリケーションは、もっと大規模なものになるとは思いますが、少しでも実感が湧いてもらえればと思います。