HeapsterでKubernetesを使わないDockerコンテナのリソース監視


はじめに

前回、cAdvisorのInfluxDB連携機能を試しましたが、やはりHeapsterも試してみます。
前回はcAdvisorが直接InfluxDBにデータを入れたが、Heapsterを使う場合、HeapsterがcAdvisorのAPIを呼び、HeapsterがInfluxDBにデータを入れるという形になる。

そのため、Heapsterは監視対象のサーバーを知っている必要がある。ドキュメントには書かれていないが、ソースを見るとこの方法は3つ用意されている。

  • Kubernetesから取得
  • CoreOSのFleetから取得
  • 設定ファイルから取得

今回はKubernetesもCoreOSも使わない環境を想定しているので、3番目の設定ファイルから取得を試してみる。Kubernetesを使わないのにHeapsterを使う需要はないかもしれませんが…

※なお、これも3月中旬に試した時の内容です。

設定ファイルから取得する設定を調べる

ドキュメントには設定方法は記載されていないのでソースを読む。

external_hosts_fileオプションで指定したファイルにホストリストを設定する。デフォルトは/var/run/heapster/hostsである。設定ファイルはJSONで、構造はExternalNodeList型で定義されている。(sources/nodes/external.go#L48
設定ファイルでの設定を有効にするには、kubernetes_masterおよびcoreosオプションに何も指定しなければよい。(sources/types.go#L34sources/kube.go#L40

以下がExternalNodeList型(sources/api/types.go#L53

// An external node represents a host which is running cadvisor. Heapster will expect
// data in this format via its external files API.
type ExternalNode struct {
    Name string `json:"name,omitempty"`
    IP   string `json:"ip,omitempty"`
}

// ExternalNodeList represents a list of all hosts that are running cadvisor which heapster will monitor.
type ExternalNodeList struct {
    Items []ExternalNode `json:"items,omitempty"`
}

つまり、以下のようなJSONファイルにすればよい。
参考:Goのjson.Marshal/Unmarshalの仕様を整理してみる - I Will Survive

{
  "items": [
    {"name":"hostA", "ip":"x.x.x.x"},
    {"name":"hostB", "ip":"x.x.x.x"}
  ]
}

Heapsterセットアップ手順

設定方法がわかったので、前回と同じ3台構成でセットアップしていく。

  1. Heapster, influxDB, Grafana
  2. Dockerホスト、cAdvisor(2台)

前回の記事で作った環境を下敷きにしているので、細かいところは前回の記事を参照してください。

cAdvisorの起動方法を変更

先にcAdvisorの設定を変更して、InfluxDBと連携しないようにします。
前のcAdvisorコンテナは停止してください。
その後、新しくオプションを変更してcAdvisorを起動します。

$ sudo docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:rw \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  --privileged \
  google/cadvisor:latest \
  --log_dir=/

Heapsterをインストール

Heapsterはインストールパッケージが提供されていません。Dockerコンテナはあるのですが、Dockerコンテナを監視するツールをDockerで動かしてもしょうがない気がするので、ソースからビルドしてみます。

Goのインストール

インストール手順は公式ドキュメントの通りです。

Downloads - The Go Programming Languageから最新のパッケージのURLを確認して以下のようにコマンドを実行します。

$ wget https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.4.2.linux-amd64.tar.gz

/etc/profileに以下を書き加えてしまいます。

export PATH=$PATH:/usr/local/go/bin

/etc/profileを反映して、確認します。

$ source /etc/profile
$ go version
go version go1.4.2 linux/amd64

sudoしたときもPATHが通るようにしておきます。

$ sudo visudo

以下を追加し、

Defaults    env_keep +=  "PATH"

以下をコメントアウト

# Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

Godepのインストール

Heapsterはビルドにgodepを使っているので、godepを入れます。

$ sudo yum -y install git
$ cd /opt
$ sudo GOPATH=/opt/godep go get github.com/tools/godep
$ sudo ln -s /opt/godep/bin/godep /usr/local/bin/

Heapsterのインストール

$ sudo yum -y install mercurial
$ sudo GOPATH=/opt/godep go get github.com/GoogleCloudPlatform/heapster
$ cd /opt/godep/src/github.com/GoogleCloudPlatform/heapster
$ sudo GOPATH=/opt/godep godep get
$ sudo ln -s /opt/godep/bin/heapster /usr/local/bin/

Heapsterの設定

/var/run/heapster/hostsを設定します。

$ sudo mkdir /var/run/heapster
$ sudo /var/run/heapster/hosts

/var/run/heapster/hostsを設定します。
IPアドレスは環境に合わせて設定してください。

{
  "items": [
    {"name":"cAdvisor1", "ip":"172.30.0.104"},
    {"name":"cAdvisor2", "ip":"172.30.0.105"}
  ]
}

Heapster起動

Heapsterを起動する前に保存先のInfluxDBのデータベースを作成します。デフォルトはk8sというDB名なのでそれで作成してください。
作成したら、Heapsterを以下のコマンドで起動します。

$ sudo heapster --sink influxdb

InfluxDBをデフォルトで設定したままなら他の設定は不要ですが、必要に応じて設定してください。(sinks/external.go#L28

オプション デフォルト値 説明
sink_influxdb_username root InfluxDB username
sink_influxdb_password root InfluxDB password
sink_influxdb_host localhost:8086 InfluxDB host:port
sink_influxdb_name k8s Influxdb database name
sink_influxdb_no_columns false When true, prefixes metric series names with metadata instead of storing metadata in additional columns. Metadata includes hostname, container name, etc.

確認

InfluxDBで確認

k8sデータベースでlist seriesを実行し、どんなseriesが作られているか確認します。

以下のseriesが作成されていました。cAdvisorでは一つのseriesにカラムで分けられていましたが、Heapsterではseriesで分けて入れるようです。

  • cpu/usage_ns_cumulative
  • memory/page_faults_gauge
  • memory/usage_bytes_gauge
  • memory/working_set_bytes_gauge
  • network/rx_bytes_cumulative
  • network/rx_errors_cumulative
  • network/tx_bytes_cumulative
  • network/tx_errors_cumulative
  • uptime_ms_cumulative

試しにselect * from "memory/usage_bytes_gauge" limit 10と実行すると以下のようなデータが取得できます。

どのseriesでもカラムは同じです。わかりやすいです。

Grafanaで確認

/opt/grafana-1.9.1/config.jsk8sデータベースを追加します。

      datasources: {
        k8s: {
          type: 'influxdb',
          url: "http://<IPアドレス>:8086/db/k8s",
          username: 'root',
          password: 'root',
        },
        test: {
          type: 'influxdb',
          url: "http://<IPアドレス>:8086/db/test",
          username: 'root',
          password: 'root',
        },
        cadvisor: {
          type: 'influxdb',
          url: "http://<IPアドレス>:8086/db/cadvisor",
          username: 'root',
          password: 'root',
        },
        grafana: {
          type: 'influxdb',
          url: "http://<IPアドレス>:8086/db/grafana",
          username: 'root',
          password: 'root',
          grafanaDB: true
        },
      },

HeapsterのリポジトリにGrafana用のダッシュボード設定例があったので、これを読み込んでみます。
grafana/kubernetes-dashboard.jsonをダウンロードします。

右上の「ファイルを開くアイコン」>「Import」からダウンロードしたJSONを選択すると、読み込まれ以下のように表示されます。

例えばCPU usageの方は以下のような設定になっています。

クエリは以下です。

select container_name, derivative(value) from "cpu/usage_ns_cumulative" where $timeFilter group by time($interval), container_name order asc

しかし、なんかCPU使用率がまともに表示されないと思ったら、変な値が入っています。累計のCPU使用時間のはずなのに3桁変わるレベルで変動しているし、減ったりしている。

謎です。面倒なので深堀りはせずここで終わります。

おわりに

当然なのかもしれませんが、KubernetesかCoreOSを使わない場合はHeapsterを使うメリットはないのではない気がします。前回のcAdvisorから直接InfluxDBに入れるのでよいと思います。

よかったら前回の記事もご覧ください。
cAdvisor, InfluxDB, GrafanaでDockerコンテナのリソース監視 - Qiita