Docker メトリクスを Prometheus で収集

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

警告

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

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

Docker の設定

Docker デーモンを Prometheus ターゲットとして設定するには、 metrics-address を指定する必要があります。この指定にベストな方法は damon.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 に参加するため、マネージャでは docker swarm init を使い、他のマネージャとワーカ・ノードは docker swarm join を使う。
  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 config
global:
  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 config
global:
  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 config
global:
  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/