systemd-networkd
バージョン 210 から、systemd は udev と networkd による基本的なネットワーク設定のサポートを含むようになりました。
systemd-networkd はネットワーク設定を管理するシステムデーモンです。ネットワークデバイスが立ち上がるとそれを検出して設定を行い、仮想ネットワークデバイスを作成することもできます。このサービスは netctl などの通常のネットワーク管理ツールと一緒に動かすことが可能で、仮想化する場合、設定によってはツールを置き換えることもできます。特に systemd-nspawn で管理するコンテナのための基本的な、もしくは複雑なネットワーク設定 (固定 IP、ブリッジ、vlan など) を設定する場合にこのサービスはとても役に立ちます。
udev の仕事のようなネットワークインターフェイスの低レベルな設定を行うのには向いていません。
networkd は VM やコンテナなどのシンプルな設定のために作られていますが、イーサネット接続でも問題なく使うことは可能です。WiFi はサポートしていませんが、wpa_supplicant と一緒に使うことでワイヤレス接続を管理することができます。
インストール
systemd 210 以上でサービスが利用可能です。ホストやコンテナで systemd-networkd.service
を有効化・起動することができます。
デバッグするときのために bridge-utils, net-tools, iproute2 パッケージをインストールすることが強く推奨されます。
ネットワーク設定によっては、systemd-nspawn@.service
を編集して ExecStart
行にブートオプションを追加する必要があります。オプションの完全なリストは man 1 systemd-nspawn
を参照してください。
DHCP による自動 DNS 設定を利用したい場合は、systemd-resolved
を有効にして /run/systemd/resolve/resolv.conf
から /etc/resolv.conf
にシンボリックリンクを張る必要があります。詳しくは systemd-resolved.service(8)
を見て下さい。
設定ファイル
設定ファイルは /usr/lib/systemd/network
から、そして一時的な実行時のネットワークディレクトリ /run/systemd/network
とローカルのネットワーク管理ディレクトリ /etc/systemd/network
から読み込まれます。/etc/systemd/network
内のファイルが一番優先されます。
3つのタイプの設定ファイルが存在します。
- .network ファイル。マッチするデバイスにネットワーク設定を適用します。
- .netdev ファイル。マッチする環境に仮想ネットワークデバイスを作成します。
- .link ファイル。ネットワークデバイスが作られた時、udev は最初にマッチする .link ファイルを探します。
これらの設定ファイルは同じルールに従っています:
[Match]
セクションの全ての条件がマッチすれば、プロファイルが有効になります。- 空の
[Match]
セクションはどんな場合でもそのセクションを適用することを示します (いわば*
ジョーカーのようなものです)。 - それぞれのエントリは
NAME=VALUE
構文によるキーです。 - 全ての設定ファイルは辞書順でまとめてソートされ処理されます。ファイルがどのディレクトリにあるかは関係ありません。
- 同じ名前のファイルは互いを置き換えます。
network ファイル
このファイルはネットワーク設定の変数の設定、特にサーバーとコンテナの設定のために存在します。
以下は基本的な構造の MyProfile.network ファイルになります:
/etc/systemd/network/MyProfile.network
[Match] a vertical list of keys [Network] a vertical list of keys [Address] a vertical list of keys [Route] a vertical list of keys
[Match] セクション
よく使われるキーは:
Name=
デバイスの名前 (例: Br0, enp4s0)Host=
マシンのホストネームVirtualization=
システムが仮想化環境で起動されているかどうかをチェックします。Virtualization=no
キーはホストマシンでのみ適用され、逆にVirtualization=yes
はコンテナや VM で適用されます。
[Network] セクション
よく使われるキーは:
DHCP=
は DHCPv4 や DHCPv6 サポートを有効にします。both
,none
,v4
,v6
が設定できます。DNS=
は DNS サーバーのアドレスです。このオプションは複数個指定することができます。Bridge=
はリンクに追加するブリッジの名前です。
[Address] セクション
[Address]
セクションでよく使われるキーは:
Address=
は固定の IPv4 または IPv6 アドレスとそのプレフィックス長で、/
を使って区切ります (例:192.168.1.90/24
)。このオプションは必須です。
[Route] セクション
[Route]
セクションでよく使われるキーは:
Gateway=
はマシンのゲートウェイのアドレスです。このオプションは必須です。
完全なキーのリストについては、systemd.network(5)
を参照してください。
netdev ファイル
このファイルは仮想ネットワークデバイスを作成します。
以下は基本的な構造の Mydevice.netdev ファイルになります:
/etc/systemd/network/MyDevice.netdev
[Match] a vertical list of keys [Netdev] a vertical list of keys
[Match] セクション
よく使われるキーは Host=
と Virtualization=
です。
[Netdev] セクション
よく使われるキーは:
Name=
は netdev を作成するときに使うインターフェイスの名前です。このオプションは必須です。Kind=
は netdev の種類になります。現在 bridge, bond, vlan, macvlan がサポートされています。このオプションは必須です。
完全なキーのリストについては、systemd.netdev(5)
を参照してください。
link ファイル
このファイルはカスタム udev ルールの代わりとなりデバイスが現れた時に udev によって適用されます。
以下は基本的な構造の Mydevice.link ファイルになります:
/etc/systemd/network/MyDevice.link
[Match] a vertical list of keys [Link] a vertical list of keys
[Link]
セクションでデバイスの設定を指定した場合、[Match]
セクションは指定した link ファイルが指定したデバイスに適用できるかどうかを決めます。
[Match] セクション
よく使われるキーは MACADRESS=
, Host=
, Virtualization=
です。
Type=
はデバイスのタイプです (例: vlan)
[Link] セクション
よく使われるキーは:
MACAddressPolicy=
は永続的な MAC アドレスをハードウェアに設定する persistent (ほとんどのハードウェアはこちらにするべきです) またはデバイスが現れた時にランダムな MAC アドレスを与える random を指定します。
MACAddressPoicy=
を指定しなかった場合は MACAddress=
を使います。
使用方法
基本的な DHCP ネットワーク
以下はホストとコンテナで DHCP IP を有効にします。この場合、両方のシステムが同じインターフェイスを共有し、同じ IP を共有します。
/etc/systemd/network/MyDhcp.network
[Match] Name=en* [Network] DHCP=v4
そして、コンテナで systemd-networkd
を起動・有効化してください。
もちろん en*
を $ ip link
コマンドの出力でわかる Ethernet デバイスのフルネームに置き換えることは可能です。
- ホストとコンテナで:
$ ip a
2: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 14:da:e9:b5:7a:88 brd ff:ff:ff:ff:ff:ff inet 192.168.1.72/24 brd 192.168.1.255 scope global enp7s0 valid_lft forever preferred_lft forever inet6 fe80::16da:e9ff:feb5:7a88/64 scope link valid_lft forever preferred_lft forever
デフォルトのホストネームは DHCP サーバーから取得され一時的なホストネームとして使用されます。
変更するには [DHCPv4]
セクションに UseHostname=false
を追加してください:
/etc/systemd/network/MyDhcp.network
[DHCPv4] UseHostname=false
/etc/resolv.conf
で DNS を設定するかわりに DHCP に設定してもらいたい場合、systemd-resolved
を有効にして /run/systemd/resolve/resolv.conf
から /etc/resolv.conf
にシンボリックリンクを作成してください:
$ systemctl enable systemd-resolved $ ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
詳しくは systemd-resolved.service(8)
を参照。
2つの別々な IP で DHCP を使う
ブリッジインターフェイス
仮想ブリッジインターフェイスを作成する:
/etc/systemd/network/MyBridge.netdev
[NetDev] Name=br0 Kind=bridge
- ホストとコンテナで:
$ ip a
3: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default link/ether ae:bd:35:ea:0c:c9 brd ff:ff:ff:ff:ff:ff
インターフェイス br0 が表示されていますが DOWN になっているので注意してください。
イーサネットをブリッジに関連付ける
/etc/systemd/network/MyDhcp.network
を編集して DHCP を削除します。ブリッジはどの IP にもバインドされないインターフェイスが必要なので、このデバイスを br0 にバインドするキーを追加してください。名前を適切なものに変更しましょう。
/etc/systemd/network/MyEth.network
[Match] Name=en* [Network] Bridge=br0
ブリッジネットワーク
ブリッジのネットワークプロファイルを作成:
/etc/systemd/network/MyBridge.network
[Match] Name=br0 [Network] DHCP=v4
コンテナを起動するオプションを追加する
ホストとコンテナに別々の IP を割り当てたいので、ホストからコンテナのネットワークを切断する必要があります。切断するには、コンテナの起動コマンドに --network-bridge=br0
オプションを追加します。
# systemd-nspawn --network-bridge=br0 -bD /path_to/my_container
結果
- ホスト側
$ ip a
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 14:da:e9:b5:7a:88 brd ff:ff:ff:ff:ff:ff inet 192.168.1.87/24 brd 192.168.1.255 scope global br0 valid_lft forever preferred_lft forever inet6 fe80::16da:e9ff:feb5:7a88/64 scope link valid_lft forever preferred_lft forever 6: vb-MyContainer: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000 link/ether d2:7c:97:97:37:25 brd ff:ff:ff:ff:ff:ff inet6 fe80::d07c:97ff:fe97:3725/64 scope link valid_lft forever preferred_lft forever
- コンテナ側
$ ip a
2: host0: <BROADCAST,MULTICAST,ALLMULTI,AUTOMEDIA,NOTRAILERS,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 5e:96:85:83:a8:5d brd ff:ff:ff:ff:ff:ff inet 192.168.1.73/24 brd 192.168.1.255 scope global host0 valid_lft forever preferred_lft forever inet6 fe80::5c96:85ff:fe83:a85d/64 scope link valid_lft forever preferred_lft forever
注意
- ホストの br0 と、コンテナの host0 にそれぞれ IP アドレスが割り当てられました。
- 2つの新しいインターフェイスが作成されます: ホストの
vb-MyContainer
とコンテナのhost0
です。これは--network-bridge=br0
オプションによるものです。このオプションには--network-veth
という別のオプションも含まれており、ホストとコンテナの間に仮想イーサネットリンクが作成されます。 host0
の DHCP アドレスはシステムの/usr/lib/systemd/network/80-container-host0.network
ファイルから由来します。- ホスト側
$ brctl show
bridge name bridge id STP enabled interfaces br0 8000.14dae9b57a88 no enp7s0 vb-MyContainer
上記のコマンドの出力で2つのインターフェイスがバインドされたブリッジが確認できます。
- ホスト側
$ ip route
default via 192.168.1.254 dev br0 192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.87
- コンテナ側
$ ip route
default via 192.168.1.254 dev host0 192.168.1.0/24 dev host0 proto kernel scope link src 192.168.1.73
上記のコマンドの出力で IP アドレスとゲートウェイが 192.168.1.254 の br0
と host0
インターフェイスが有効になったのが確認できます。ゲートウェイのアドレスは systemd-networkd によって自動的に取得されます。
$ cat /run/systemd/resolve/resolv.conf
nameserver 192.168.1.254
固定 IP ネットワーク
ウェブサービス (例: FTP, http, SSH) を動かしている場合、デバイスごとに固定 IP を設定するのが役に立つかもしれません。システムの /usr/lib/systemd/network/99-default.link
ファイルに MACAdressPolicy=persistent
オプションがあれば (デフォルトの設定)、各デバイスは再起動しても同じ MAC アドレスを維持します。つまり、ゲートウェイのサービスを簡単に適切なデバイスに設定することができます。
まず、システムの /usr/lib/systemd/network/80-container-host0.network
ファイルを除去します。永続的にするために (例: アップグレードしても変わらないように)、ホストとコンテナ両方で以下を行なって下さい。これによって /etc/systemd/network
の同じ名前のファイルが /usr/lib/systemd/network
のファイルよりも優先されるため /usr/lib/systemd/network/80-container-host0.network
ファイルがマスクされます。
# ln -sf /dev/null /etc/systemd/network/80-container-host0.network
次に、コンテナで systemd-networkd
を有効化・起動してください。
必要な設定ファイル:
- ホスト側
/etc/systemd/network/MyBridge.netdev /etc/systemd/network/MyEth.network
MyBridge.network の修正
/etc/systemd/network/MyBridge.network
[Match] Name=br0 [Network] DNS=192.168.1.254 Address=192.168.1.87/24 Gateway=192.168.1.254
- コンテナ側
/etc/systemd/network/MyVeth.network
[Match] Name=host0 [Network] DNS=192.168.1.254 Address=192.168.1.94/24 Gateway=192.168.1.254
Et voila!