Docker環境のコンテナのパフォーマンス測定

# はじめに

本記事では、Docker上のコンテナで稼働するアプリケーションの負荷テストと耐久テストに使用した構成および測定ツールについて説明します。

## 目的

ストリーム処理アプリケーションについて以下の2点を確認することを目的とします。

1. 同一のDocker環境内の複数コンテナで構成されたアプリケーションのメトリクス計測ができること。（EKSやAKSではContainer Insights等が同様の機能を提供していますが、Dockerの場合は個別に構成する必要があります）
2. 入力ストリームデータに対して一定時間継続して測定ができること。

## 構成

今回測定対象としたアプリケーションの構成は以下の通りです。赤い点線で囲まれた部分が測定の対象です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1590551/b8e7a3ec-acca-d417-31dc-2878c2e669c1.png)

`docker stats` でコンテナの状態を確認します。これでも簡易的に確認できますが、継続的な監視には不向きです。

```bash
docker stats

CONTAINER ID   NAME                              CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
e87352cf4466   vantiq_ai_assistant               0.15%     306.8MiB / 15.43GiB   1.94%     35.5GB / 25.6GB   0B / 602kB        9
5fbb4631d1a9   vantiq-edge-vantiq_edge-1         1.98%     4.234GiB / 15.43GiB   27.44%    35.5GB / 25.6GB   14.8MB / 2.9GB    101
f3cef740f793   nginx-proxy                       0.13%     41.52MiB / 15.43GiB   0.26%     12.7GB / 14.1GB   4.61MB / 2.09MB   26
b5208d83c078   vantiq_edge_qdrant                0.06%     27.98MiB / 15.43GiB   0.18%     11.5MB / 6.33MB   2.18MB / 127kB    23
69ccdf3ecdc8   vantiq-edge-vantiq_edge_mongo-1   0.74%     1.403GiB / 15.43GiB   9.09%     15.7GB / 33.1GB   216MB / 169GB     45
ef5006bfc0fa   postgreSQL                        0.02%     17.36MiB / 15.43GiB   0.11%     3.15kB / 582B     6.27MB / 36.9kB   7
c6f575a05629   mongo                             0.38%     990.9MiB / 15.43GiB   6.27%     2GB / 91.4MB      6.72MB / 13.7GB   42
57e86586fcfb   cadvisor                          10.12%    53.58MiB / 15.43GiB   0.34%     374MB / 8.29GB    30.9MB / 1.15MB   40
```

測定ツールを含めた構成は以下のようになります。これ以降の説明は、Machine #2にDocker環境が構築されていること、およびネットワークの構成にアクセス制限がないことを前提としています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1590551/7a41545b-506a-e33a-c032-53f25a8e470d.png)



### 使用したツール
詳細は公式のページや他の記事を参考にしてください。

- cAdvisor: コンテナリソース使用状況の収集ツール
- Prometheus: システム監視・アラートのためのツール
- Grafana: データの視覚化を提供

### 構成手順

1. cAdvisor の構成

    Machine #1にてcAdvisorを構成します。以下のコマンドを実行してください。公式ページのサンプルではportは8080になっていますが、対象アプリがすでに使用しているため、8000にしています。
    
    ```bash
    sudo docker run \
      --volume=/:/rootfs:ro \
      --volume=/var/run:/var/run:ro \
      --volume=/sys:/sys:ro \
      --volume=/var/lib/docker/:/var/lib/docker:ro \
      --volume=/dev/disk/:/dev/disk:ro \
      --publish=8000:8080 \
      --detach=true \
      --name=cadvisor \
      --privileged \
      --device=/dev/kmsg \
      gcr.io/cadvisor/cadvisor:latest
    ```
    
      cAdvisorの稼働を確認を確認するため、ブラウザを開き、`http://<machine #1 host>:8000`にアクセスします。
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1590551/f6639248-67e9-2a50-6158-c8895bb4513e.png)


2. prometheusを構成

    Machine #2でPrometheusを構成します。PrometheusがcAdvisorからメトリクスデータを取得するように、必要な設定ファイルを作成します。
    
    ```yaml:~/prometheus-data/prometheus.yml
    global:
      scrape_interval:     10s
    
    scrape_configs:
      - job_name: 'cadvisor'
        static_configs:
        - targets:
          - '<machine #1 host>:8000'
    ```
    Machine #2のDocker上でPrometheusを開始します。前ステップで作成した設定ファイルをパラメータとして指定します。
    
    ```bash
    docker run -p 9090:9090 -v ~/prometheus-data:/prometheus-data prom/prometheus --config.file=/prometheus-data/prometheus.yml
    ```
    `http://<machine #2 host>:9090` にアクセスすると、Prometheusが確認できます。
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1590551/6070ac8a-9a58-fc9b-6e53-86cea06b0001.png)


3. Grafanaを構成

    Machine #2のDocker上でGrafanaを開始します。
    
    ```bash
    docker run -d -p 3000:3000 grafana/grafana
    ```
    `http://<machine #2 host>:3000` にアクセスし、Grafanaの稼働を確認します。admin/adminでログインします。
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1590551/08961256-56bd-a7d5-c0f4-c27d0ec4d99a.png)
     
    メニューからConnection >> Data Sourcesと進み、”+ Add new data source”をクリックし、Prometheusを選択します。前ステップで作成したPrometheusを参照できるように構成します。
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1590551/55efb53f-bfa5-5963-80a6-f6af9edd0746.png)
     
    Prometheus server URL に `http://<machine #2>:9090`を指定します。“Save and Test”で接続が成功することを確認します。
    
    :::note warn
    machine #2をlocalhostや127.0.0.1にすると接続できません。
:::

メニューからDashboardと進み、”New”をクリックし、”Import”を選択します。以下の設定を行います。

1. Dashboardを[grafana_dashboard](https://github.com/vegasbrianc/grafana_dashboard)から取得し、インポートします。 JSONでインポートします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1590551/e1f35a82-44e6-9926-9211-c566f6aa5e7b.png)

1. データソースを指定します。Prometheusに対して、前ステップで作成したPrometheusを指定します
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1590551/6ed48fcc-dd7c-f33c-fd02-8300a1264449.png)

 

Dashboardが表示されれば成功です。今回の目的に関して、ストリーム処理を実行している間CPUとメモリが安定して推移していることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1590551/60336adb-afaf-0edd-7a05-d02f8c69cf0e.png)


# まとめ

複数のコンテナで構成した既存のアプリケーションに対して、負荷測定を追加する仕組みを構築しました。

# 参照したリンク

- [cAdvisorのメトリックをPrometheusに格納してGrafanaで確認](https://qiita.com/ryojsb/items/ac790241b45c3fbcdd16)
- [cAdvisor GitHubリポジトリ](https://github.com/google/cadvisor)
- [Prometheus Installation](https://prometheus.io/docs/prometheus/latest/installation/)
- [Grafana 公式サイト](https://grafana.com/)