ラズパイk8s用の監視システム(Node Exporter + Prometheus + InfluxDB + Grafana)


Raspberry Pi 4でKubernetesクラスターを構築したわけですが、こういったシステムがあると、イケてるダッシュボードを作って監視したくなる修正をもつのがエンジニアという生き物です。

Kubernetesの監視といえば、Prometheus + Grafanaが鉄板ですが、それだけでは面白くないので、独自のコンセプトの元、監視システムを構築してみました。

システム構成

ダッシュボード

コンセプト

  • ダッシュボードはスマホからも見れるようにインターネットに公開する
  • 自宅のLANはインターネットに公開しない
  • CPU温度をモニタリングする
  • 運用コストはなるべく安価にすます

ネットワーク面

自宅のネットワークを公開すると、セキュリティ面で考慮すべき事柄が多くなりため、極力避ける方針です。
普通に構築してしまうと、Prometheusはpull型のモニタリングシステムであることから、 Grafana → Prometheus → 監視対象 となり、どこかでインターネットからLAN内への通信が発生してしまいます。

そこで、今回はPrometheusのremote storage機能を利用し、remote storageにクラウド上に構築したInfluxDBを指定することで、Grafana → Influxdb ← Prometheus というように、インターネットからLANへのアクセスが発生しないように構築しました。

インフラ面

ダッシュボードとInfluxDBはクラウド上に構築する必要があるのですが、なるべく安価にすませつつ、独自ドメインで運用したかったため、禁断のGCP永久無料枠のインスタンスを採用することとしました。
(なぜ禁断かというと、アカウントで1インスタンスしか無料で利用できないので、他で使いたくなると困るため)

ドメインはエンジニアなら誰しもがもっている.devドメインを使い、Let's Encryptの証明書を利用しています。

Prometheus自体は監視対象にアクセスできる場所に構築する必要があるため、普通のご家庭なら何台か余っているRaspberry Pi 3を使いLAN内に構築しました。

詳細

kube-state-metrics

Kubernetesの情報をPrometheusで取得できる形式で出力してくれる、kube-state-metricsをKubernetesクラスター上に構築します。
基本はREADME通りにkubectl applyすれば構築ができるのですが、イメージはarmに対応しているものに変更する必要があります。(Raspberry PiのCPUがarm 32bit v7のため)

やり方は様々あると思いますが、今回は本家をforkし、GitHub Actionsで自分のDocker Hub上にarm用イメージをpushする方式としました。

reireias/kube-state-metrics上のブランチ

arm用のイメージをGitHub Actions(CPUはx86_64)上でビルドするには少しコツがいるので、ご紹介します。
multiarch/qemu-user-staticを利用し、CPU情報をエミュレートすることで、これが実現できます。
workflowの設定は下記のようになります。

.github/workflows/main.yml
name: main

on: [push, pull_request]

jobs:
  main:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: setup docker for arm
        run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
      - name: push image
        run: |
          docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASS }}
          make quay-push
        env:
          GOARCH: arm
          GOARM: 7

Node exporter

Kubernetesの各NodeのCPUやメモリを取得するためにNode exporterを各Nodeに設置します。
arm用のバイナリはReleasesにあるのですが、CPUの温度を取得できるようにするため最新のコードから自分でビルドしています。
(※つい先日1.0.0-rc0のビルドが追加されていたので、そちらでも大丈夫そうです)

# clone
$ git clone https://github.com/prometheus/node_exporter.git

# build for arm
$ GOOS=linux GOARCH=arm GOARM=7 go build

各ノードへの配置は下記リポジトリ内のnode-exporterというroleにまとめています。

Prometheus

Prometheusはarm用のバイナリがGitHubのReleasesから配布されているので、それをそのまま利用します。
こちらもAnsibleのroleとして作成しています。
reireias/raspberrypi-ansible - roles/prometheus

Prometheus用の設定ファイルは下記のように設定しています。

  • node exporter用とkubernetes用のjobを設定
  • node exporterはlabelの関係で3台それぞれを定義
  • remote strage設定にInfluxDBのエンドポイントを指定
roles/prometheus/templates/prometheus.yml
global:
  scrape_interval:     60s # By default, scrape targets every 15 seconds.
  evaluation_interval: 60s # By default, scrape targets every 15 seconds.
  external_labels:
      monitor: 'pikube'

rule_files:
  # - "first.rules"
  # - "second.rules"
scrape_configs:
  - job_name: 'prometheus'

    static_configs:
      - targets: ['localhost:9090']

  - job_name: node
    static_configs:
      # node exporterその1
      - targets:
        - 192.168.99.100:9100
        labels:
          node_name: pikube01
      # node exporterその2
      - targets:
        - 192.168.99.101:9100
        labels:
          node_name: pikube02
      # node exporterその3
      - targets:
        - 192.168.99.102:9100
        labels:
          node_name: pikube03
  # kube-state-metrics
  - job_name: kubernetes
    static_configs:
      - targets:
        - 192.168.99.200:8080
# remote storageの設定
remote_write:
  - url: 'https://{{ influxdb_domain }}/api/v1/prom/write?db=prometheus&u={{ influxdb_user }}&p={{ influxdb_pass }}'
remote_read:
  - url: 'https://{{ influxdb_domain }}/api/v1/prom/read?db=prometheus&u={{ influxdb_user }}&p={{ influxdb_pass }}'

InfluxDB + Grafana on GCE

GCP上に永久無料枠で構築したGCEインスタンスに、InfluxDBとGrafanaを構築しています。
InfluxDBは一言で説明するなら、時系列データに特化したDBです。

また、当然アクセスはSSLで行うので、Nginxを配置し、Let's Encryptによる証明書を取得し、設置しています。
Let's Encryptの証明書は3ヶ月と期間が短いので、自動更新もcronで設定しています。

GrafanaはGUIで設定しています。
データソースにInfluxDBを指定可能なので、これを指定してダッシュボードを作成しています。
InfluxDBは時系列データに特化したDBですが、SQL文はわりと普通に書けるので、そんなに詰まる部分はありませんでした。

それらをAnsibleで構築したものがこちらです。

GCPの永久無料枠でのGCEインスタンス構築は、下記記事を参考にさせていただきました。
GCPで永久無料枠を利用してサービスを立ち上げたときにしたことの備忘録

まとめ

イケてるダッシュボードが作れた!
これで外出時でも自宅のKubernetesクラスターの監視ができるようになった。(するとは言っていない)