veth implements a point-to-point virtual connection, and two namespaces can be connected through veth. If we need to connect three or more namespaces to the same layer 2 network, we cannot just use veth.
In a physical network, if we need to connect multiple hosts, we will use a bridge, also known as a switch. Linux also provides a virtual implementation of network bridges. Next we try to connect three namespaces through Linux bridge.
Create 3 Network Namespaces
$ ip netns add ns0 $ip netns add ns1 $ip netns add ns2 $ip netns list ns2 ns1 ns0
Create 3 pairs of veth pairs
$ ip link add type veth $ ip link add type veth $ ip link add type veth $ip link 23: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 02:31:8e:3f:e3:41 brd ff:ff:ff:ff:ff:ff 24: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether a6:fa:24:af:7e:25 brd ff:ff:ff:ff:ff:ff 25: veth2@veth3: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether b6:44:af:1c:9d:34 brd ff:ff:ff:ff:ff:ff 26: veth3@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 02:89:cd:6d:91:5e brd ff:ff:ff:ff:ff:ff 27: veth4@veth5: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether d6:44:b0:6d:f2:af brd ff:ff:ff:ff:ff:ff 28: veth5@veth4: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 4e:9d:92:7f:97:6e brd ff:ff:ff:ff:ff:ff
Create a network bridge
Create a bridge named bridge0
$ ip link add bridge0 type bridge
Start the bridge0 bridge:
$ ip link set dev bridge0 up
Query the bridge0 bridge:
$ ip addr 29: bridge0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000 link/ether c2:a8:ec:6b:f5:9e brd ff:ff:ff:ff:ff:ff inet 172.16.0.1/16 brd 172.16.255.255 scope global bridge0 valid_lft forever preferred_lft forever
Bind network port
The Network Namespace, veth pair, and bridge have all been created. The following command is used to bind one end of each pair of veth pairs to the network namespace, and the other end to the docker0 bridge for network interoperability.
Configure the first network namespace ns0:
//Add veth1 into ns0 $ ip link set dev veth1 netns ns0 // Configure ip for veth1 in ns0 $ ip netns exec ns0 ip addr add 172.16.0.11/16 dev veth1 // Start the veth1 network card in ns0 $ ip netns exec ns0 ip link set dev veth1 up // Add veth0 to bridge0 $ ip link set dev veth0 master bridge0 // Start the veth0 network card $ ip link set dev veth0 up $ ip netns exec ns0 ip addr 24: veth1@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether a6:fa:24:af:7e:25 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.16.0.11/16 scope global veth1 valid_lft forever preferred_lft forever inet6 fe80::a4fa:24ff:feaf:7e25/64 scope link valid_lft forever preferred_lft forever
Configure the second network namespace ns1:
//Add veth3 into ns1 $ ip link set dev veth3 netns ns1 // Configure IP for veth3 in ns1 $ ip netns exec ns1 ip addr add 172.16.0.33/16 dev veth3 // Start the veth3 network card in ns1 $ ip netns exec ns1 ip link set dev veth3 up //Add veth2 to bridge0 $ ip link set dev veth2 master bridge0 // Start the veth2 network card $ ip link set dev veth2 up $ ip netns exec ns1 ip addr 26: veth3@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 02:89:cd:6d:91:5e brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.16.0.33/16 scope global veth3 valid_lft forever preferred_lft forever inet6 fe80::89:cdff:fe6d:915e/64 scope link valid_lft forever preferred_lft forever
Configure the third network namespace ns2:
//Add veth5 into ns2 $ ip link set dev veth5 netns ns2 // Configure ip for veth5 in ns2 $ ip netns exec ns2 ip addr add 172.16.0.55/16 dev veth5 // Start the veth5 network card in ns2 $ ip netns exec ns2 ip link set dev veth5 up //Add veth4 to bridge bridge0 $ ip link set dev veth4 master bridge0 // Start the veth4 network card $ ip link set dev veth4 up $ ip netns exec ns2 ip addr 28: veth5@if27: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 4e:9d:92:7f:97:6e brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.16.0.55/16 scope global veth5 valid_lft forever preferred_lft forever inet6 fe80::4c9d:92ff:fe7f:976e/64 scope link valid_lft forever preferred_lft forever
Verify communication between multiple namespaces
$ ip netns exec ns0 ping 172.16.0.33 -c 2 PING 172.16.0.33 (172.16.0.33) 56(84) bytes of data. 64 bytes from 172.16.0.33: icmp_seq=1 ttl=64 time=0.026 ms 64 bytes from 172.16.0.33: icmp_seq=2 ttl=64 time=0.038 ms --- 172.16.0.33 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.026/0.032/0.038/0.006 ms $ ip netns exec ns0 ping 172.16.0.55 -c 2 PING 172.16.0.55 (172.16.0.55) 56(84) bytes of data. 64 bytes from 172.16.0.55: icmp_seq=1 ttl=64 time=0.047 ms 64 bytes from 172.16.0.55: icmp_seq=2 ttl=64 time=0.036 ms --- 172.16.0.55 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.036/0.041/0.047/0.008 ms
Through the above experiment, we verified that Linux bridge can be used to connect multiple namespaces to the same Layer 2 network. You may notice that when allocating IP addresses, we only assigned addresses to the virtual network card on the end of veth in the namespace, but not on the end that joins the bridge. This is because bridge works on Layer 2 and will only process Ethernet packets, including ARP parsing, forwarding and flooding of Ethernet packets; it does not perform Layer 3 (IP) processing, so Layer 3 IP is not required. address.
Use brctl
Above we used ip link
to create the bridge. If you want to better operate the bridge, you can use brctl. This command comes from the bridge-utils
installation package.
The related commands of brctl
are as follows:
$ brctl help never heard of command [help] Usage: brctl [commands] commands: addbr <bridge> add bridge delbr <bridge> delete bridge addif <bridge> <device> add interface to bridge delif <bridge> <device> delete interface from bridge hairpin <bridge> <port> {<!-- -->on|off} turn hairpin on/off setageing <bridge> <time> set ageing time setbridgeprio <bridge> <prio> set bridge priority setfd <bridge> <time> set bridge forward delay sethello <bridge> <time> set hello time setmaxage <bridge> <time> set max message age setpathcost <bridge> <port> <cost> set path cost setportprio <bridge> <port> <prio> set port priority show [ <bridge> ] show a list of bridges showmacs <bridge> show a list of mac addrs showstp <bridge> show bridge stp info stp <bridge> {<!-- -->on|off} turn stp on/off
View the ports bound to the bridge
Use the brctl show
command to query the network card bound to the bridge.
$ brctl show bridge name bridge id STP enabled interfaces bridge0 8000.02318e3fe341 no veth0 veth2 veth4
Delete the interface for bridge
Use brctl delif
to delete the interface for the bridge.
$ brctl delif bridge0 veth0 $ brctl show bridge0 bridge name bridge id STP enabled interfaces bridge0 8000.327eef22246d no veth2 veth4
Add interface to bridge
Use brctl addif
to add an interface to the bridge.
$ brctl addif bridge0 veth0 $ brctl show bridge0 bridge name bridge id STP enabled interfaces bridge0 8000.327eef22246d no veth0 veth2 veth4
Create a network bridge
Use brctl addbr
to create a network bridge.
$ brctl addbr bridge1 $ brctl show bridge name bridge id STP enabled interfaces bridge0 8000.327eef22246d no veth0 veth2 veth4 bridge1 8000.000000000000 no
Equivalent to the command ip link add bridge1 type bridge
.
Delete bridge
Use brctl delbr
to delete a bridge.
$ brctl delbr bridge1 $ brctl show bridge name bridge id STP enabled interfaces bridge0 8000.327eef22246d no veth0 veth2 veth4
Equivalent to the command ip link delete bridge1
.