systemd-networkd:.networkファイルでLinuxサーバーのネットワーク設定をシンプルに — NetworkManagerを置き換える方法

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

午前2時。カーネルアップデート後にVPSサーバーが再起動したら、ネットワークが上がってこない。SSHが切れた。VNCプロバイダー経由のコンソールアクセスはひどいラグ。NetworkManagerは device unmanaged エラーを吐いている。本番環境では絶対に遭遇したくないタイプの障害だ。

それ以来、全てのヘッドレスサーバーからNetworkManagerを外してsystemd-networkdに移行した。GUIも不要、肥大化したデーモンも不要、テキストファイルを数個書くだけで完結する。

クイックスタート — 5分で完了

サーバーがネットワークに接続中でsystemd-networkdへ今すぐ移行したい場合は、この手順を正確な順番で実行すること。順番を間違えると簡単にSSHが切れる。

まず、使用中のインターフェース名を確認する:

ip link show
# 出力例:
# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
# 3: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> ...

そのインターフェース用の設定ファイルを作成する(eth0は実際のインターフェース名に置き換えること):

sudo nano /etc/systemd/network/20-eth0.network

DHCP設定(VPSで最もよく使われる):

[Match]
Name=eth0

[Network]
DHCP=yes
DNS=1.1.1.1
DNS=8.8.8.8

または静的IPの設定:

[Match]
Name=eth0

[Network]
Address=203.0.113.10/24
Gateway=203.0.113.1
DNS=1.1.1.1
DNS=8.8.8.8

systemd-networkdを有効にしてNetworkManagerを無効にする — 正しい順番で:

# まずsystemd-networkdを有効にする
sudo systemctl enable --now systemd-networkd

# systemd-resolved(付属のDNSリゾルバー)を有効にする
sudo systemctl enable --now systemd-resolved

# リゾルバーの設定をリンクする
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

# その後でNetworkManagerを無効にする
sudo systemctl disable --now NetworkManager

すぐに確認する:

networkctl status
ping -c 3 1.1.1.1
ping -c 3 google.com

両方のpingが成功すれば完了。5分もかからない。

詳細解説 — 仕組みを理解して迷わない

systemd-networkdとは何か、なぜサーバーに使うのか?

systemd-networkdはsystemdに組み込まれたネットワーク管理デーモンだ — 現代のLinuxディストリビューションのほとんどが既に搭載している。追加インストールは一切不要。

NetworkManagerとの実質的な違いはこうだ:

  • NetworkManager:デスクトップ向けに設計されている — WiFiの自動スキャン、GUIでのVPN管理、モバイルホットスポット。ヘッドレスサーバーではこれら全て不要なのに、そのオーバーヘッドを払い続けることになる。
  • systemd-networkd:テキストファイルを書いてreloadするだけ。GUIなし、補助デーモンなし、起動が速く、AnsibleやスクリプトによるIT管理も容易。

モニターもWiFiもないヘッドレスサーバーでは、NetworkManagerは純粋なオーバーヘッドだ。実測値:Debian/UbuntuのVPSでsystemd-networkdに移行後、起動時間が3〜4秒短縮された

.networkファイルの構造

設定ファイルは/etc/systemd/network/に置く。ファイル名はXX-名前.network形式 — 前の数字が優先順位(数字が小さいほど優先度が高い)。

.networkファイルには3つの主要セクションがある:

[Match]
# どのインターフェースにこの設定を適用するかを指定する
Name=eth0          # インターフェース名で指定
# MACAddress=aa:bb:cc:dd:ee:ff  # またはMACアドレスで指定

[Network]
# メインのネットワーク設定
DHCP=yes           # DHCPから自動的にIPを取得
# Address=x.x.x.x/24   # または静的IP
# Gateway=x.x.x.x
DNS=1.1.1.1

[DHCP]
# DHCPクライアントのカスタマイズ
RouteMetric=10     # ルートのメトリック(複数インターフェースがある場合)
UseDNS=yes

[Match]セクションが最も重要 — このファイルをどのインターフェースに適用するかを決定する。マッチしなければ完全に無視される。インターフェース名を間違えてハマる人が多い箇所だ。

systemd-resolved — 付属のDNSリゾルバー

systemd-networkdは通常、DNS処理のためにsystemd-resolvedと組み合わせて使う。.networkファイルにDNS=1.1.1.1と記述すると、systemd-resolvedがドメイン名の解決を引き受けて管理する。

/etc/resolv.confはsystemd-resolvedのスタブリゾルバーを指すように設定する必要がある:

# 現在のresolv.confを確認する
cat /etc/resolv.conf

# シンボリックリンクが未設定の場合は作成する
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

# 使用中のDNSを確認する
resolvectl status

応用編 — 実践的なユースケース

インターフェースが2つあるサーバー(マネジメント用 + データ用)

よくある構成:eth0をマネジメント(SSH)用、eth1をアプリケーショントラフィック用として使う。

# eth0用ファイル — マネジメント用
# /etc/systemd/network/10-management.network
[Match]
Name=eth0

[Network]
Address=10.0.0.5/24
Gateway=10.0.0.1
DNS=10.0.0.1

[Route]
Gateway=10.0.0.1
Metric=100
# eth1用ファイル — データネットワーク用
# /etc/systemd/network/20-data.network
[Match]
Name=eth1

[Network]
DHCP=yes

[DHCP]
RouteMetric=200
UseRoutes=yes

メトリック値が低いほど優先度が高い。eth0(メトリック100)がメインインターフェースになる。

ワイルドカードマッチ — 複数インターフェースへの一括適用

[Match]
Name=eth*

[Network]
DHCP=yes

eth0eth1eth2など全てをDHCPにしたい場合に便利。ただし注意が必要 — ワイルドカードは意図しないインターフェースにマッチすることがある。

VLANの設定

# VLANインターフェース用のnetdevファイルを作成する
# /etc/systemd/network/30-vlan100.netdev
[NetDev]
Name=eth0.100
Kind=vlan

[VLAN]
Id=100
# VLAN用のnetworkファイル
# /etc/systemd/network/30-vlan100.network
[Match]
Name=eth0.100

[Network]
Address=192.168.100.5/24

systemd-networkdはVLAN、ブリッジ、ボンディングをネイティブサポート — 追加パッケージは不要。

実践的なTips — 本番運用から学んだこと

3年間、10台以上のVPS、真夜中に何度かSSHが切れる経験 — 以下のことは痛い目を見て学んだ。本番環境ではネットワーク設定ミスは許されない。特にVultrやHetznerのようにコンソールアクセスができないプロバイダーでは。

Tip 1:必ずステージングサーバーで先にテストする

安価なテスト用VPSに設定をコピーして、起動のたびにネットワークが正常に立ち上がることを確認するため、何度かrebootする習慣がある。

# rebootせずに設定をリロードしてテストする
sudo networkctl reload

# 各インターフェースの状態を確認する
networkctl list
networkctl status eth0

Tip 2:ネットワークが上がらない時のデバッグ

# networkdのログを確認する
journalctl -u systemd-networkd -n 50

# リアルタイムでログを確認する
journalctl -u systemd-networkd -f

# .networkファイルが正しくパースされているか確認する
networkctl cat eth0

Tip 3:削除前にNetworkManagerの設定をバックアップする

# NetworkManagerの設定をバックアップする
sudo cp -r /etc/NetworkManager /etc/NetworkManager.bak

# 現在の接続設定を確認する
nmcli connection show

Tip 4:.networkファイルの命名規則

私が使っている規則:数字が小さい = 優先度が高い = より重要なインターフェース。

  • 10-loopback.network — ループバック(設定が必要な場合)
  • 20-management.network — SSH/マネジメント用インターフェース
  • 30-data.network — データ用インターフェース
  • 90-default.network — 専用ファイルがないインターフェースへのワイルドカードフォールバック

Tip 5:確信がなければNetworkManagerは削除しなくていい

実際のところ、NetworkManagerを無効にしてsystemd-networkdを有効にするだけで十分だ。完全に削除すると他のパッケージが依存している場合に問題が起きる可能性がある。無効化の方がずっと安全だ:

sudo systemctl disable NetworkManager
sudo systemctl stop NetworkManager
# apt removeは不要

Tip 6:VPSでcloud-initを使っている場合

多くのVPSは初期化時のネットワーク設定にcloud-initを使っている。問題は、cloud-initが再起動のたびに.networkファイルを上書きする可能性があること。確認する:

cat /etc/cloud/cloud.cfg | grep network

# cloud-initのネットワーク管理を無効にしたい場合
sudo mkdir -p /etc/cloud/cloud.cfg.d/
echo 'network: {config: disabled}' | sudo tee /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg

設定を終えてrebootし、午前2時に30分デバッグして初めてcloud-initが全て上書きしていたことに気づいた。最初のエラーより腹が立った。

もちろん、systemd-networkdが全員向けというわけではない。複雑なWiFi設定が必要?複数プロファイルのVPN?デスクトップ環境?ならNetworkManagerの方が優れている。でも24時間365日稼働するヘッドレスサーバーは話が別だ — 静的な設定ファイル、少ないデーモン、余計なタイミングで壊れる要素が少ない。午前2時に必要なのは賢いツールではなく、邪魔をしないツールだ。

Share: