監視体制の準備
サーバー運用といえばまず監視である(?)。Kubernetesクラスタを立ち上げる前に、まずRaspberry Piの監視体制を組んでみることにした。
構成については『ラズパイk8s用の監視システム(Node Exporter + Prometheus + InfluxDB + Grafana)』を参考にした。ダッシュボードはインターネットからアクセスしたいが、インターネットからLANへのアクセスは可能な限りしたくないということで、InfluxDBとGrafanaは元から契約していたVPS上に構築することにした。
参考記事の公開が2020年なのだが、それからInfluxDB 2.0がリリースされたようで、ここでPrometheusのRemote Write APIのサポートが削除されている。代わりにTelegrafにPrometheus write parserが実装されているので、今回は"Prometheus → Telegraf → InfluxDB → Grafana"という構成を取ることにする。
Docker Composeで監視コンポーネントを動かす準備
VPS上ではDockerが動かせる状態になっているので、Composeを使うことにした。次のようなdocker-compose.yml
を用意した。
version: '3'
services:
influxdb:
image: influxdb:2.2
expose:
- 8086
volumes:
- influxdb2:/var/lib/influxdb2
networks:
- influxdb
telegraf:
image: telegraf:1.22
expose:
- 8080
volumes:
- ./telegraf.conf:/etc/telegraf/telegraf.conf:ro
networks:
- influxdb
- telegraf
grafana:
image: grafana/grafana
expose:
- 3000
volumes:
- grafana-storage:/var/lib/grafana
networks:
- grafana
- telegraf
volumes:
influxdb2:
external: true
grafana-storage:
external: true
networks:
influxdb:
external: true
grafana:
external: true
telegraf:
external: true
ボリュームやネットワークはexternalにしてあるので先に作っておく。
$ docker volume create influxdb2
$ docker volume create grafana-storage
$ docker network create influxdb
$ docker network create grafana
$ docker network create telegraf
Telegrafの設定
Telegrafだけは設定ファイルを作っておく必要がある。
前述の通りInfluxDB 2.0でPrometheus Remote Write APIのサポートがなくなってしまったが、InfluxDataがPrometheus Remote Write Support with InfluxDB 2.0という記事を公開している。この記事にある通り、次の3つのプラグインを使ってPrometheus Remote Writeに対応する。
- HTTP Listener v2 Input Plugin
- Prometheus Remote Write Parser
- InfluxDB v2 Output Plugin
ちなみにプラグインといっても同梱されているものなので、設定さえ書いておけば使える状態になっている。
HTTP Listener v2 Input Pluginが入力を担当する。Prometheus Remote WriteはHTTPでAPIを呼び出すので、その受け口となるプラグインである。その中身を解釈するのがPrometheus Remote Write Parserである。そして解釈されたデータをInfluxDBに送るのがInfluxDB v2 Output Plugin、という構成になっている。
docker-compose.yml
と同じディレクトリに以下の内容のtelegraf.conf
を作る。
[[inputs.http_listener_v2]]
service_address = ":8080"
paths = ["/telegraf"]
data_format = "prometheusremotewrite"
[[outputs.influxdb_v2]]
urls = ["http://influxdb:8086"]
token = "$INFLUX_TOKEN"
organization = "$INFLUX_ORG"
bucket = "$INFLUX_BUCKET"
まずHTTP Listener v2 Input Pluginの設定だが、service_address
にプラグインが待ち受けるポートを指定する。docker-compose.yml
でexpose
に指定したポート番号と一致させる。パスは今回/telegraf
としているが、これは任意に決めてよい。data_format = prometheusremotewrite
とすることでPrometheus Remote Write Parserが有効になる。
次にInfluxDB v2 Output Pluginの設定である。urls
にはdocker-compose.yml
のサービス名でInfluxDBのインスタンスを指定する(同一のComposeプロジェクト内で同じネットワークに属するのでサービス名で名前解決ができる)。organization
, bucket
については後ほどInfluxDBの初期設定で作成する値を指定しておく。また、token
についても初期設定後にInfluxDBのUIから作成するので仮置きする(とりあえず指定がおかしくてもリクエストに失敗するだけで起動はするはず)。
https-portalの設定と起動
他のアプリケーションでhttps-portalを使っているので、これを流用することにした。そのため、ポートはホストにバインドせず単にexposeするだけにしている。networks
に指定したネットワークでhttps-portalのコンテナと接続する。また、DNS設定で適当なサブドメインをInfluxDBとGrafanaにアクセスするために割り当てる。以上の準備をした上で、https-portal側のdocker-compose.ymlを抜粋するとこんな感じになる。
services:
web:
image: steveltn/https-portal
# ...
networks:
- influxdb
- grafana
- telegraf
environment:
DOMAINS: influxdb.example.com -> http://influxdbgrafana_influxdb_1:8086, grafana.example.com -> http://influxdbgrafana_grafana_1:3000, telegraf.example.com -> http://influxdbgrafana_telegraf_1:8080
これでhttps-portalを再起動する。
InfluxDBの設定
https-portalが正常に起動した後、ブラウザからInfluxDBにアクセスすると初期設定が始まる。最近はCTログからドメインを特定するらしく、どこにも公開してないのにあっという間にいろいろな楽しいリクエストが飛んでくるようになるので、早めに初期設定しておこう。もしくは一時的にポートをホストにバインドしてローカルからアクセスして初期設定をするとか、docker exec
でCLIからやってもよいと思う。Docker Hubのinfluxdbのページも参考になるだろう。
初期設定した後にリロードするとダッシュボードが表示される。最初に"Data"が選択されていると思うが、この右端に"API Tokens"というタブがある。このタブを選択して"Generate API Token"をクリックして"Read/Write API Token"を選択、後は書き込み対象のバケットを選択するとAPIトークンが生成される。トークン一覧から今作成したトークンをクリックすればAPIトークンの値を確認できるので、この値をtelegraf.conf
に転記する。
Prometheusの準備
全ノードにnode_exporterをインストール、マスターノードにのみprometheusをインストールする。また、Raspberry Pi特有のメトリクスを公開してくれるraspberrypi_exporterも導入する。
$ sudo apt install prometheus-node-exporter
$ sudo apt install prometheus
$ curl -fsSL "https://raw.githubusercontent.com/fahlke/raspberrypi_exporter/master/installer.sh" | sudo bash
/etc/prometheus/prometheus.yml
が設定ファイルである。まずサンプルが入っているので、適当に弄っていく。
scrape_interval
が15秒になってたりするが、そんなに細かく取得してくれなくてよいのでデフォルトとされる1分に戻す。evaulation_interval
も同様external_labels
でmonitor=mykube
といった感じで適当な名前を振っておくstatic_configs
以下- prometheusそのものをscrapeする設定が入っているが、
localhost:9090
ではなくてノード名(kube-0.local
)で指定する - node_exporterからscrapeする設定を書く
- prometheusそのものをscrapeする設定が入っているが、
metric_relabel_configs
で、node_name
にノード名を付与するinstance
から適当に抜き出すだけだが、気持ちと見た目の問題が大きい- ちなみに
metric_*
じゃないrelabel_configs
だと動かなかった(これで何日も潰した)
global:
scrape_interval: 1m
evaluation_interval: 1m
external_labels:
monitor: 'mykube'
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['kube-0.local:9090']
metric_relabel_configs:
- source_labels: ["instance"]
regex: '([^:]+):.+'
replacement: $1
target_label: node_name
- job_name: node
static_configs:
- targets:
- 'kube-0.local:9100'
- 'kube-1.local:9100'
- 'kube-2.local:9100'
metric_relabel_configs:
- source_labels: ["instance"]
regex: '([^:]+):.+'
replacement: $1
target_label: node_name
remote_write:
- url: "https://telegraf.example.com/telegraf"
設定が済んだらreloadさせる。
$ sudo systemctl reload prometheus
raspberrypi_exporterは定期的にシェルスクリプトを実行して /var/lib/node_exporter/textfile_collector/raspberrypi-metrics.prom
にPrometheusのフォーマットで値を書き出すようになっている。これをnode_exporterのTextfile collectorを通して公開する。そのためにはnode_exporterにオプションを渡す必要があるので、/etc/default/prometheus-node-exporter
を修正する。
ARGS="--collector.textfile.directory=/var/lib/node_exporter/textfile_collector"
node_exporterも再起動する。
$ sudo systemctl restart prometheus-node-exporter
しばらく待ってからInfluxDBのUIを見て、node_name
でフィルタをかける。ノード名(.local:9100
が入ってない名前)でフィルタして、_field
で大量の項目が出てきたら成功している。適当なフィールドを選んで"Submit"すればグラフが表示される。このスクリーンショットは3台のロードアベレージを表示させたところである。
Grafanaの設定
https-portalの設定を済ませてブラウザからアクセスする。初期ユーザー・パスワードは admin:admin
と分かりやすいので、こちらも起動したらとりあえずログインしてパスワードを設定しておく。
左下の歯車 (Configuration) から"Data Sources"を選ぶ。“Add data source"のページで対応データソースの一覧が出るので、InfluxDBを選択する。今回はクエリ言語に"Flux"を選択した。URLにInfluxDBのURLを指定するが、今回はコンテナ内通信で完結できるので http://influxdbgrafana_influxdb_1:8086
のようにコンテナ名を指定すればよい。
Fluxを選択した場合は認証にトークンを使うことができる。Telegrafからの送信設定のときと同様にトークンを作成して、“InfluxDB Details"のTokenの項目に入力する。Organizationも埋めたら"Save & Test"を押して、“1 buckets found"の表示が出れば設定完了である。
Grafanaからクエリができるかを確認してみよう。サイドバーの"Explore"を選ぶと、適当なクエリを入力してその場で結果を確認できるページに移る。Fluxについては公式のGet started with Fluxなどを参照してもらうとして、試しにCPU温度をクエリしてみた結果が次の通り。
アラート設定とかは何もしてないけど、とりあえず状態を見られるようになったので今回はここまで。