安装工具:

apt install bridge-utils net-tools

创建一个新的网络命名空间

$ ip netns add net1  # net1为该网络空间的名称

查看命名空间的iptable, 路由表,设备

$ ip netns exec net1 route  # 查看路由表
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

$ ip netns exec net1 iptables -L # 查看iptable
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination  

$ ip netns exec net1 ip link list # 查看设备
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    # 目前只有本地回环设备, 并且状态为DOWN(未启动)


创建一对veth,并将veth的一头添加到net1中

$ ip link add veth1 type veth peer name veth1_p
$ ip link set veth1 netns net1

查看主机上当前设备,只能看到veth1_p这个设备了

$ ip link list | grep veth
1284: veth1_p@if1285: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000

查看net1网络命名空间,veth1在这个空间里面

$ ip netns exec net1 ip link list
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
1285: veth1@if1284: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 8a:b3:bb:2a:3a:92 brd ff:ff:ff:ff:ff:ff link-netnsid 0

为这对veth配置ip,并启动起来

$ ip addr add 10.68.0.100/24 dev veth1_p # 配置net1中的设备ip
$ ip netns exec net1 ip addr add 10.68.0.101/24 dev veth1 
$ ip netns exec net1 ip link set dev veth1 up # 启动net1中的设备
$ ip link set dev veth1_p up # 启动母机中的设备

分别查看当前启动的网络设备

$ ifconfig | grep veth1 # 母机
veth1_p: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

$ ip netns exec net1 ifconfig
veth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.101  netmask 255.255.255.0  broadcast 0.0.0.0
        inet6 fe80::88b3:bbff:fe2a:3a92  prefixlen 64  scopeid 0x20<link>
        ether 8a:b3:bb:2a:3a:92  txqueuelen 1000  (Ethernet)
        RX packets 57  bytes 7088 (6.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10  bytes 796 (796.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

测试通信

$ ip netns exec net1 ping 10.68.0.100 -I veth1
PING 10.68.0.100 (10.68.0.100) 来自 10.68.0.101 veth1 56(84) 字节的数据。
64 字节,来自 10.68.0.100: icmp_seq=1 ttl=64 时间=0.040 毫秒
64 字节,来自 10.68.0.100: icmp_seq=2 ttl=64 时间=0.096 毫秒
64 字节,来自 10.68.0.100: icmp_seq=3 ttl=64 时间=0.057 毫秒
64 字节,来自 10.68.0.100: icmp_seq=4 ttl=64 时间=0.070 毫秒
64 字节,来自 10.68.0.100: icmp_seq=5 ttl=64 时间=0.070 毫秒
64 字节,来自 10.68.0.100: icmp_seq=6 ttl=64 时间=0.070 毫秒
^C
--- 10.68.0.100 ping 统计 ---
已发送 6 个包, 已接收 6 个包, 0% packet loss, time 5077ms
rtt min/avg/max/mdev = 0.040/0.067/0.096/0.016 ms

创建网桥

$ brctl addbr mybridge

设置网桥ip

$ ip addr add 10.68.0.1/24 dev mybridge

启动网桥

$ ip link set dev mybridge up

查看网桥

$ ip addr show mybridge
35: mybridge: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 7e:06:1f:5a:53:f5 brd ff:ff:ff:ff:ff:ff
    inet 10.68.0.1/24 scope global mybridge
       valid_lft forever preferred_lft forever

将设备插入网桥

$ ip link set veth1_p master mybridge

查看是否插入成功

$ brctl show
bridge name	bridge id		STP enabled	interfaces
mybridge		8000.7e061f5a53f5	no		veth1_p

从veth对的另一端ping网桥

$ ip netns exec net1 ping 10.68.0.1 -I veth1
PING 10.68.0.1 (10.68.0.1) 来自 10.68.0.101 veth1 56(84) 字节的数据。
64 字节,来自 10.68.0.1: icmp_seq=1 ttl=64 时间=0.051 毫秒
64 字节,来自 10.68.0.1: icmp_seq=2 ttl=64 时间=0.063 毫秒
64 字节,来自 10.68.0.1: icmp_seq=3 ttl=64 时间=0.094 毫秒
^C
--- 10.68.0.1 ping 统计 ---
已发送 3 个包, 已接收 3 个包, 0% packet loss, time 2036ms
rtt min/avg/max/mdev = 0.051/0.069/0.094/0.018 ms

查看net1空间中的路由规则

$ ip netns exec net1 ip route
10.68.0.0/24 dev veth1 proto kernel scope link src 10.68.0.101 

设置一条默认路由:

$ ip netns exec net1 route add default gw 10.68.0.1 dev veth1

现在为止,已经可以实现在一台宿主机上的两个容器的相互通信。

将物理接口与网桥桥接:

$ brctl addif mybridge eth0

配置路由和转发

sysctl net.ipv4.ip_forward=1

现在,应该可以从net1中的veth1向外界发送消息:

$ ip netns exec net1 ping 8.8.8.8 -I veth1
PING 8.8.8.8 (8.8.8.8) from 10.68.0.101 veth1: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=2 ttl=62 time=39.5 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=62 time=40.5 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=62 time=39.3 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=62 time=49.9 ms
64 bytes from 8.8.8.8: icmp_seq=6 ttl=62 time=40.3 ms
64 bytes from 8.8.8.8: icmp_seq=7 ttl=62 time=39.1 ms
64 bytes from 8.8.8.8: icmp_seq=8 ttl=62 time=39.1 ms
^C
--- 8.8.8.8 ping statistics ---
8 packets transmitted, 7 received, 12.5% packet loss, time 7015ms
rtt min/avg/max/mdev = 39.062/41.081/49.859/3.620 ms

Refercences

Build your own bridgechatpgtHow to Configure Network Bridge on Linux? - zenarmor.comhttps://zhuanlan.zhihu.com/p/65566171