赞
踩
环境: centos7.3
前提:最好了解namespace和bridge
对docker的学习以及docker网络的学习也有一段时间了,想通过linux的一些命令以及namespace和路由实现一个类似docker网络的结构。我们先创建两个网络namespace,相当于创建两个容器实现网络隔离。我们再通过brctl创建一个linux的网桥,这个网桥就类似于docker中的docker0网桥。创建两个了隔离的ns我们就可以想象成两天新买的服务器,它们没有网络配置。而新建的网桥就相当于一个类似路由器的设备。我们接下来就需要给两个"新的服务器"(ns)配置IP以及连接它们到网桥上。这样就完成了第一步,连接在"网桥"上的"两台主机"是可以通信的。
创建两个ns(可以类比于新买的两台服务器)
- #创建两个ns
- ip netns add net1
- ip netns add net2
- #创建成功了,查看两个ns
- ip netns list
- #如果创建错误了,使用下面命令删除
- ip netns del <netns-name>
创建一个linux的网桥
- #没有brctl先安装
- yum install -y bridge-utils
- #创建一个linux的网桥
- brctl addbr bridge0
- #查看创建的网桥,注意新建网桥的state的是DOWN
- #还能看到新建的网桥并没有配置IP
- [root@localhost ~]# ip addr show bridge0
- 6: bridge0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
- link/ether fe:ff:11:30:b3:fd brd ff:ff:ff:ff:ff:ff
- #通过brctl show查看,可以查看网桥上依附的接口
- [root@localhost ~]# brctl show
- bridge name bridge id STP enabled interfaces
- bridge0 8000.000000000000 no
以上的操作,我们先创建两个ns(两个服务器),一个bridge(路由器),接下来我们需要通过这个bridge让两个ns(两个服务器)能相互通信。现实社会中,我们需要一个网线把他们连接起来,在虚拟网络中,我们需要veth-pair设备,它是一对虚拟的网络设备对。就像使用网线那样,我们一端放在ns中,一端依附在网桥上,同时给ns端的设备配上IP地址。同时也给网桥配上IP地址。同理,我们也给另一个ns做相同的操作。这样就相当于,两台服务器通过网络设备对veth-pair 连接到路由器上。
- #创建两对veth-pair设备
- ip link add veth1 type veth peer name veth_peer1
- ip link add veth2 type veth peer name veth_peer2
- #查看创建的veth-pair设备(部分截图)
- #新创建的设备都是DOWN状态,我们需要他们都启动了
- 7: veth_peer1@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
- link/ether d2:64:d2:45:4d:33 brd ff:ff:ff:ff:ff:ff
- 8: veth1@veth_peer1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
- link/ether 42:54:a0:9b:a3:56 brd ff:ff:ff:ff:ff:ff
- 9: veth_peer2@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
- link/ether 52:bf:16:34:9e:31 brd ff:ff:ff:ff:ff:ff
- 10: veth2@veth_peer2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
- link/ether ba:51:66:8e:b8:19 brd ff:ff:ff:ff:ff:ff
现在创建好了网线,我们需要一端放入ns中。一端附着到网桥中,并且把他们state都启动起来。
- #把veth1放到ns1中
- ip link set veth1 netns net1
- #把veth_peer1依附到bridge0上
- ip link set veth_peer1 master bridge0
- #把veth_peer1设置为启动状态
- ip link set veth_peer1 up
-
- #同理,下面的操作
- ip link set veth2 netns net2
- ip link set veth_peer2 master bridge0
- ip link set veth_peer2 up
查看veth_peer的状态,以及依附到网桥上的接口
- 7: veth_peer1@if8: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master bridge0 state LOWERLAYERDOWN group default qlen 1000
- link/ether d2:64:d2:45:4d:33 brd ff:ff:ff:ff:ff:ff link-netnsid 1
- 9: veth_peer2@if10: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master bridge0 state LOWERLAYERDOWN group default qlen 1000
- link/ether 52:bf:16:34:9e:31 brd ff:ff:ff:ff:ff:ff link-netnsid 2
- [root@localhost ~]# brctl show
- bridge name bridge id STP enabled interfaces
- bridge0 8000.52bf16349e31 no veth_peer1
- veth_peer2
我们给veth-pair依附到bridge上,另一端放入ns中,接下来需要把ns中的虚拟设备配置好IP并且启动。相当于服务器的网卡配置IP并且启动网卡。
- #因为不同的ns,网络操作都是隔离的,我们需要在各自的ns中执行操作,就相当于各自的服务器中执行操作
- #给net1中的veth1配置IP
- ip netns exec net1 ip addr add 10.10.1.2/24 dev veth1
- #设置veth1状态是UP
- ip netns exec net1 ip link set veth1 up
- #查看net1中的网络设备
- [root@localhost ~]# ip netns exec net1 ip addr
- 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
- 8: veth1@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
- link/ether 42:54:a0:9b:a3:56 brd ff:ff:ff:ff:ff:ff link-netnsid 0
- inet 10.10.1.2/24 scope global veth1
- valid_lft forever preferred_lft forever
- inet6 fe80::4054:a0ff:fe9b:a356/64 scope link
- valid_lft forever preferred_lft forever
- #同理,我们配置ns2
- [root@localhost ~]# ip netns exec net2 ip addr add 10.10.1.3/24 dev veth2
- [root@localhost ~]# ip netns exec net2 ip link set veth2 up
- [root@localhost ~]# ip netns exec net2 ip addr
- 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
- 10: veth2@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
- link/ether ba:51:66:8e:b8:19 brd ff:ff:ff:ff:ff:ff link-netnsid 0
- inet 10.10.1.3/24 scope global veth2
- valid_lft forever preferred_lft forever
- inet6 fe80::b851:66ff:fe8e:b819/64 scope link
- valid_lft forever preferred_lft forever
现在,有一根网线(veth-pair)把ns和bridg连接起来,但是bridge并没有配置IP地址,也没有启动。如果bridge没有IP地址,Linux协议栈不会给brige转发数据。所以我们需要配置bridge的地址以及启动它。
- #配置bridge的地址
- ip addr add 10.10.1.1/24 dev bridge0
- #配置bridge0启动
- ip link set bridge0 up
- #查看配置好的bridge0
- [root@localhost ~]# ip addr show bridge0
- 6: bridge0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
- link/ether 52:bf:16:34:9e:31 brd ff:ff:ff:ff:ff:ff
- inet 10.10.1.1/24 scope global bridge0
- valid_lft forever preferred_lft forever
- inet6 fe80::50bf:16ff:fe34:9e31/64 scope link
- valid_lft forever preferred_lft forever
验证网络的联通性
- [root@localhost ~]# ip netns exec net1 ping -c 4 10.10.1.3
- PING 10.10.1.3 (10.10.1.3) 56(84) bytes of data.
- 64 bytes from 10.10.1.3: icmp_seq=1 ttl=64 time=0.055 ms
- 64 bytes from 10.10.1.3: icmp_seq=2 ttl=64 time=0.057 ms
- 64 bytes from 10.10.1.3: icmp_seq=3 ttl=64 time=0.059 ms
- 64 bytes from 10.10.1.3: icmp_seq=4 ttl=64 time=0.064 ms
-
- --- 10.10.1.3 ping statistics ---
- 4 packets transmitted, 4 received, 0% packet loss, time 3000ms
- rtt min/avg/max/mdev = 0.055/0.058/0.064/0.009 ms
- [root@localhost ~]# ip netns exec net2 ping -c 4 10.10.1.2
- PING 10.10.1.2 (10.10.1.2) 56(84) bytes of data.
- 64 bytes from 10.10.1.2: icmp_seq=1 ttl=64 time=0.055 ms
- 64 bytes from 10.10.1.2: icmp_seq=2 ttl=64 time=0.060 ms
- 64 bytes from 10.10.1.2: icmp_seq=3 ttl=64 time=0.066 ms
- 64 bytes from 10.10.1.2: icmp_seq=4 ttl=64 time=0.063 ms
-
- --- 10.10.1.2 ping statistics ---
- 4 packets transmitted, 4 received, 0% packet loss, time 3002ms
- rtt min/avg/max/mdev = 0.055/0.061/0.066/0.004 ms
默认情况下,每个ns是无法ping通自己的,是因为默认的lo设备是DOWN状态的,所以,我们需要把lo设备启动了,这样就可以ping通自己了。
- [root@localhost ~]# ip netns exec net2 ping -c 4 10.10.1.3
- PING 10.10.1.3 (10.10.1.3) 56(84) bytes of data.
- ^C
- --- 10.10.1.3 ping statistics ---
- 2 packets transmitted, 0 received, 100% packet loss, time 1000ms
-
- [root@localhost ~]# ^C
- [root@localhost ~]# ip netns exec net2 ip link set lo up
- [root@localhost ~]# ip netns exec net2 ping -c 4 10.10.1.3
- PING 10.10.1.3 (10.10.1.3) 56(84) bytes of data.
- 64 bytes from 10.10.1.3: icmp_seq=1 ttl=64 time=0.033 ms
- ^C
- --- 10.10.1.3 ping statistics ---
- 1 packets transmitted, 1 received, 0% packet loss, time 0ms
- rtt min/avg/max/mdev = 0.033/0.033/0.033/0.000 ms
以上实验的拓扑图如下所示:
正常的容器中,我们能和宿主机以及外部的网络通信,但是我们在隔离的网络中无法ping通宿主机的,唉?这是怎么回事呢?
- [root@localhost ~]# ip netns exec net2 ping 192.168.159.14
- connect: Network is unreachable
接下来,我们将实现ns和外部的网络互连。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。