「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の組み合わせで実装されている
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
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
$ 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
$ 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
veth1がUP状態になり、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
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
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 netnsやip 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 |
ip netnsを手で操作できるようになると、コンテナのネットワークトラブルシュートや、本番に影響を与えずにルーティング変更を検証したい場面で強力なツールになります。
Linuxネットワークの仕組みを体系的に理解したい方へ
ネットワーク名前空間やvethペアを使いこなすには、IPアドレス・ルーティング・NICの基礎からDockerのネットワーク設計まで体系的に理解することが重要です。断片的な知識を積み重ねるより、現場で使われる構成を一度まとめて学ぶことで、トラブル発生時に迷わず対処できるようになります。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:Gitリポジトリをシェルスクリプトから操作する設計|自動pull・差分検知・タグ付与を安全に実装する方法
- この記事の属するカテゴリ:Linuxtips・ネットワーク管理コマンドへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます