Network Namespaceをvethで接続するネットワークを作ってみる

Network Namespaceとvethで下記のネットワークを作ってみます。

<img width="761" alt="network.drawio.png (21.4 kB)" src="https://img.esa.io/uploads/production/attachments/5809/2025/02/26/19598/3f56aa4b-143c-4636-a883-9f5564d6814b.png">

# Network Namespaceの作成

```bash
# Network Namespace作成
sudo ip netns add ns1
sudo ip netns add ns2
```

Network Namespaceの一覧表示

```bash
sudo ip netns list
# ns1
# ns2
```
# veth(Virtual Ethenet Device | 仮想ネットワークインターフェース)の作成
`ns1` と `ns2` を接続するvethを作成します。
```bash
sudo ip link add ns1-veth0 type veth peer name ns2-veth0
```

vethの確認
```bash
sudo ip link show | grep veth
# 177: ns2-veth0@ns1-veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
# 178: ns1-veth0@ns2-veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
```

# vethをnsに接続

```bash
sudo ip link set ns1-veth0 netns ns1
sudo ip link set ns2-veth0 netns ns2
```

vethが`ns1` と `ns2` に接続されていることを確認
```bash
# nsに接続するとvethは見えなくなる
sudo ip link show | grep veth

# 代わりにns内からvethが見える様になる
sudo ip netns exec ns1 ip link show | grep veth
# 178: ns1-veth0@if177: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000

sudo ip netns exec ns2 ip link show | grep veth
# 177: ns2-veth0@if178: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
```

# vethにIPアドレスとMACアドレスを付与
```bash
# vethにIPアドレスを付与
sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0

# vethにMACアドレスを付与
sudo ip netns exec ns1 ip link set dev ns1-veth0 address 00:00:5E:00:53:11
sudo ip netns exec ns2 ip link set dev ns2-veth0 address 00:00:5E:00:53:12
```

`ns1` と `ns2` に IPアドレス・MACアドレスが付与されていることを確認

```bash
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
# 178: ns1-veth0@if177: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
#     link/ether 00:00:5e:00:53:11 brd ff:ff:ff:ff:ff:ff link-netns ns2
#     inet 192.0.2.1/24 scope global ns1-veth0
#        valid_lft forever preferred_lft forever

sudo ip netns exec ns2 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
# 177: ns2-veth0@if178: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
#     link/ether 00:00:5e:00:53:12 brd ff:ff:ff:ff:ff:ff link-netns ns1
#     inet 192.0.2.2/24 scope global ns2-veth0
#        valid_lft forever preferred_lft forever
```

# ネットワークインターフェースをUPする
このままだとstateがDOWN担っているのでUPする

```bash
sudo ip netns exec ns1 ip link set ns1-veth0 up
sudo ip netns exec ns2 ip link set ns2-veth0 up
```



# 疎通確認

ns1 から ns2 に ping を送る

```bash
# ns2をtcpdumpでキャプチャ
#   -t タイムスタンプを表示しない
#   -n アドレスを名前に変換しない
#   -e イーサネットのヘッダ情報を表示する
#   -l 標準出力を行バッファリングする
sudo ip netns exec ns2 tcpdump -tnel -i any icmp

# ping: ns1 -> ns2
#   -I: 送信元アドレスを指定する
sudo ip netns exec ns1 ping -c 3 192.0.2.2 -I 192.0.2.1
# PING 192.0.2.2 (192.0.2.2) from 192.0.2.1 : 56(84) bytes of data.
# 64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.041 ms
# 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.053 ms
# 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.040 ms
# 
# --- 192.0.2.2 ping statistics ---
# 3 packets transmitted, 3 received, 0% packet loss, time 2041ms
# rtt min/avg/max/mdev = 0.040/0.044/0.053/0.005 ms
```

tcpdumpでキャプチャした結果

```
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
ns2-veth0 In  ifindex 177 00:00:5e:00:53:11 ethertype IPv4 (0x0800), length 104: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 21643, seq 1, length 64
ns2-veth0 Out ifindex 177 00:00:5e:00:53:12 ethertype IPv4 (0x0800), length 104: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 21643, seq 1, length 64
ns2-veth0 In  ifindex 177 00:00:5e:00:53:11 ethertype IPv4 (0x0800), length 104: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 21643, seq 2, length 64
ns2-veth0 Out ifindex 177 00:00:5e:00:53:12 ethertype IPv4 (0x0800), length 104: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 21643, seq 2, length 64
ns2-veth0 In  ifindex 177 00:00:5e:00:53:11 ethertype IPv4 (0x0800), length 104: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 21643, seq 3, length 64
ns2-veth0 Out ifindex 177 00:00:5e:00:53:12 ethertype IPv4 (0x0800), length 104: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 21643, seq 3, length 64
```

# 削除

```bash
# nsの全削除
sudo ip --all netns delete

# 一個づつ削除
sudo ip netns delete ns1
sudo ip netns delete ns2
```