[Docker] Linux bridge connects multiple namespaces

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.