VyOS を DHCP Server として利用する

# はじめに

VyOS は Linux ベースのソフトウェア ルーターで、単なるルーティングだけでなく、BGP や OSPF といったダイナミック ルーティング プロトコルに対応していたり、VXLAN による L2 延伸や、ファイアウォールなど、豊富な機能を持っています。

https://vyos.io/

比較的省リソースな仮想環境でも動作するので、ラボを運用する上では、独自のネットワークを構成でき、非常に便利です。
2023年6月時点では、LTS Release (1.3.x Equuleus) と Rolling Release (1.4.x Sagitta) の 2種類が提供されており、LTS の方はサブスクリプション契約が無いと、取得できないようです。一方で、Rolling の方は、Nightly Build という位置付けで、デイリーでビルドされた iso イメージを、公式サイトから取得できます。

今回は、例えば、Tanzu Kubernetes Grid (TKG) の[ネットワーク要件](https://docs.vmware.com/jp/VMware-Tanzu-Kubernetes-Grid/2.2/tkg-deploy-mc-22/mgmt-reqs-prep-vsphere.html)にある DHCP による IP アドレス管理を、この VyOS を使って、用意する方法をご紹介します。
もし、既にラボで VyOS を利用している場合には、TKG 構築のため、わざわざ専用の DHCP Server を立てなくても、VyOS で賄えますので、少しでも TKG のラボ構築がお手軽になればと思います。


# 前提条件

利用している VyOS の ver は下記の通りです。
昨年の iso イメージなので、ちょっと古めになりつつあります。

```text
$ show system image
The system currently has the following image(s) installed:

   1: 1.4-rolling-202209020217 (default boot) (running image)
```

# 手順

参考にしている VyOS 公式ドキュメントは、こちらです。

https://docs.vyos.io/en/latest/configuration/service/dhcp-server.html


## TL;DR;

VyOS の操作がわかる方には、実際の設定例を見ていただく方が早いかも知れません。

```text: フォーマット
service {
    dhcp-server {
        shared-network-name <name> {
            name-server <address>
            ntp-server <address>
            subnet <subnet> {
                default-router <address>
                range <n> {
                    start <address>
                    stop <address>
                }
            }
        }
    }
}
```

```text: 設定例
service {
    dhcp-server {
        shared-network-name tkg-workload-network {
            name-server 192.168.110.1
            ntp-server 192.168.110.1
            subnet 192.168.100.0/24 {
                default-router 192.168.100.254
                range 0 {
                    start 192.168.100.100
                    stop 192.168.100.200
                }
            }
        }
    }
}
```

## Step-by-Step

まず、VyOS にログインして、Configuration Mode に入ります。

```text
configure
```

```text: 実行例
vyos@vyos:~$ configure
[edit]
vyos@vyos#
```

次に、`tkg-workload-network` という名前で、DHCP で払い出す共有ネットワークの管理単位を作成します。

```text
set service dhcp-server shared-network-name tkg-workload-network
```

この `tkg-workload-network` に対して、ここでは TKG のネットワーク要件になっている DNS サーバーと、NTP サーバーを設定していきます。
どちらも IP アドレス形式の設定が必要な点に注意して下さい。

```text
set service dhcp-server shared-network-name tkg-workload-network name-server 192.168.110.1
```

```text
set service dhcp-server shared-network-name tkg-workload-network ntp-server 192.168.110.1
```

実際に、DHCP を使って払い出される IP アドレス帯 (サブネット) を設定します。
まず、サブネットの作成と一緒に、デフォルト ゲートウェイを設定してしまいます。

```text
set service dhcp-server shared-network-name tkg-workload-network subnet 192.168.100.0/24 default-router 192.168.100.254
```

このサブネットに対して、実際に払い出す IP アドレスのレンジは、複数個 (0 ~ 255番) 作成することができるようです。
ここでは、0番として、`192.168.100.100` ~ `192.168.100.200` のレンジを指定しています。

```text
set service dhcp-server shared-network-name tkg-workload-network subnet 192.168.100.0/24 range 0 start 192.168.100.100
```

```text
set service dhcp-server shared-network-name tkg-workload-network subnet 192.168.100.0/24 range 0 stop 192.168.100.200
```

`show` コマンドを使って、設定が正しく投入されているかを確認します。
例えば、こんな感じになると思います。

```text
# show service dhcp-server
+shared-network-name tkg-workload-network {
+    name-server 192.168.110.1
+    ntp-server 192.168.110.1
+    subnet 192.168.100.0/24 {
+        default-router 192.168.100.254
+        range 0 {
+            start 192.168.100.100
+            stop 192.168.100.200
+        }
+    }
+}
[edit]
```

問題無ければ、`commit` コマンドで設定を反映させます。

```text
vyos@vyos# commit
[edit]
vyos@vyos#
```

ただ、このままだと、OS 再起動時に、設定が消えてしましますので、`save` をお忘れずに。

```
vyos@vyos# save
Saving configuration to '/config/config.boot'...
Done
[edit]
vyos@vyos#
```

# 補足

ラボ環境であれば、ここまでの設定で、十分に動作すると思いますが、TKG のネットワーク要件に厳密に従うと、安全のため、制御プレーン ノードの IP アドレスは、固定割り当てにしておく必要があります。
これは、例えば、制御プレーン ノードが、何らかの不幸で、長時間パワーオフまたはオフラインになってしまった場合に、DHCP のリース期限が切れ、違う IP アドレスが割り当てられてしまう問題を回避するために実行します。

VyOS では、下記のような設定を入れることで、IP アドレスを固定割り当てにできます。

```text: フォーマット
service {
    dhcp-server {
        shared-network-name <name> {
            name-server <address>
            ntp-server <address>
            subnet <subnet> {
                default-router <address>
                range <n> {
                    start <address>
                    stop <address>
                }
+                static-mapping <description> {
+                    ip-address <address>
+                    mac-address <address>
+                }
            }
        }
    }
}
```