docker
kubernetes
locust
GKE

Google Kubernetes Engineチュートリアル locustを動かす

google公式チュートリアルを試してみた
Distributed Load Testing Using

手順は、kubernetesでlocustという負荷テストツールを用いて
負荷分散テスト用のクラスタを作成し、
負荷テスト対象としてサンプルのweb appを
Google App Engineへデプロイして、実際に負荷テストを試すところまで行う

google cloudのアカウントを持っている+gcloudコマンドをインストール済みのところから始める

環境

ubuntu 17.04
kubectl 1.7.8
gcloud 178.0.0
git 2.15.0
docker 17.09.9-ce

手順

ソースコードや手順は公式のgithubリポジトリを利用した
一部実行コマンドや手順を変えているところもある

Distributed Load Testing Using Kubernetes

プロジェクトの作成

https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes#prerequisites

# zoneの設定
$ gcloud config set compute/zone us-west1-c
Updated property [compute/zone].
# プロジェクトの作成
$ gcloud config set project test-12345
# 確認
$ gcloud config list
[compute]
zone = us-west1-c
[core]
account = xx@xx.com
project = test-12345

Google App Engineに負荷テスト対象web appを作成

https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes#deploy-web-application

$ git clone https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes.git
$ cd ./distributed-load-testing-using-kubernetes/

$ gcloud app deploy ./sample-webapp/app.yaml --project=test-12345

Deployed service [default] to [https://test-12345.appspot.com]

動作確認

$ gcloud app browse
Opening [https://test-12345.appspot.com] in a new tab in your default browser.

ブラウザにアクセスすると

Screenshot-2017-11-27 https free-180413 appspot com(1).png

と表示される
https://test-12345.appspot.comが負荷テスト対象のエンドポイントとなる

locustのTARGET_HOST書き換え

https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes#deploy-controllers-and-services

各controllerのconfigファイルのTARGET_HOST環境変数
の部分をweb appのエンドポイント
https://test-12345.appspot.comを書き換えておく

./kubernetes-config/locust-master-controller.yaml(一部抜粋)
          env:
            - name: LOCUST_MODE
              value: master
            - name: TARGET_HOST
              value: https://test-12345.appspot.com
./kubernetes-config/locust-worker-controller.yaml(一部抜粋)
          env:
            - name: LOCUST_MODE
              value: worker
            - name: TARGET_HOST
              value: https://test-12345.appspot.com

kubernetes clusterの作成

https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes#deploy-kubernetes-cluster

1コマンドで簡単に作成できる。クラスタ名はlocust

$ gcloud container clusters create locust
WARNING: Accessing a Container Engine cluster requires the kubernetes commandline
client [kubectl]. To install, run
  $ gcloud components install kubectl
...

Created [https://container.googleapis.com/v1/projects/test-12345/zones/us-west1-c/clusters/locust].
kubeconfig entry generated for locust.
NAME    ZONE        MASTER_VERSION  MASTER_IP       MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
locust  us-west1-c  1.7.8-gke.0     xx.xxx.xxx.xxx  n1-standard-1  1.7.8-gke.0   3          RUNNING

kubectlコマンドのインストール

kubectlコマンドを入れてなかったので、インストールしろといわれた

$ gcloud components install kubectl
 ERROR: (gcloud.components.install) 
You cannot perform this action because the Cloud SDK component manager 
is disabled for this installation. You can run the following command 
to achieve the same result for this installation: 

sudo apt-get install kubectl

今度はapt-getで入れろとでたので、実行する

$ sudo apt-get install kubectl
...
$ kubectl version
Client Version: 
...

インストールできた

動作確認

クラスタが動作しているか確認

$ kubectl config get-contexts
CURRENT   NAME                                CLUSTER                             AUTHINFO                            NAMESPACE
*         gke_test-12345-west1-c_locust   gke_test-12345-west1-c_locust   gke_test-12345-west1-c_locust        

にて作成したクラスタが選択されているのを確認してから

$ kubectl cluster-info
Kubernetes master is running at https://xx.xxx.xxx.xxx
...

動いているっぽい

locust-task用docker imageのbuild

kubernetesにlocustのReplicationControllerをデプロイしていくが、
作成用config(xxx-controller.yaml)、に記述されているcontainer imageのURL、
https://gcr.io/cloud-solutions-images/locust-tasks:latest
にimageがなかったので、ローカルでdocker buildしたimageを使う
リポジトリにはbuild用のファイルも入っているので簡単に作成できる(素晴らしい)

$ cd docker-images
$ docker build -t locust-task:v1.0 ./
Sending build context to Docker daemon  39.42kB
Step 1/8 : FROM python:2.7.8
...

$ cd ../
$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
locust-task             v1.0              15bede444779        36 seconds ago      820MB

xxx-controller.yamlを以下のように書き換えれば作成したdocker imageを使うはず

xxx-controller.yaml(一部抜粋)
    spec:
      containers:
        - name: locust
          image: locust-task:v1.0
          imagePullPolicy: IfNotPresent

locust masterのデプロイ

https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes#deploy-locust-master

デプロイ&動作確認

$ kubectl apply -f kubernetes-config/locust-master-controller.yaml --record
replicationcontroller "locust-master" created

$ kubectl get rc
NAME            DESIRED   CURRENT   READY     AGE
locust-master   1         1         0         49m

podが1つ作成されているのを確認

$ kubectl get pods -l name=locust,role=master
NAME                  READY     STATUS    RESTARTS   AGE
locust-master-q29pl   1/1       Running   0          1m

serviceも作成。locustにアクセスするためのロードバランサが作られる

$ kubectl apply -f kubernetes-config/locust-master-service.yaml --record
service "locust-master" created


$ gcloud compute forwarding-rules list
NAME                              REGION    IP_ADDRESS      IP_PROTOCOL  TARGET
a4e6a0198d38c11e7889842010a8a00f  us-west1  xx.xxx.xxx.xxx TCP          us-west1/targetPools/a4e6a0198d38c11e7889842010a8a00f

locust workerのデプロイ

https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes#deploy-locust-worker

デプロイ&動作確認

$ kubectl apply -f kubernetes-config/locust-worker-controller.yaml --record
replicationcontroller "locust-worker" created

$ kubectl get pods -l name=locust,role=worker -o wide
NAME                  READY     STATUS    RESTARTS   AGE       IP          NODE
locust-worker-9rd4l   1/1       Running   0          16m       10.24.2.9   gke-locust-default-pool-df42c7df-jqbl
locust-worker-b2gf6   1/1       Running   0          16m       10.24.0.6   gke-locust-default-pool-df42c7df-vl4p
locust-worker-h7xqx   1/1       Running   0          16m       10.24.2.7   gke-locust-default-pool-df42c7df-jqbl

kubectl scaleコマンドでpodの数を変更してみる

$ kubectl scale --replicas=4 replicationcontrollers locust-worker
replicationcontroller "locust-worker" scaled

$ kubectl get pods -l name=locust,role=worker -o wide
NAME                  READY     STATUS    RESTARTS   AGE       IP          NODE
locust-worker-9rd4l   1/1       Running   0          16m       10.24.2.9   gke-locust-default-pool-df42c7df-jqbl
locust-worker-b2gf6   1/1       Running   0          16m       10.24.0.6   gke-locust-default-pool-df42c7df-vl4p
locust-worker-h7xqx   1/1       Running   0          16m       10.24.2.7   gke-locust-default-pool-df42c7df-jqbl
locust-worker-s6c0g   1/1       Running   0          16m       10.24.2.8   gke-locust-default-pool-df42c7df-jqbl

firewallの設定

https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes#setup-firewall-rules

k8s-locustという名前で作成。locustのweb画面を閲覧するために8089ポートを許可する

クラスタの各々のノードのNAMEを、

$ kubectl get nodes
NAME                                    STATUS    ROLES     AGE       VERSION
gke-locust-default-pool-df42c7df-jqbl   Ready     <none>    1h        v1.7.8-gke.0
gke-locust-default-pool-df42c7df-vgmd   Ready     <none>    1h        v1.7.8-gke.0
gke-locust-default-pool-df42c7df-vl4p   Ready     <none>    1h        v1.7.8-gke.0

--target-tags引数に設定する

$ gcloud compute firewall-rules create k8s-locust --allow=tcp:8089 --target-tags gke-locust-default-pool-df42c7df-jqbl,gke-locust-default-pool-df42c7df-vgmd,gke-locust-default-pool-df42c7df-vl4p
Creating firewall...|Created [https://www.googleapis.com/compute/v1/projects/test-12345/global/firewalls/k8s-locust].         
Creating firewall...done.                                                                                                      
NAME        NETWORK  DIRECTION  PRIORITY  ALLOW     DENY
k8s-locust  default  INGRESS    1000      tcp:8089

locustを試す

作成したロードバランサのエンドポイント(xx.xxx.xxx.xxx:8089)にアクセスすると

Screenshot-2017-11-28 Locust.png

web画面が表示されるので、適当に数値を入力して
Start swarmingをクリックすると負荷テストが始まる

dist-load-testing-locust-web-interface-swarming.png

locustはpythonで負荷テストのシナリオを記述できるらしい

実際./docker-image/locust-tasks/tasks.pyをみると

./docker-image/locust-tasks/tasks.py(一部抜粋)
  _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()})

/login/metricsにリクエストを送ってるような記述がある

クラスタの削除

https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes#deployment-cleanup

$ gcloud container clusters delete locust

$ gcloud compute forwarding-rules delete a4e6a0198d38c11e7889842010a8a00f

$ gcloud compute firewall-rules delete k8s-locust

感想

  • 作成したら数百円くらいかかった(1週間位ロードバランサーを消すのを忘れたせいかもしれない。。。)

節約したければクラスタ作成時にgcloud container clusters createコマンドに
--machine-type引数を指定して、マシンタイプをf1-microにするとか(デフォルトはn1-standard-1)
--num-nodes引数を指定して、ノードの台数を減らすとかしてみるといいかもしれない(デフォルトは3)

  • AWSでkunernetesクラスタ作成するのに比べてとても簡単でした

参考