負荷試験を⾏う際に、⼩規模であればあまり気にする必要はないと思いますが、中〜⼤規模になってくると、負荷掛け環境にも⾼い性能が求められるケースがあります。
しかし、事前にどのくらいの性能が必要かを予想するのは難しいため、⾃動スケーリングでリソースを確保できたら楽ですよね。
Google Cloudでは、そのような場合に備えた負荷掛け環境をGKEを⽤いて構築する⽅法が紹介されています。
Google Kubernetes Engine を使⽤した負荷分散テスト
今回は、この⼿順に沿って実際に負荷掛け環境を構築していきます。
仕組み
構成は以下のようになっています。
Locustの画⾯操作とモニタリングはマスターポッドで処理され、内部TCP/UDPロードバランサを通して、ウェブ上で確認できます。
ワーカーポッドは負荷試験対象へのリクエストを⽣成するため、リクエスト数を増やすほどにワーカーポッドの台数も必要になります。
また、ポート8089はLocustのウェブインターフェース⽤に使⽤し、ポート5557, 5558はポッドへの通信のために使⽤しています。
前提条件
- 下記APIの有効化
- App Engine
- Artifact Registry
- Cloud Build
- Compute Engine
- Resource Manager
- Google Kubernetes Engine
- Identity and Access Management
- 下記権限の付与
- Service Usage 管理者
- Kubernetes Engine 管理者
- App Engine 管理者
- App Engine 作成者
- Artifact Registry 管理者
- プロジェクト IAM 管理者
- Compute インスタンス管理者(v1)
- サービス アカウント ユーザー
- Cloud Build サービス アカウント
- サービス アカウント管理者
- 負荷試験ツール:Locust
- Locustアプリケーション⽤コンテナイメージ:distributed-load-testing-using-kubernetes
設定⽅法
GKEクラスタ作成
1.GKEにアタッチするサービスアカウントを以下の権限で作成
- Artifact Registry 読み取り
- Kubernetes Engine ノード サービス エージェント
2.GKEクラスタを作成
gcloud container clusters create 【GKEクラスタ名】 \ --service-account=【作成したサービスアカウント】 \ --region 【リージョン】 \ #asia-northeast1 --network=【VPC名】 --subnetwork=【サブネット名】 --machine-type 【ノードに使⽤するマシンタイプ】 \ #e2-standard-4 --enable-autoscaling \ --num-nodes 3 \ --min-nodes 3 \ --max-nodes 10 \ --scopes "【スコープのURI】" #クラウドプラットフォーム(https://www.googleapis.com/auth/cloud-platform)
3.GKEクラスタに接続
gcloud container clusters get-credentials 【GKEクラスタ名】 \ --region 【リージョン】 \ --project 【プロジェクト名】
以下のように出⼒されればOKです。
Fetching cluster endpoint and auth data. kubeconfig entry generated for 【GKEクラスタ名】.
補⾜1
GKEクラスタを作成する際に、レガシーネットワークを指定していると下記のエラーが発⽣します。
––no-enable-ip-aliasを付けることでエラーは回避できますが、エイリアスIPを使⽤したい場合は、レガシーネットワークを使わないようしましょう。
- ResponseError: code=400, message=IP aliases cannot be used with a legacy network.
コンテナイメージのビルド
1.GitHubからサンプルリポジトリをクローン
git clone https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes
2.作業ディレクトリを移動
cd distributed-load-testing-using-kubernetes
3.Artifact Registryにリポジトリを作成
gcloud artifacts repositories create 【Artifact Registryリポジトリ名】 \ --repository-format=docker \ --location=【リージョン】 \ --description="Distributed load testing with GKE and Locust"
4.コンテナイメージをビルド
gcloud builds submit \ --tag 【リージョン】-docker.pkg.dev/【プロジェクト名】/【Artifact Registryのリポジトリ名】/【コンテナイメージ名】:【イメージタグ】 \ docker-image
5.イメージがArtifact Registryに保存されたことを確認
gcloud artifacts docker images list 【リージョン】-docker.pkg.dev/【プロジェクト名】/【Artifact Registryのリポジトリ名】 | grep 【コンテナイメージ名】
以下が出力されればOKです。
Listing items under project 【プロジェクト名】, location 【リージョン】, repository 【Artifact Registryのリポジトリ名】. IMAGE: 【リージョン】-docker.pkg.dev/【プロジェクト名】/【Artifact Registryのリポジトリ名】/【コンテナイメージ名】
docker-image/locust-tasks/tasks.py
サンプルアプリケーションは、/loginと/metricsへのリクエストを1:999の割合でテストするアプリケーションとなっています。
class MetricsTaskSet(TaskSet): _deviceid = None def on_start(self): self._deviceid = str(uuid.uuid4()) @task(1) def login(self): self.client.post( '/login', {"deviceid": self._deviceid}) @task(999) def post_metrics(self): self.client.post( "/metrics", {"deviceid": self._deviceid, "timestamp": datetime.now()}) class MetricsLocust(FastHttpUser): tasks = {MetricsTaskSet}
GKEのマスターポッドとワーカーポッドのデプロイ
1.以下のファイルのパラメータを編集
vi kubernetes-config/locust-master-controller.yaml.tpl vi kubernetes-config/locust-worker-controller.yaml.tpl
- image:【リージョン】-docker.pkg.dev/【プロジェクト名】/【Artifact Registryのリポジトリ名】/【コンテナイメージ名】
- Target_Host:http://【負荷試験対象のFQDN】
- その他、必要に応じてポッド数などを調整する
2.マスターデプロイメント、およびワーカーデプロイメントを作成
envsubst < kubernetes-config/locust-master-controller.yaml.tpl | kubectl apply -f - envsubst < kubernetes-config/locust-worker-controller.yaml.tpl | kubectl apply -f - envsubst < kubernetes-config/locust-master-service.yaml.tpl | kubectl apply -f -
3.デプロイメントが作成されたことを確認
kubectl get pods -o wide
以下のように出力されればOKです。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES locust-master-77c8784dd7-pgclg 1/1 Running 0 73s 10.44.7.6 gke-kameda-test-gke-default-pool-1f1a4018-d95t <none> <none> locust-worker-86854fbf74-4zfw4 1/1 Running 0 58s 10.44.8.2 gke-kameda-test-gke-default-pool-1f1a4018-d5gq <none> <none> locust-worker-86854fbf74-hbmbb 1/1 Running 0 58s 10.44.6.3 gke-kameda-test-gke-default-pool-1f1a4018-sw5f <none> <none> locust-worker-86854fbf74-np4bn 1/1 Running 0 58s 10.44.2.4 gke-kameda-test-gke-default-pool-f1d133a3-h4ms <none> <none> locust-worker-86854fbf74-vtrvj 1/1 Running 0 58s 10.44.3.4 gke-kameda-test-gke-default-pool-f7ba5e2f-1n03 <none> <none> locust-worker-86854fbf74-wfkm7 1/1 Running 0 58s 10.44.0.3 gke-kameda-test-gke-default-pool-f1d133a3-8t4s <none> <none>
4.サービスを確認
kubectl get services
以下のように出力されればOKです。
後ほど、locust-master-webのEXTERNAL-IPの値でLocustアプリケーションへ接続します。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.48.0.1 <none> 443/TCP 23m locust-master ClusterIP 10.48.12.154 <none> 5557/TCP,5558/TCP 102s locust-master-web LoadBalancer 10.48.5.48 10.10.10.17 8089:30780/TCP 102s
Locustアプリケーションへ接続
内部ロードバランサを立てているため、同じネットワーク内からは接続できますが、インターネットから接続することはできません。
そのため、プロキシ用GCEを作成し、SSHトンネルを使用して接続します。
- プロキシ用GCEを作成
gcloud compute instances create-with-container 【GCE名】 \ --zone 【ゾーン】 \ --network 【VPC名】 \ --subnet 【サブネット名】 \ --container-image gcr.io/cloud-marketplace/google/nginx1:latest \ --container-mount-host-path=host-path=/tmp/server.conf,mount-path=/etc/nginx/conf.d/default.conf \ --metadata=startup-script="#! /bin/bash cat <<EOF > /tmp/server.conf server { listen 8089; location / { proxy_pass http://【locust-master-webのEXTERNAL-IP】:8089; } } EOF"
2.(開いてない場合は)マネジメントコンソール右上のアイコンからCloud Shellを開く
3.プロキシ用GCEへのSSHトンネルを開く
gcloud compute ssh --zone 【ゾーン】 【GCE名】 -- -N -L 8089:localhost:8089
4.Cloud Shellターミナルの右上のアイコンから、[ウェブでプレビュー]をクリック
5.[ポートを変更]を選択し、値に8089と入力
6.ブラウザでLocustのページが表示されればOK
終わりに
GKEとサンプルコンテナイメージを利用して、Locustアプリケーションをデプロイできました。
私は今回初めてGKEを触ったので、詳細設定についてはわかっていない部分が多いのですが、それでもこんなに簡単に負荷掛け環境を構築できることに非常に驚きました。
また、Cloud Monitoringでリクエスト数の増減やレイテンシなどを確認すれば、Google Cloud内で全てを完結させることも可能です。