ip netnsコマンドでLinuxのネットワーク名前空間を操作する方法|仮想NIC・ルーティング分離の実践手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips, ネットワーク管理コマンド > ip netnsコマンドでLinuxのネットワーク名前空間を操作する方法|仮想NIC・ルーティング分離の実践手順
「ネットワーク設定を壊さずに、独立したルーティング環境でコマンドのテストをしたい」
「Dockerがどうやってコンテナのネットワークをホストから分離しているのか、仕組みを知りたい」

Linuxにはネットワーク名前空間(network namespace)という機能があります。1台のホストの中でネットワークスタック(NIC・ルーティングテーブル・iptablesルール・ポート番号空間)を完全に分離した仮想空間を複数作れます。DockerやPodmanがコンテナごとにIPアドレスを持てるのも、この仕組みがベースです。

この記事では、ip netnsコマンドで名前空間を作成し、vethペア(仮想NICのペア)で接続してIPアドレスを付与・通信確認するまでの実践手順を、Rocky Linux 9.4の実機出力とともに解説します。

この記事のポイント

・ip netns addで独立したネットワーク名前空間を即座に作成できる
・vethペアで2つの名前空間を接続しIPアドレスを付与するまでの手順が再現できる
・ip netns execで名前空間内のコマンドをホストから実行できる
・DockerのブリッジネットワークはLinux veth+bridgeの組み合わせで実装されている


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linuxのネットワーク名前空間とは何か

Linuxの名前空間(namespace)は、プロセスから見えるシステムリソースをグループ単位で分離する機能です。ネットワーク名前空間はその1種で、以下のリソースを名前空間ごとに独立して持つことができます。

・NIC(ネットワークインタフェース)の一覧
・IPアドレス・ルーティングテーブル
・iptables / nftablesのルール
・ポート番号の空間(80番ポートを複数の名前空間で個別に使える)

ホスト起動時に存在するデフォルトの名前空間は「初期名前空間(initial network namespace)」と呼ばれます。ip netnsで新規作成した名前空間は、最初はNICがlo(ループバック)しか存在せず、外部ネットワークから完全に分離されています。

ip netnsコマンドの基本操作

ip netnsコマンドはiproute2パッケージに含まれており、RHEL系では標準でインストールされています。

1. ネットワーク名前空間を作成する

# ns1 という名前の名前空間を作成する $ sudo ip netns add ns1

作成後、/var/run/netns/ディレクトリにファイルが作成されます。

2. 名前空間の一覧を表示する

$ sudo ip netns list ns1

3. 名前空間内でコマンドを実行する

ip netns execを使うと、指定した名前空間の中でコマンドを実行できます。

# ns1 内でNIC一覧を表示する $ sudo ip netns exec ns1 ip a 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

loだけが表示され、DOWN状態です。外部と通信するためには仮想NICを接続する必要があります。

4. 名前空間を削除する

$ sudo ip netns del ns1

削除すると、その名前空間内で動作していたプロセスは初期名前空間に移動するか終了します。

vethペアで名前空間を接続する手順

名前空間同士(または名前空間とホスト)を接続するにはveth(Virtual Ethernet)ペアを使います。vethは必ず2つで1組のNICで、片方に送ったパケットがもう片方からそのまま出てきます。Dockerのコンテナとホストを結ぶNICも、内部的にはvethペアです。

ここでは次の構成を作ります。

・ホスト(初期名前空間)側: veth0
・名前空間 ns1 側: veth1

1. vethペアを作成する

# veth0 と veth1 を1組のペアとして作成する $ sudo ip link add veth0 type veth peer name veth1

この時点では2つのNICともホストの初期名前空間にあります。

$ ip link show | grep veth 4: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 5: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000

2. veth1 を名前空間 ns1 に移動する

# veth1 を ns1 の名前空間に移動する $ sudo ip link set veth1 netns ns1

移動後はホスト側ではveth0だけが見えます。veth1はns1の中に移ったため、ホストのip link showには表示されなくなります。

$ ip link show | grep veth 5: veth0@if4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000

名前空間内でIPアドレスとルーティングを設定する

1. ホスト側(veth0)にIPアドレスを付与して有効化する

$ sudo ip addr add 192.168.100.1/24 dev veth0 $ sudo ip link set veth0 up

2. 名前空間内(veth1・lo)を有効化してIPアドレスを付与する

# ns1 内で veth1 にIPアドレスを付与して有効化する $ sudo ip netns exec ns1 ip addr add 192.168.100.2/24 dev veth1 $ sudo ip netns exec ns1 ip link set veth1 up # lo(ループバック)も有効化する $ sudo ip netns exec ns1 ip link set lo up

設定後、名前空間内のNIC状態を確認します。

$ sudo ip netns exec ns1 ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 4: veth1@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 5e:2f:c0:0a:1b:3f brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.100.2/24 brd 192.168.100.255 scope global veth1 valid_lft forever preferred_lft forever

veth1UP状態になり、192.168.100.2/24が付いています。

3. 名前空間内のルーティングを確認する

$ sudo ip netns exec ns1 ip route 192.168.100.0/24 dev veth1 proto kernel scope link src 192.168.100.2

同一サブネット(192.168.100.0/24)へのルートが自動的に追加されています。

pingで通信を確認する

1. ホストから名前空間内のIPアドレスへpingを打つ

$ ping -c 3 192.168.100.2 PING 192.168.100.2 (192.168.100.2) 56(84) bytes of data. 64 bytes from 192.168.100.2: icmp_seq=1 ttl=64 time=0.076 ms 64 bytes from 192.168.100.2: icmp_seq=2 ttl=64 time=0.064 ms 64 bytes from 192.168.100.2: icmp_seq=3 ttl=64 time=0.058 ms --- 192.168.100.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2053ms rtt min/avg/max/mdev = 0.058/0.066/0.076/0.008 ms

veth0(192.168.100.1)からveth1(192.168.100.2)への疎通が確認できました。

2. 名前空間内からホスト側へのpingを確認する

$ sudo ip netns exec ns1 ping -c 3 192.168.100.1 PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data. 64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=0.072 ms 64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=0.060 ms 64 bytes from 192.168.100.1: icmp_seq=3 ttl=64 time=0.055 ms --- 192.168.100.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2048ms rtt min/avg/max/mdev = 0.055/0.062/0.072/0.007 ms

双方向で通信できていることが確認できました。

3. 名前空間内のポート状態を確認する

名前空間内でのポートやソケットの状態確認には、ip netns execを通じてssコマンドが使えます。Linux ポート確認の全コマンドで解説しているオプションも、名前空間内でそのまま機能します。

$ sudo ip netns exec ns1 ss -tulpn Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process

新規作成直後の名前空間はリスニングサービスがゼロです。ホスト上のポートとは完全に分離されています。

よくあるエラーとトラブルシュート

「Cannot open network namespace: No such file or directory」が出る

名前空間名のタイポか、ip netns addが実行されていません。ip netns listで作成済みの名前空間を確認してください。

$ sudo ip netns list ns1

pingが通らない(「connect: Network is unreachable」)

NICがDOWN状態のままです。ip link set dev <NIC名> upでインタフェースを有効化しているか確認してください。ループバック(lo)もupにするのを忘れないことが重要です。

# ns1 内のNIC状態確認 $ sudo ip netns exec ns1 ip link show 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN ... 4: veth1@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN ... # DOWN なら up にする $ sudo ip netns exec ns1 ip link set lo up $ sudo ip netns exec ns1 ip link set veth1 up

「RTNETLINK answers: File exists」が出る

同名のNICやIPアドレスが既に存在します。ip addr showまたはip link showで現在の設定を確認し、既存のvethペアを削除してから再作成してください。

# 既存のvethペアを削除する(片方を削除すれば両方消える) $ sudo ip link del veth0

サーバー再起動後に設定が消える

ip netnsip linkで行った設定はメモリ上にのみ存在します。再起動後も設定を維持したい場合は、NetworkManagerのコネクション設定またはsystemdのネットワークユニットで管理する必要があります。

本記事のまとめ

やりたいこと コマンド
名前空間を作成する sudo ip netns add ns1
名前空間の一覧を表示する ip netns list
名前空間内でコマンドを実行する sudo ip netns exec ns1 コマンド
vethペアを作成する sudo ip link add veth0 type veth peer name veth1
NICを名前空間へ移動する sudo ip link set veth1 netns ns1
IPアドレスを付与する sudo ip addr add 192.168.100.2/24 dev veth1
NICを有効化する sudo ip link set veth1 up
vethペアを削除する sudo ip link del veth0
名前空間を削除する sudo ip netns del ns1
ネットワーク名前空間は、Dockerなどのコンテナ基盤がネットワーク分離を実現するための根幹技術です。ip netnsを手で操作できるようになると、コンテナのネットワークトラブルシュートや、本番に影響を与えずにルーティング変更を検証したい場面で強力なツールになります。

Linuxネットワークの仕組みを体系的に理解したい方へ

ネットワーク名前空間やvethペアを使いこなすには、IPアドレス・ルーティング・NICの基礎からDockerのネットワーク設計まで体系的に理解することが重要です。断片的な知識を積み重ねるより、現場で使われる構成を一度まとめて学ぶことで、トラブル発生時に迷わず対処できるようになります。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。