crashRT のブログ

インフラとwebとデザインと色々

Kea DHCP + Stork でDHCPサーバーを構築して Grafana + Prometheus で監視してみた

DHCPサーバーをKea DHCPで構築し,StorkとGrafana+Prometheusでリースアドレス数などを監視できるようにしました. 以前Dockerを用いてKea DHCPを構築していましたが, 色々試してみるとDockerでの構築はあまり想定されていない使い方のようだったので*1,今回はVMに直接インストールする形で構築しました.

まず全体の構成について簡単に説明します. その後,Kea DHCP と Kea CA をインストールしてDHCPサーバーを構築します. そしてStorkを構築し,最後にStorkから取得できるメトリクスを使ってGrafana・Prometheusでリース数などを可視化します.

構成概要

Kea DHCP, Stork, Grafana, Prometheus と登場人物が多いので関係をまとめておくと,以下の図のようになります*2

3台のVMを使っていて, pavane では Kea DHCP・Kea CA・Stork Agentが,lavalse ではStork Serverが,karelia ではGrafanaとPrometheusが動いています.

Kea DHCPDHCPサーバー本体です.DHCPv4のためのkea-dhcp4とDHCPv6のためのkea-dhcp6があります.今回はIPv4だけ考えます.

Kea Control Agent (Kea CA) というKea DHCPに対するRESTful APIを提供するdaemonです*3. Kea DHCP と同じVMで動作し, unix stream socket を経由して接続します*4

Stork は Kea DHCP を管理するためのwebUIとPrometheus, Grafanaのためのメトリクスを提供するソフトウェアです. StorkにはStork Server と Stork Agent の2つがあります*5Stork Server はKea DHCP などの web UI を提供します.複数台のKea DHCPを一括で管理することもできます. Stork Agent は Kea CA と接続し,Kea DHCPの情報をStork Server へ提供します.

Stork Server と Stork Agent はどちらもメトリクスを取得するためのエンドポイントを提供しています. Prometheus でそれらからメトリクスを取得し蓄積し,Grafana でPrometheusに蓄積された情報を可視化します.

Kea DHCP・Kea CAの構築

以下のドキュメントに従ってインストールします.

kea.readthedocs.io

リポジトリの追加

Kea DHCP・Kea CAのインストール

以下のコマンドでインストールします. インストールすると自動で起動します.

sudo apt update
sudo apt install isc-kea

Kea DHCP の設定

設定ファイルは /etc/kea 配下にあります.

kea-dhcp4.conf の設定の詳細は以下のドキュメントにあります.

kea.readthedocs.io

interfaces-config では使用するインタフェースを設定します.

control-socket はKea CAと接続するための unix socket の設定です.デフォルトのままで良いと思います.

lease-database はリース情報を格納する場所をしています.デフォルトのmemfileのままにしていますが,MySQLとかpostgreSQLとかにしても面白いと思います.

valid-lifetime はリース期間で,renew-timerrebind-timer はリース更新に使われるT1とT2です*6

option-data ではオプションで使う値を設定しています. subnet4 の中の option-data はサブネットごとのオプション(デフォルトゲートウェイなど),subnet4 の外はサブネット共通のオプション(DNSサーバーなど)を設定します.

subnet4 ではDHCPサーバーが管理するサブネットを設定します. subnet でサブネットを指定し,pools で実際に割り当てるアドレスの範囲を指定します. subnet DHCP relay をした場合のサブネットの選択などで使われます*7

Stork でアドレスプールの使用率などを取得するには stats_cmd のhook を有効化する必要があるので hooks-libraries で設定します *8 . hook のライブラリがあるパスはインストール時にデフォルトで登録されているものを参考にすると良いと思います. 僕の環境の場合は /usr/lib/x86_64-linux-gnu/kea/hooks/ 以下にありました. stats_cmd についての詳細は以下のドキュメントにあります.

kea.readthedocs.io

"Dhcp4": {
    "interfaces-config": {
        "interfaces": ["ens18"]
    },
    "control-socket": {
        "socket-type": "unix",
        "socket-name": "/tmp/kea4-ctrl-socket"
    },
    "lease-database": {
        "type": "memfile",
        "lfc-interval": 3600
    },

    "renew-timer": 90,
    "rebind-timer": 180,
    "valid-lifetime": 600,

    "option-data": [
        {
            "name": "domain-name-servers",
            "data": "192.168.11.4"
        },
        {
            "name": "domain-search",
            "data": "home"
        }
    ],
    "subnet4": [
        {
            "id": 1,
            "subnet": "192.168.2.0/24",
            "pools": [ { "pool": "192.168.2.129 - 192.168.2.250" } ],
            "option-data": [
                {
                    "name": "routers",
                    "data": "192.168.2.1"
                }
            ]
        }
    ],

    "hooks-libraries" :[
        {
            "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_stat_cmds.so"
        },
        {
            "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_lease_cmds.so"
        },
    ],
    "loggers": [
    {
        "name": "kea-dhcp4",
        "output-options": [
            {
                "output": "stdout",
                "pattern": "%-5p %m\n",
            }
        ],
        "severity": "INFO",
        "debuglevel": 0
    }
  ]
}
}

Kea CAの設定ファイル kea-ctrl-agent.conf についてはデフォルトの設定をそのまま使用しました. control-sockets については Kea DHCP と一致させる必要があるので変更する場合は注意してください.

"Control-agent": {
    "http-host": "127.0.0.1",
    "http-port": 8000,
    "control-sockets": {
        "dhcp4": {
            "socket-type": "unix",
            "socket-name": "/tmp/kea4-ctrl-socket"
        },
        "dhcp6": {
            "socket-type": "unix",
            "socket-name": "/tmp/kea6-ctrl-socket"
        },
        "d2": {
            "socket-type": "unix",
            "socket-name": "/tmp/kea-ddns-ctrl-socket"
        }
    },

    "loggers": [
    {
        "output-options": [
            {
                "output": "stdout",
                "pattern": "%-5p %m\n"
            }
        ],
        "severity": "INFO",
        "debuglevel": 0
    }
  ]
}
}

設定の反映

設定を反映させるために再起動します. ドキュメントには sudo systemctl enable kea-dhcp4 で再起動できるとありますが*9, 以下のようにそんなサービスはないと言われてしまいました.

crashrt@pavane:~$ sudo systemctl enable kea-dhcp4
Failed to enable unit: Unit file kea-dhcp4.service does not exist.

アドレスは降ってくるので動いてないことはないはずだったので,systemctl list-unit-files を使ってサービス名を調べました.

crashrt@pavane:~$ sudo systemctl list-unit-files -t service | grep kea
isc-kea-ctrl-agent.service                   enabled         enabled
isc-kea-dhcp-ddns-server.service             enabled         enabled
isc-kea-dhcp4-server.service                 enabled         enabled
isc-kea-dhcp6-server.service                 enabled         enabled

正しくは isc-kea-dhcp4-server らしいので,改めて再起動します.

$ sudo systemctl restart isc-kea-dhcp4-server.service

Stork の構築

Stork の構築は以下のドキュメントを参考にしました.

kb.isc.org

Stork Server

新しいVMStork Server をインストールします.

リポジトリを追加し,stork-serverをインストールします.

curl -1sLf 'https://dl.cloudsmith.io/public/isc/stork/cfg/setup/bash.deb.sh' | sudo bash
sudo apt install isc-stork-server

Stork Server はPostgreSQLを使うので準備します.

sudo apt install postgresql postgresql-contrib
sudo postgresql-setup --initdb
sudo systemctl start postgresql
sudo systemctl enable postgresql
sudo -u postgres stork-tool db-create --db-name stork --db-user stork-server

systemd で動かして永続化します.

sudo systemctl enable isc-stork-server
sudo systemctl start isc-stork-server
sudo systemctl status isc-stork-server

設定ファイルは /etc/stork/server.env です.

STORK_SERVER_ENABLE_METRICS=true

を設定すると /metrics でメトリクスを取得できるようになります((

STORK_SERVER_ENABLE_METRICS - enable the Prometheus metrics collector and /metrics HTTP endpoint

https://stork.readthedocs.io/en/v2.0.1/install.html#setup )).

Stork Agent

次にKea DHCPが動くVMStork Agent をインストールします.

リポジトリを追加し,インストールします.

curl -1sLf 'https://dl.cloudsmith.io/public/isc/stork/cfg/setup/bash.deb.sh' | sudo bash
sudo apt install isc-stork-agent

systemd で起動・永続化します.

sudo systemctl enable isc-stork-agent
sudo systemctl start isc-stork-agent
sudo systemctl status isc-stork-agent

8080番ポートが競合したので8081番に変更します. /etc/stork/agent.env

STORK_AGENT_PORT=8081

を追記します*10

Stork ServerにこのStork Agentを登録します.

sudo su stork-agent -s /bin/sh -c 'stork-agent register --server-url http://lavalse.home:8080'

Stork ServerのWebUIを表示し,Stork AgentをAuthorizeすると,Stork ServerからStork Agentが持つ情報を確認できるようになります. Kea DHCP への接続は /etc/kea/kea-ctrl-agent.conf を読んで自動でしてくれるので,特に何もしなくて良いです.

これで Kea DHCP, Kea CA, Stork Server, Stork Agentの構築が完了しました. 最後に,Grafana+Prometheusでリース数などのメトリクスの監視をします.

メトリクスの可視化

Stork Server

Stork Serverのメトリクスは8080番ポートの /metrics から取得できます. prometheus.yml に以下のように設定します.

scrape_configs:
  - job_name: 'keadhcp4-strok-server'
    metrics_path: /metrics
    static_configs:
      - targets:
        - 'lavalse:8080'

Stork Serverからは取得できるメトリクスはあまりありません. storkserver_subnet_address_utilization で,Stork Serverが管理するDHCPサーバーのサブネットの使用率が取得できます. 以下のようなPromQLでサブネットごとの使用率を取得できます.

storkserver_subnet_address_utilization{job="keadhcp4-strok-server"}

Stork Agentのメトリクスは9547番ポートの /metrics から取得できます. prometheus.yml に以下のように設定します.

scrape_configs:
  - job_name: 'keadhcp4-strok-agent'
    metrics_path: /metrics
    static_configs:
      - targets:
        - 'pavane:9547'

Stork Agentからは色々なメトリクスを取得できます. 取得できるメトリクスについてはドキュメントの以下の部分で解説されています.

kea.readthedocs.io

例えばリースアドレス数は kea_dhcp4_addresses_assigned_total で取得することができるので, 以下のようなPromQLが書けます.

kea_dhcp4_addresses_assigned_total{job="keadhcp4-strok-agent", subnet_id="1"}

累積値ではなく現状の値が返されるので, rate() などを使う必要はありません. assigned_total のアドレス数にはアドレスプールの枯渇を検知するため,正常に割り当てられたアドレスの数の他に DHCPDECLINE されたアドレスの数も含まれることに注意してください*11. 正常に割り当てられたアドレス数のみを取り出す場合は,以下のように kea_dhcp4_addresses_declined_total の値を引く必要があります.

kea_dhcp4_addresses_assigned_total{job="keadhcp4-strok-agent", subnet_id="1"} - kea_dhcp4_addresses_declined_total{job="keadhcp4-strok-agent", subnet_id="1"}

最後に

Kea DHCPDHCPサーバーを構築し,Storkで管理,Grafana+Prometheusで監視するようにしました. DHCPのバックエンドをDBにするとかまだまだ遊びたいことはあるので,今後も色々やっていこうと思います.

*1:

  • DBをバックエンドにするためのスクリプトがDockerイメージには無い
  • Stork は Kea Control Agent のコンフィグを読んで接続する(HTTPのREST APIだけどIPアドレス周りがめんどくさい)
  • DHCPパケットは特殊なのでDockerネットワークでの扱いが面倒...

などなど... うまくやればできそうですが,無理にDockerでやる意味もないのでやめました

*2:イラストは https://loosedrawing.com/のものを使いました.

*3:https://kea.readthedocs.io/en/kea-2.6.2/arm/agent.html

*4:

The management API allows the issuing of specific management commands, such as statistics retrieval, reconfiguration, or shutdown. For more details, see Management API. Currently, the only supported communication channel type is the UNIX stream socket.

8. The DHCPv4 Server — Kea 2.6.2 documentation

*5:https://stork.readthedocs.io/en/v2.0.1/overview.html#architecture

*6:https://datatracker.ietf.org/doc/html/rfc2131

*7:https://kea.readthedocs.io/en/kea-2.6.2/arm/dhcp4-srv.html#dhcp4-subnet-selection

*8: https://stork.readthedocs.io/en/v2.0.1/overview.html#preprocessing-the-kea-and-bind-9-statistics-for-the-prometheus-server

*9:https://kea.readthedocs.io/en/kea-2.6.2/arm/quickstart.html#quick-start-guide-using-native-packages

*10:Stork ServerとStork Agentを同じVMにインストールする場合,どちらも8080番ポートを使うので必ず競合します.今回はVMを分けていますが,別のソフトウェアと競合しました

*11:

The Kea server does not decrease the assigned-addresses statistics when a DHCPDECLINE is received and processed successfully. While technically a declined address is no longer assigned, the primary usage of the assigned-addresses statistic is to monitor pool utilization. Most people would forget to include declined-addresses in the calculation, and would simply use assigned-addresses/total-addresses. This would cause a bias towards under-representing pool utilization. As this has a potential to cause serious confusion, ISC decided not to decrease assigned-addresses immediately after receiving DHCPDECLINE, but to do it later when Kea recovers the address back to the available pool.

8. The DHCPv4 Server — Kea 2.6.2 documentation