Network Namespace (NS)の基礎
Network Namespace (NS)の基礎
概要
Network Namespace(ネットワークネームスペース、以下NS)は、Linuxカーネルの機能の一つで、複数のネットワークスタックを分離して管理することができます。同一OSシステムの中で異なるネットワーク環境を提供するために広く利用されており、コンテナにおける個別ネットワークの提供のためや仮想ネットワークの作成に利用されています。スタック自体が分離されるため深いリソースの分離が可能になる反面で柔軟な利用ができない場面もあるので利用時には最適な技術の利用の検討が必要です。
使い方
NSの使い方はシンプルで、いくつかの基本的なコマンドを用いて管理することができます。以下に、典型的な操作手順を示します。本記事では基本的にはiproute2 を用いて操作を行います。
1. ネットワークネームスペースの作成
$ sudo ip netns add mynamespace
このコマンドで「mynamespace」という名前のNSを作成します。
コマンドを実行しても何も表示されませんが新しくNSが作成されています。作成されたNSはip netns list
コマンドで確認できます。
$ ip netns list
mynamespace
作成されたNS内ではコマンドを実行できます。この操作にはip netns exec
を使うと指定したNS内でのコマンドを実行できます。また、実行コマンドにシェルを指定することで連続してコマンドを入力することもできます。ip
コマンド自体をNS内で実行したい場合には、ip -n
オプションを利用します。
$ sudo ip netns exec mynamespace ip address show
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
$ sudo ip netns exec mynamespace bash
# ip address show
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
# exit
$ sudo ip -n mynamespace route show vrf VRF1
192.168.100.0/24 dev veth2-vrf1 proto kernel scope link src 192.168.100.1
不要になったNSを削除するにはip netns delete
コマンドを使います。作成したnetns
の環境は永続性のある設定ではないため、OSを再起動することで削除することもできます。
$ sudo ip netns delete mynamespace
$ ip netns list
(何も表示されません)
2. ネットワークデバイスの追加
NSにネットワークデバイスを追加するには、vethペア(仮想イーサネットデバイス)を作成し、一方をホスト側に、もう一方をNS側に割り当てます。これを実ネットワークに例えるならばケーブルをルータに接続しているようなものです。
$ sudo ip link add veth0 type veth peer name veth1
$ sudo ip link set veth1 netns mynamespace
このコマンドでveth0はホストに、veth1はNS「mynamespace」に割り当てられます。ここではリンクレベルで接続されたことになりますのでL3の設定を実施する必要があります。
3. ネットワークデバイスの設定
グローバルのName Spaceであるホスト側のvethデバイスにIPアドレスを割り当て、起動します。
$ sudo ip addr add 192.168.10.1/24 dev veth0
$ sudo ip link set veth0 up
$ ip address show veth0
5: veth0@if4: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
link/ether 1e:4b:7b:d8:84:10 brd ff:ff:ff:ff:ff:ff link-netns mynamespace
inet 192.168.10.1/24 scope global veth0
valid_lft forever preferred_lft foreve
NS内のネットワークデバイスを設定するには、ip netns exec
を使用して、L3の設定を実施します。
$ sudo ip netns exec mynamespace ip addr add 192.168.10.2/24 dev veth1
$ sudo ip netns exec mynamespace ip link set veth1 up
$ sudo ip netns exec mynamespace ip link set lo up
$ sudo ip netns exec mynamespace ip address show veth1
4: veth1@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 92:8d:2d:c5:ed:00 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.10.2/24 scope global veth1
valid_lft forever preferred_lft forever
inet6 fe80::908d:2dff:fec5:ed00/64 scope link
valid_lft forever preferred_lft forever
$ ip address show veth0
5: veth0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 1e:4b:7b:d8:84:10 brd ff:ff:ff:ff:ff:ff link-netns mynamespace
inet 192.168.10.1/24 scope global veth0
valid_lft forever preferred_lft forever
inet6 fe80::1c4b:7bff:fed8:8410/64 scope link
valid_lft forever preferred_lft forever
vethの両端で適切な設定がなされることでインターフェースの状態がUP
に変化したことが確認できます。実際にこの仮想ネットワークへパケットを送信して導通できているか確認してみます。
$ sudo ip netns exec mynamespace ping -c 3 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.125 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.087 ms
64 bytes from 192.168.10.1: icmp_seq=3 ttl=64 time=0.072 ms
--- 192.168.10.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2033ms
rtt min/avg/max/mdev = 0.072/0.094/0.125/0.022 ms
参考
現在の環境のNSを識別するには/proc
の状態を確認することで実施できます。selfのnetの部分にSymリンクになりますが、inode番号が記載されています。実際にns1
の環境にシェルが入ると、inode番号が変化していることがわかります。
$ ls -alF /proc/self/ns/net
lrwxrwxrwx 1 ubuntu ubuntu 0 Aug 6 05:36 /proc/self/ns/net -> 'net:[4026531840]'
$ sudo ip netns add ns1
$ sudo ip netns exec ns1 bash
# ls -alF /proc/self/ns/net
lrwxrwxrwx 1 root root 0 Aug 6 05:37 /proc/self/ns/net -> 'net:[4026532242]'
# stat -L /proc/self/ns/net
File: /proc/self/ns/net
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 4h/4d Inode: 4026532242 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-08-06 05:37:17.438093308 +0000
Modify: 2024-08-06 05:37:17.438093308 +0000
Change: 2024-08-06 05:37:17.438093308 +0000
Birth: -
# exit
$ ls -alF /proc/self/ns/net
lrwxrwxrwx 1 ubuntu ubuntu 0 Aug 6 05:40 /proc/self/ns/net -> 'net:[4026531840]'
$ ls /var/run/netns
ns1
$ ip netns list
ns1
まとめ
Network Namespaceは、ネットワークの柔軟性とセキュリティを高めるためのツールです。コンテナ技術や仮想化環境で広く利用されており、システム管理者や開発者にとって有用です。基本的なコマンドを理解し、適切に活用することで、複雑なネットワーク環境も簡単に管理することができます。
Discussion