cAdvisor?
cAdvisor(Container Advisor)は、稼働中のコンテナのリソース使用量や、パフォーマンス特性を提供してくれるものです。
【Docker】cAdvisorによるDockerコンテナの監視について - Qiita
あるホストで稼働する以下の情報をコンテナごとに取得し、エクスポートしてくれます。
- リソースごとのパラメーター
- リソース使用量のヒストグラム
- ネットワーク統計情報
ちなみに、KubernetesではkubeletにcAdvisorが統合、導入されているようです。
マシン内のすべてのコンテナを検出し、CPU、メモリ、ファイルシステム、ネットワーク使用量の統計を収集してくれますと。
さらにはマシン全体も、と。
Kubernetesに、Kustomizeを使ってDaemonSetとしてデプロイする例もあります。
https://github.com/google/cadvisor/tree/v0.33.0/deploy/kubernetes
使ってみる
とまあ、なんとなくcAdvisorの役割を見たところで、動かしてみましょう。
Quick Startの通り、Dockerコンテナを使って動かすようです。
Quick Start: Running cAdvisor in a Docker Container
実行するOS(CentOS、Fedora、RHEL、Debian)によっては注意事項があったりするようなので、必要に応じてこちらを参照しましょう。
https://github.com/google/cadvisor/blob/v0.33.0/docs/running.md
設定項目はこちら。今回は、特に指定せずにいきます。
https://github.com/google/cadvisor/blob/v0.33.0/docs/runtime_options.md
環境は、こちらを使います。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.2 LTS Release: 18.04 Codename: bionic $ docker version Client: Version: 18.09.4 API version: 1.39 Go version: go1.10.8 Git commit: d14af54266 Built: Wed Mar 27 18:35:44 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 18.09.4 API version: 1.39 (minimum version 1.12) Go version: go1.10.8 Git commit: d14af54 Built: Wed Mar 27 18:01:48 2019 OS/Arch: linux/amd64 Experimental: false
Quick Startに起動例が書かれていますが、ホスト側へのポートバインドやlatestタグの使用はやめて、こんな感じで利用。
$ docker run -it --rm \ --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 \ --name=cadvisor \ google/cadvisor:v0.33.0
バージョンは、v0.33.0とします。
「http://[cAdvisorのIPアドレス]:8080」にアクセスすると、cAdvisorのWeb UIを見ることができます。
参考)
なお、REST APIもある模様。
https://github.com/google/cadvisor/blob/v0.33.0/docs/api_v2.md
この状態だと、ホスト側の情報を見ることができるようです。ページをスクロースさせて下の方に行くと、プロセスの一覧や
CPU、メモリ、ネットワーク、ファイルシステムの状態を見ることができます。
では、他のコンテナを立ててみましょう。
せっかくなので、少しわかりやすいように簡単なサーバーと負荷をかけるツールを動かすコンテナを作ってみます。
次の2つのコンテナを作成します。
- 簡単なSpring Bootアプリケーションを動かすコンテナ(172.17.0.3)
- Locustで負荷をかけるコンテナ(172.17.0.4)
最初に、サーバー側。
$ sdk install springboot 2.1.3.RELEASE
こんな感じの簡単なRestControllerを用意。なんとなく、パラメーターを受け取るようにしています。
server.groovy
@RestController public class SimpleController { @GetMapping('/') public index(@RequestParam('id') id) { id } }
Uber JARにします。
$ spring jar server.jar server.groovy
OpenJDK 8のイメージを使って、アプリケーションを起動。CPUは絞っておきます。
$ docker container run -it --rm --name server -v `pwd`:/host --cpuset-cpus=0,1 openjdk:8-jdk-slim bash # java -jar /host/server.jar
続いて、Locust。
まず、シナリオを用意。 locustfile.py
from locust import HttpLocust, TaskSet, task import uuid class WebAccess(TaskSet): @task def index(self): id = uuid.uuid4() with self.client.get("/?id=" + str(id), catch_response = True) as response: if response.status_code != 200: response.failure("request failed!!") class WebAccessUser(HttpLocust): task_set = WebAccess min_wait = 300 max_wait = 500
Python 3.7のイメージを使って、環境を用意。
$ $ docker container run -it --rm --name locust -v `pwd`/locustfile.py:/tmp/locustfile.py --cpuset-cpus=2,3 python:3.7 bash # pip3 install locustio
ここで、cAdvisorのWeb UIの「Docker Containers」リンクを押すと、現在のコンテナの一覧を見ることができます。
コンテナ名をクリックすると、コンテナ単位に情報(CPUやメモリなども)を見ることができます。
では、負荷をかけてみましょう。
# locust -f /tmp/locustfile.py --host=http://172.17.0.3:8080 --no-web -c 200 -r 20 -t 180
各コンテナのページを見ると、リソースの使用状況が変化していく様子を確認することができます。
なんとなく、確認できた気がします。
Prometheusにメトリクスをエクスポートする
cAdvisorは、Storage Driver Pluginとして情報をエクスポートする仕組みがあるようです。
https://github.com/google/cadvisor/blob/v0.33.0/docs/storage/README.md
Prometheus向けのものがあるようですので、こちらを使ってみましょう。
https://github.com/google/cadvisor/blob/v0.33.0/docs/storage/prometheus.md
設定ファイルは、こんな感じで用意。 prometheus.yml
global: scrape_interval: 3s evaluation_interval: 3s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: "cadvisor" static_configs: - targets: ["172.17.0.2:8080"]
この設定ファイルを使って、Prometheusのコンテナを起動します。
$ docker container run -it --rm --name prometheus -v `pwd`/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus:v2.8.1
ちなみに、cAdvisorのPrometheus向けのエンドポイントは、「/metrics」のようですよ。設定で変更することもできるようです。
CPUに関する情報を見てみます。
$ curl -s 172.17.0.2:8080/metrics | grep cpu | grep -E 'server|locust' container_cpu_load_average_10s{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 0 1554127322988 container_cpu_load_average_10s{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 0 1554127321610 container_cpu_system_seconds_total{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 10.18 1554127322988 container_cpu_system_seconds_total{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 5.06 1554127321610 container_cpu_usage_seconds_total{container_label_maintainer="",cpu="cpu00",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 21.025954446 1554127321610 container_cpu_usage_seconds_total{container_label_maintainer="",cpu="cpu01",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 18.710983788 1554127321610 container_cpu_usage_seconds_total{container_label_maintainer="",cpu="cpu02",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 66.183811872 1554127322988 container_cpu_usage_seconds_total{container_label_maintainer="",cpu="cpu02",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 0.256701358 1554127321610 container_cpu_usage_seconds_total{container_label_maintainer="",cpu="cpu03",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 165.403016329 1554127322988 container_cpu_usage_seconds_total{container_label_maintainer="",cpu="cpu03",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 0.610232295 1554127321610 container_cpu_usage_seconds_total{container_label_maintainer="",cpu="cpu05",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 0.000928385 1554127321610 container_cpu_user_seconds_total{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 221.28 1554127322988 container_cpu_user_seconds_total{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 34.14 1554127321610 container_spec_cpu_period{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 100000 container_spec_cpu_period{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 100000 container_spec_cpu_shares{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 1024 container_spec_cpu_shares{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 1024
PrometheusのWeb UIでも見てみましょう。
「CPU使用率」、みたいな感じでは得られないみたいですね。計算する必要があるようです。
Average CPU % usage per container · Issue #2026 · google/cadvisor · GitHub
とすると、cAdvisorのWeb UIではコンテナ内のプロセスに対してCPU使用率が表示されていたのでは?と思うのですが、
こちらは自前で計算しているみたいですね。
https://github.com/google/cadvisor/blob/v0.33.0/pages/assets/js/containers.js#L369-L370
なるほど…。
メモリもちらっと。
$ curl -s 172.17.0.2:8080/metrics | grep memory | grep -E 'server|locust' container_memory_cache{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 6.2480384e+07 1554128366591 container_memory_cache{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 32768 1554128366572 container_memory_failcnt{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 0 1554128366591 container_memory_failcnt{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 0 1554128366572 container_memory_failures_total{container_label_maintainer="",failure_type="pgfault",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust",scope="container"} 185466 1554128366591 container_memory_failures_total{container_label_maintainer="",failure_type="pgfault",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust",scope="hierarchy"} 185466 1554128366591 container_memory_failures_total{container_label_maintainer="",failure_type="pgfault",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server",scope="container"} 213939 1554128366572 container_memory_failures_total{container_label_maintainer="",failure_type="pgfault",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server",scope="hierarchy"} 213939 1554128366572 container_memory_failures_total{container_label_maintainer="",failure_type="pgmajfault",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust",scope="container"} 0 1554128366591 container_memory_failures_total{container_label_maintainer="",failure_type="pgmajfault",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust",scope="hierarchy"} 0 1554128366591 container_memory_failures_total{container_label_maintainer="",failure_type="pgmajfault",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server",scope="container"} 0 1554128366572 container_memory_failures_total{container_label_maintainer="",failure_type="pgmajfault",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server",scope="hierarchy"} 0 1554128366572 container_memory_mapped_file{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 2.781184e+06 1554128366591 container_memory_mapped_file{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 32768 1554128366572 container_memory_max_usage_bytes{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 1.9380224e+08 1554128366591 container_memory_max_usage_bytes{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 8.28792832e+08 1554128366572 container_memory_rss{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 6.3279104e+07 1554128366591 container_memory_rss{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 8.22767616e+08 1554128366572 container_memory_swap{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 0 1554128366591 container_memory_swap{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 0 1554128366572 container_memory_usage_bytes{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 1.36892416e+08 1554128366591 container_memory_usage_bytes{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 8.27752448e+08 1554128366572 container_memory_working_set_bytes{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 8.820736e+07 1554128366591 container_memory_working_set_bytes{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 8.2771968e+08 1554128366572 container_spec_memory_limit_bytes{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 0 container_spec_memory_limit_bytes{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 0 container_spec_memory_reservation_limit_bytes{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 0 container_spec_memory_reservation_limit_bytes{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 0 container_spec_memory_swap_limit_bytes{container_label_maintainer="",id="/docker/c6ad0ec76ccf0b4bc8aa3363c21215605269f88d224bf55e2fc8e1568dba7b3a",image="python:3.7",name="locust"} 0 container_spec_memory_swap_limit_bytes{container_label_maintainer="",id="/docker/d8239a9c87003f352da6da885a2687eb93ed7c67428dacbfaec0aba9a5158dda",image="openjdk:8-jdk-slim",name="server"} 0
Web UIでも。