3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1年の振り返りAdvent Calendar 2024

Day 2

Network Namespaceを使って仮想ネットワークを作る

Posted at

これは何?

Dockerなどのコンテナ技術で使用されるNetwork Namespaceを使い、小さな仮想ネットワークを作る記事です。
ゴールは、異なるNetwork Namespace間でpingできるようにすることです。

Network Namespaceとは

Network NamespaceはLinuxのNamespace機能の一つで、ネットワーク関連のリソースを隔離する機能です。
Network Namespaceを使うことによって、ネットワーク的にシステムから独立した仮想的な空間を作ることができます。

Network namespaces provide isolation of the system resources associated with networking: network devices, IPv4 and IPv6 protocol stacks, IP routing tables, firewall rules, the /proc/net directory (which is a symbolic link to /proc/pid/net), the /sys/class/net directory, various files under /proc/sys/net, port numbers (sockets), and so on. In addition, network namespaces isolate the UNIX domain abstract socket namespace (see unix(7)).

ネットワーク的に独立した空間を作るため、ネットワーク関連の設定がホストマシンとNetwork Namespace内では異なります。

例えば、ホストマシンのRoute Tableと作成したNetwork Namespace内のRoute Tableを見ると、違う内容が表示されます。

$ ip route show
default via 10.32.0.1 dev eno1 proto dhcp src 10.32.1.33 metric 100 
10.32.0.0/16 dev eno1 proto kernel scope link src 10.32.1.33 metric 100
$ sudo ip netns add ns
$ sudo ip netns exec ns bash
$ ip route show

Network Namespaceを作成した段階ではRoute Tableにエントリが存在しないため、特に何も表示されません。

実践

環境

$ cat /etc/issue
Ubuntu 24.04.1 LTS \n \l

Network Namespaceの作成

異なるNetwork Namespace間でpingが通るようにしたいので、まずは2つのNetwork Namespaceを作成します。

$ sudo ip netns add ns1
$ sudo ip netns add ns2

仮想Network Interfaceの作成

続いて、各Network Namespaceが通信するための仮想的なNetwork Interfaceを作成します。
この仮想的なNetwork Intefaceはveth(Virtual Ethernet Device)と呼ばれます。
vethを作成する際にはNetwork Interfaceを単体で作るのではなく、両端がNetwork Interfaceになっている仮想的なケーブルを作成し、それをNetwork Namespaceにアタッチします。

$ sudo ip link add veth1 type veth peer name veth2

veth1, veth2というNetwork Interfaceが追加されていることが確認できます。

$ sudo ip link show
# ...
4: veth2@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 36:e9:5b:30:7a:75 brd ff:ff:ff:ff:ff:ff
5: veth1@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 02:f2:f1:f3:55:82 brd ff:ff:ff:ff:ff:ff

この時点ではホストマシンの領域にできてしまっているので、両端のNetwork Interfaceを各Network Namespaceにアタッチします。

$ sudo ip link set veth1 netns ns1
$ sudo ip link set veth2 netns ns2

ns1, ns2に入ってNetwork Interfaceがアタッチされているか確認します。

$ sudo ip netns exec ns1 bash
$ ip link show
# ...
5: veth1@if4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 02:f2:f1:f3:55:82 brd ff:ff:ff:ff:ff:ff link-netns ns2

$ sudo ip netns exec ns2 bash
$ ip link show
# ...
4: veth2@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 36:e9:5b:30:7a:75 brd ff:ff:ff:ff:ff:ff link-netns ns1

IPアドレスの割当

この時点で異なるNetwork Namespace同士がvethを通して繋がりましたが、pingを通すためにはIPアドレスの設定が必要になります。
各Network Namespaceでvethに対してIPアドレスを割り当てます。

$ sudo ip netns exec ns1 bash
$ ip address add 192.0.1.1/24 dev veth1
$ ip address show
# ...
5: veth1@if4: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 02:f2:f1:f3:55:82 brd ff:ff:ff:ff:ff:ff link-netns ns2
    inet 192.0.1.1/24 scope global veth1
       valid_lft forever preferred_lft forever

$ sudo ip netns exec ns2 bash
$ ip address add 192.0.1.2/24 dev veth2
$ ip address show
# ...
4: veth2@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 36:e9:5b:30:7a:75 brd ff:ff:ff:ff:ff:ff link-netns ns1
    inet 192.0.1.2/24 scope global veth2
       valid_lft forever preferred_lft forever

Network Interfaceの状態をUPに変更する

最後にNetwork Interfaceの状態をUPにすることで通信できるようにします。
Route tableにエントリが追加されます。

$ sudo ip netns exec ns1 bash
$ ip link set veth1 up
$ ip route show
192.0.1.0/24 dev veth1 proto kernel scope link src 192.0.1.1 linkdown

$ sudo ip netns exec ns2 bash
$ ip link set veth2 up
$ ip route show
192.0.1.0/24 dev veth2 proto kernel scope link src 192.0.1.2

ping

$ sudo ip netns exec ns1 bash
$ ping -c 3 192.0.1.2
PING 192.0.1.2 (192.0.1.2) 56(84) bytes of data.
64 bytes from 192.0.1.2: icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from 192.0.1.2: icmp_seq=2 ttl=64 time=0.066 ms
64 bytes from 192.0.1.2: icmp_seq=3 ttl=64 time=0.058 ms

--- 192.0.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2059ms
rtt min/avg/max/mdev = 0.058/0.062/0.066/0.003 ms

参考

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?