• 【Docker】Linux网桥连接多个命名空间


    veth实现了点对点的虚拟连接,可以通过veth连接两个namespace,如果我们需要将3个或者多个namespace接入同一个二层网络时,就不能只使用veth了。

    在物理网络中,如果需要连接多个主机,我们会使用bridge(网桥),或者又称为交换机。Linux也提供了网桥的虚拟实现。下面我们试验通过Linux bridge来连接三个namespace。

    创建3个Network Namespace

    $ ip netns add ns0
    
    $ ip netns add ns1
    
    $ ip netns add ns2
    
    $ ip netns list
    ns2
    ns1
    ns0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    创建3对veth pair

    $ 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    创建网桥

    创建名为bridge0的网桥

    $ ip link add bridge0 type bridge
    
    • 1

    启动bridge0网桥:

    $ ip link set dev bridge0 up
    
    • 1

    查询bridge0网桥:

    $ 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
    
    • 1
    • 2
    • 3
    • 4
    • 5

    绑定网口

    Network Namespace、veth pair、bridge都创建完毕,下面通过命令将每对veth pair的一端绑定在network namespace,另一端绑定在docker0网桥上,用于实现网络互通。

    配置第一个网络命名空间ns0:

    // 将veth1添加进ns0
    $ ip link set dev veth1 netns ns0
    
    // 为ns0中的veth1配置ip
    $ ip netns exec ns0 ip addr add 172.16.0.11/16 dev veth1
    
    // 启动ns0中的veth1网卡
    $ ip netns exec ns0 ip link set dev veth1 up
    
    // 将veth0添加加网桥bridge0
    $ ip link set dev veth0 master bridge0
    
    // 启动veth0网卡
    $ 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    配置第二个网络命名空间ns1:

    // 将veth3添加进ns1
    $ ip link set dev veth3 netns ns1
    
    // 为ns1中的veth3配置ip
    $ ip netns exec ns1 ip addr add 172.16.0.33/16 dev veth3
    
    // 启动ns1中的veth3网卡
    $ ip netns exec ns1 ip link set dev veth3 up
    
    // 将veth2添加加网桥bridge0
    $ ip link set dev veth2 master bridge0
    
    // 启动veth2网卡
    $ 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    配置第三个网络命名空间ns2:

    // 将veth5添加进ns2
    $ ip link set dev veth5 netns ns2
    
    // 为ns2中的veth5配置ip
    $ ip netns exec ns2 ip addr add 172.16.0.55/16 dev veth5
    
    // 启动ns2中的veth5网卡
    $ ip netns exec ns2 ip link set dev veth5 up
    
    // 将veth4添加加网桥bridge0
    $ ip link set dev veth4 master bridge0
    
    // 启动veth4网卡
    $ 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    验证多个namespace之间的通信

    $ 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    通过上面的试验,我们验证了可以使用Linux bridge来将多个namespace连接到同一个二层网络中。你可能注意到,在分配IP地址的时候,我们只为veth在namespace中那一端的虚拟网卡分配了地址,而没有为加入bridge那一端分配地址。这是因为bridge是工作在二层上的,只会处理以太包,包括ARP解析,以太数据包的转发和泛洪;并不会进行三层(IP)的处理,因此不需要三层的IP地址。

    使用brctl

    上面我们是借助ip link来创建网桥的,要想更好的操作网桥可以使用brctl,这个命令来自bridge-utils安装包。

    brctl相关的命令如下:

    $ 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    查看网桥绑定的端口

    使用brctl show命令来查询网桥下绑定的网卡。

    $ brctl show
    bridge name     bridge id               STP enabled     interfaces
    bridge0         8000.02318e3fe341       no              veth0
                                                            veth2
                                                            veth4
    
    • 1
    • 2
    • 3
    • 4
    • 5

    给bridge删除接口

    使用brctl delif可以给bridge删除接口。

    $ brctl delif bridge0 veth0
    
    $ brctl show bridge0
    bridge name     bridge id               STP enabled     interfaces
    bridge0         8000.327eef22246d       no              veth2
                                                            veth4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    给bridge增加接口

    使用brctl addif可以给bridge增加接口。

    $ brctl addif bridge0 veth0
    
    $ brctl show bridge0
    bridge name     bridge id               STP enabled     interfaces
    bridge0         8000.327eef22246d       no              veth0
                                                            veth2
                                                            veth4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    创建网桥

    使用brctl addbr可以创建网桥。

    $ brctl addbr bridge1
    
    $ brctl show
    bridge name     bridge id               STP enabled     interfaces
    bridge0         8000.327eef22246d       no              veth0
                                                            veth2
                                                            veth4
    bridge1         8000.000000000000       no
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    相当于命令ip link add bridge1 type bridge

    删除网桥

    使用brctl delbr可以删除网桥。

    $ brctl delbr bridge1
    
    $ brctl show
    bridge name     bridge id               STP enabled     interfaces
    bridge0         8000.327eef22246d       no              veth0
                                                            veth2
                                                            veth4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    相当于命令ip link delete bridge1

  • 相关阅读:
    esp32c3 nuttx 移植 micropython 尝试
    神经网络模型画图工具,神经网络模型图怎么画
    爬虫之xpath
    Linux实现进度条小程序(包含基础版本和模拟下载过程版本)
    初见物理引擎库Cannon.js
    内行才知道的大数据分析平台
    三维模型3DTile格式轻量化压缩的遇到常见问题与处理方法分析
    Android 开发想学习Flutter?带你从0基础到“封神”
    贝叶斯网络预测相关问题
    hive行转列函数stack(int n, v_1, v_2, ..., v_k)
  • 原文地址:https://blog.csdn.net/u022812849/article/details/134069621