なぜ仮想マシンの代わりにNetwork Namespacesを使うべきなのか?
1台のサーバー上で、ポート80を占有する2つのサービスを同時に実行したいと思ったことはありませんか?通常、Dockerを検討するか、あるいはわずかなスクリプトを実行するためだけに少なくとも512MBのRAMを消費する重い仮想マシン(VM)を作成することを考えるでしょう。Network Namespaces(netns)は、リソース消費がほぼゼロの非常に軽量な代替ソリューションです。
この技術により、Linuxオペレーティングシステムを複数の独立したネットワーク空間に分割できます。各空間は独自のルーティングテーブル、インターフェースリスト、ファイアウォールルール(iptables)を保持します。これらは完全に独立して動作し、あたかも1つの筐体の中に複数の物理的なコンピュータを所有しているかのようになります。
実際、Dockerもコンテナのネットワーク隔離にこのnetnsを利用しています。手動での設定方法を理解することで、自動化ツールに頼らずに複雑なネットワークトラブルシューティングを行えるようになります。
知っておくべき3つのコア構成要素
図解を理解する前に、急いでコマンドを打ち込まないでください。この仮想ネットワークシステムを以下のようにイメージしてみましょう:
- Network Namespace: 完全に隔離された「籠」です。許可しない限り、内部からは外部のネットワークリソースを見ることはできません。
- Veth Pair (Virtual Ethernet): 2つの端を持つ仮想ネットワークケーブルです。一方の端をNamespace Aに、もう一方をホストマシン(Host)に接続すると、2つの環境間でデータが流れるようになります。
- Bridge: 仮想スイッチの役割を果たします。3つ、5つ、あるいは数十のNamespaceをより簡単に接続するのに役立ちます。
実践:ゼロからのネットワーク環境構築
1つのNamespaceを作成し、それをホストマシンに接続してインターネットアクセスを許可します。これは、Webアプリケーションやプロキシを安全にテストするための標準的なシナリオです。
ステップ1:Namespaceの初期化
lab_network という名前の空間を作成します。すべての管理コマンドは ip netns プレフィックスで始まります。
# 新しいnamespaceを作成
sudo ip netns add lab_network
# リストを確認
ip netns list
この時点では、lab_network は箱から出したばかりのコンピュータのようなものです。ネットワークカードもIP設定もまだありません。
ステップ2:Veth Pairによる接続
2つの世界をつなぐための仮想ケーブルが必要です。
# vethペアを作成:v-host側とv-ns側
sudo ip link add v-host type veth peer name v-ns
# v-ns側をnamespace lab_networkに移動
sudo ip link set v-ns netns lab_network
このコマンドの後、v-ns 側はホストマシンから消え、namespaceの内部に現れます。
ステップ3:IP設定と接続の有効化
デフォルトでは、新しいインターフェースはDOWN(オフ)状態です。IPを割り当てて有効化する必要があります。
# ホストマシン(Host)側の設定
sudo ip addr add 10.1.1.1/24 dev v-host
sudo ip link set v-host up
# Namespace内部の設定
sudo ip netns exec lab_network ip addr add 10.1.1.2/24 dev v-ns
sudo ip netns exec lab_network ip link set v-ns up
# loopbackインターフェースを有効化(内部アプリケーションの通信に非常に重要)
sudo ip netns exec lab_network ip link set lo up
ホストマシンから ping 10.1.1.2 を試してみてください。通常0.05ms未満の遅延で応答があれば成功です。
ステップ4:インターネットアクセスの許可(NAT)
Namespaceはホストマシンを認識できるようになりましたが、まだインターネットには出られません。ホストマシンを中間ルーターにする必要があります。
# パケット転送(IPフォワーディング)を有効化
sudo sysctl -w net.ipv4.ip_forward=1
# iptablesによるNAT設定(eth0を実際のネットワークカード名に置き換えてください)
sudo iptables -t nat -A POSTROUTING -s 10.1.1.0/24 -o eth0 -j MASQUERADE
# Namespaceにデフォルトゲートウェイを追加
sudo ip netns exec lab_network ip route add default via 10.1.1.1
次のコマンドでNATとパケット転送の設定を確認します: sudo ip netns exec lab_network ping 8.8.8.8。
トラブルを避けるための実践的な経験則
何度もシステムをデバッグした結果、得られた3つの重要な注意点を紹介します:
- DNSエラー: IP 8.8.8.8にはpingが通るのに
curl google.comができない場合、それはNamespaceにDNS設定がないためです。/etc/netns/lab_network/resolv.confファイルを作成し、そこにnameserver 8.8.8.8を追記してください。 - 自動クリーンアップ: Namespaceを削除すると(
sudo ip netns del)、Linuxは関連するvethインターフェースを自動的に回収します。システムのゴミを心配する必要はありません。 - パケット監視: ネットワークが繋がらない場合は、ホストマシンで tcpdump -i v-host を使用してください。ファイアウォールによる遮断か、ルーティングミスか、パケットがどこで止まっているかすぐに分かります。
まとめ
Network Namespacesを使用することは、仮想ケーブルやスイッチを使ってレゴで遊ぶようなものです。これは単にアプリケーションを隔離するためのツールであるだけでなく、ネットワーキングを直感的に学ぶための最良の方法でもあります。私の職場では、新しいファイアウォールルールをテストする際、会社全体のネットワークを落とさないように、必ず先にnetnsモデルを構築して確認しています。基本的なコマンドから始めてみてください。Linuxの管理がより一層楽しくなるはずです。

