Docker メトリクスを Prometheus で収集

Prometheus はオープンソースのシステム監視と通知ツールキットです。Docker を Prometheus のターゲットに設定できます。このトピックで紹介するのは、Prometheus を Docker コンテナとして実行するようセットアップする方法と、Prometheus を使って Docker そのものを監視します。

警告

利用可能なメトリクスとこれらメトリクス名は、アクティブな開発下にあるため、いつでも変わる可能性があります。

現時点では、Docker 自身のみを監視できます。Docker ターゲットを使ってアプリケーションの監視は現在できません。

Docker の設定

Docker デーモンを Prometheus ターゲットとして設定するには、 metrics-address を指定する必要があります。この指定にベストな方法は daemon.json を経由するもので、デフォルトでそれぞれ以下の場所にあります。もしもファイルが無ければ作成します。

  • Linux, : /etc/docker/daemon.json

  • Windows Server : C:\ProgramData\docker\config\daemon.json

  • Docker Desktop for Mac / Docker Desktop for Windows : ツールバー上の Docker アイコンをクリックし、 Preferences を選び、 Daemon を選び、 Advanced をクリック

もしもファイルが無ければ、以下の内容をペーストします。

{"metrics-addr":"127.0.0.1:9323","experimental":true}

ファイルが空でなければ、これら2つのキーを追加し、結果的に有効な JSON ファイルになることを確認島須。最後の行を除き、各行の最後はカンマ( , )で区切りますので、注意してください。

ファイルを保存します。あるいは Docker Desktop for Mac や Docker Desktop for Windows であれば設定を保存します。それから、Docker を再起動します。

以上で Docker はポート 9323 上で Prometheus 互換のメトリクスを出力します。

Prometheus の設定と実行

Prometheus は Docker Swarm 上の Docker サービスとして実行します。

注釈

事前準備

  1. 1つまたは複数の Docker Engine を Docker swarm に参加するため、マネージャでは dockerswarminit を使い、他のマネージャとワーカ・ノードは dockerswarmjoin を使う。

  2. Prometheus イメージの取得のためには、インターネット接続が必要。

以下の設定ファイルを、(Linux か Mac は) /tmp/prometheus.yml に保存するか、(WIndows は) C:\tmp\prometheus.yml に保存。これは Prometheus 設定ファイルのストックであり、ファイルの末尾に Docker ジョブ定義がなければ追加します。Docker Desktop for Mac と Docker Desktop for Windows の場合は、少々設定ファイルが変わります。

  • Docker for Linux

# my global configglobal:scrape_interval:15s# Set the scrape interval to every 15 seconds. Default is every 1 minute.evaluation_interval:15s# Evaluate rules every 15 seconds. The default is every 1 minute.# scrape_timeout is set to the global default (10s).# Attach these labels to any time series or alerts when communicating with# external systems (federation, remote storage, Alertmanager).external_labels:monitor:'codelab-monitor'# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.rule_files:# - "first.rules"# - "second.rules"# A scrape configuration containing exactly one endpoint to scrape:# Here it's Prometheus itself.scrape_configs:# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.-job_name:'prometheus'# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:-targets:['localhost:9090']-job_name:'docker'# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:-targets:['localhost:9323']
  • Docker Desktop for Mac

# my global configglobal:scrape_interval:15s# Set the scrape interval to every 15 seconds. Default is every 1 minute.evaluation_interval:15s# Evaluate rules every 15 seconds. The default is every 1 minute.# scrape_timeout is set to the global default (10s).# Attach these labels to any time series or alerts when communicating with# external systems (federation, remote storage, Alertmanager).external_labels:monitor:'codelab-monitor'# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.rule_files:# - "first.rules"# - "second.rules"# A scrape configuration containing exactly one endpoint to scrape:# Here it's Prometheus itself.scrape_configs:# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.-job_name:'prometheus'# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:-targets:['host.docker.internal:9090']# Only works on Docker Desktop for Mac-job_name:'docker'# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:-targets:['docker.for.mac.host.internal:9323']
  • Docker Desktop for Windows

# my global configglobal:scrape_interval:15s# Set the scrape interval to every 15 seconds. Default is every 1 minute.evaluation_interval:15s# Evaluate rules every 15 seconds. The default is every 1 minute.# scrape_timeout is set to the global default (10s).# Attach these labels to any time series or alerts when communicating with# external systems (federation, remote storage, Alertmanager).external_labels:monitor:'codelab-monitor'# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.rule_files:# - "first.rules"# - "second.rules"# A scrape configuration containing exactly one endpoint to scrape:# Here it's Prometheus itself.scrape_configs:# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.-job_name:'prometheus'# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:-targets:['host.docker.internal:9090']# Only works on Docker Desktop for Windows-job_name:'docker'# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:-targets:['192.168.65.1:9323']

次は、この設定を使い、レプリカ1つの Prometheus サービスを起動します。

  • Docker for Linux

$ docker service create --replicas 1 --name my-prometheus \ --mount type=bind,source=/tmp/prometheus.yml,destination=/etc/prometheus/prometheus.yml \ --publish published=9090,target=9090,protocol=tcp \ prom/prometheus
  • Docker Desktop for Mac

$ docker service create --replicas 1 --name my-prometheus \ --mount type=bind,source=/tmp/prometheus.yml,destination=/etc/prometheus/prometheus.yml \ --publish published=9090,target=9090,protocol=tcp \ prom/prometheus
  • Docker Desktop for Windows or Windows Server

PS C:\> docker service create --replicas 1 --name my-prometheus --mount type=bind,source=C:/tmp/prometheus.yml,destination=/etc/prometheus/prometheus.yml --publish published=9090,target=9090,protocol=tcp prom/prometheus

Docker ターゲットが http://localhost:9090/targets/ の一覧にあるのを確認します。

もしも Docker Desktop for Mac や Docker Desktop for Windows を使っている場合は、このエンドポイント URL に直接アクセスできません。

Prometheus を使う

グラフを作成します。 Prometheus UI の Graphs のリンクをクリックします。Execute ボタンの右側にあるコンボボックスからメトリックを選択し、 Execute をクリックします。以下のスクリーンショットは、 engine_daemon_network_actions_seconds_count に対するグラフです。

この上のグラフが表すのは、Docker インスタンスが多少アイドル状態です。アクティブな処理を実行中であれば、グラフは異なったものになるでしょう。

グラフをもっと面白くするために、10 タスクを持つサービスを起動し、Docker にノンストップで ping を実行し(ping のターゲットは任意に選べます)ネットワークのアクションを作成しましょう。

$ docker service create \ --replicas 10\ --name ping_service \ alpine ping docker.com

少々待つと(デフォルトでは再読込間隔は 15 秒です)、グラフを再読込します。

準備ができたら、 ping_service の停止と削除をします。ホスト上で ping の洪水を起こしてよい理由はありません。

$ docker service remove ping_service

少々待つと、グラフが元のレベルにまで戻るのが見えるでしょう。

次のステップ

参考

Collect Docker metrics with Prometheus

https://docs.docker.com/config/daemon/systemd/