当前位置:   article > 正文

【Docker网络原理分析一】创建ns+bridge实现两个隔离网络通信_bridge组件负责联通隔离和开放环境

bridge组件负责联通隔离和开放环境

环境: centos7.3

前提:最好了解namespace和bridge

docker的学习以及docker网络的学习也有一段时间了,想通过linux的一些命令以及namespace和路由实现一个类似docker网络的结构。我们先创建两个网络namespace,相当于创建两个容器实现网络隔离。我们再通过brctl创建一个linux的网桥,这个网桥就类似于docker中的docker0网桥。创建两个了隔离的ns我们就可以想象成两天新买的服务器,它们没有网络配置。而新建的网桥就相当于一个类似路由器的设备。我们接下来就需要给两个"新的服务器"(ns)配置IP以及连接它们到网桥上。这样就完成了第一步,连接在"网桥"上的"两台主机"是可以通信的。

创建两个ns(可以类比于新买的两台服务器)

  1. #创建两个ns
  2. ip netns add net1
  3. ip netns add net2
  1. #创建成功了,查看两个ns
  2. ip netns list
  3. #如果创建错误了,使用下面命令删除
  4. ip netns del <netns-name>

创建一个linux的网桥

  1. #没有brctl先安装
  2. yum install -y bridge-utils
  1. #创建一个linux的网桥
  2. brctl addbr bridge0
  1. #查看创建的网桥,注意新建网桥的state的是DOWN
  2. #还能看到新建的网桥并没有配置IP
  3. [root@localhost ~]# ip addr show bridge0
  4. 6: bridge0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
  5. link/ether fe:ff:11:30:b3:fd brd ff:ff:ff:ff:ff:ff
  6. #通过brctl show查看,可以查看网桥上依附的接口
  7. [root@localhost ~]# brctl show
  8. bridge name bridge id STP enabled interfaces
  9. bridge0 8000.000000000000 no

以上的操作,我们先创建两个ns(两个服务器),一个bridge(路由器),接下来我们需要通过这个bridge让两个ns(两个服务器)能相互通信。现实社会中,我们需要一个网线把他们连接起来,在虚拟网络中,我们需要veth-pair设备,它是一对虚拟的网络设备对。就像使用网线那样,我们一端放在ns中,一端依附在网桥上,同时给ns端的设备配上IP地址。同时也给网桥配上IP地址。同理,我们也给另一个ns做相同的操作。这样就相当于,两台服务器通过网络设备对veth-pair 连接到路由器上。

  1. #创建两对veth-pair设备
  2. ip link add veth1 type veth peer name veth_peer1
  3. ip link add veth2 type veth peer name veth_peer2
  1. #查看创建的veth-pair设备(部分截图)
  2. #新创建的设备都是DOWN状态,我们需要他们都启动了
  3. 7: veth_peer1@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
  4. link/ether d2:64:d2:45:4d:33 brd ff:ff:ff:ff:ff:ff
  5. 8: veth1@veth_peer1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
  6. link/ether 42:54:a0:9b:a3:56 brd ff:ff:ff:ff:ff:ff
  7. 9: veth_peer2@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
  8. link/ether 52:bf:16:34:9e:31 brd ff:ff:ff:ff:ff:ff
  9. 10: veth2@veth_peer2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
  10. link/ether ba:51:66:8e:b8:19 brd ff:ff:ff:ff:ff:ff

现在创建好了网线,我们需要一端放入ns中。一端附着到网桥中,并且把他们state都启动起来。

  1. #把veth1放到ns1
  2. ip link set veth1 netns net1
  3. #把veth_peer1依附到bridge0
  4. ip link set veth_peer1 master bridge0
  5. #把veth_peer1设置为启动状态
  6. ip link set veth_peer1 up
  7. #同理,下面的操作
  8. ip link set veth2 netns net2
  9. ip link set veth_peer2 master bridge0
  10. ip link set veth_peer2 up

查看veth_peer的状态,以及依附到网桥上的接口

  1. 7: veth_peer1@if8: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master bridge0 state LOWERLAYERDOWN group default qlen 1000
  2. link/ether d2:64:d2:45:4d:33 brd ff:ff:ff:ff:ff:ff link-netnsid 1
  3. 9: veth_peer2@if10: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master bridge0 state LOWERLAYERDOWN group default qlen 1000
  4. link/ether 52:bf:16:34:9e:31 brd ff:ff:ff:ff:ff:ff link-netnsid 2
  1. [root@localhost ~]# brctl show
  2. bridge name bridge id STP enabled interfaces
  3. bridge0 8000.52bf16349e31 no veth_peer1
  4. veth_peer2

我们给veth-pair依附到bridge上,另一端放入ns中,接下来需要把ns中的虚拟设备配置好IP并且启动。相当于服务器的网卡配置IP并且启动网卡。

  1. #因为不同的ns,网络操作都是隔离的,我们需要在各自的ns中执行操作,就相当于各自的服务器中执行操作
  2. #给net1中的veth1配置IP
  3. ip netns exec net1 ip addr add 10.10.1.2/24 dev veth1
  4. #设置veth1状态是UP
  5. ip netns exec net1 ip link set veth1 up
  6. #查看net1中的网络设备
  7. [root@localhost ~]# ip netns exec net1 ip addr
  8. 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
  9. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  10. 8: veth1@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
  11. link/ether 42:54:a0:9b:a3:56 brd ff:ff:ff:ff:ff:ff link-netnsid 0
  12. inet 10.10.1.2/24 scope global veth1
  13. valid_lft forever preferred_lft forever
  14. inet6 fe80::4054:a0ff:fe9b:a356/64 scope link
  15. valid_lft forever preferred_lft forever
  16. #同理,我们配置ns2
  17. [root@localhost ~]# ip netns exec net2 ip addr add 10.10.1.3/24 dev veth2
  18. [root@localhost ~]# ip netns exec net2 ip link set veth2 up
  19. [root@localhost ~]# ip netns exec net2 ip addr
  20. 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
  21. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  22. 10: veth2@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
  23. link/ether ba:51:66:8e:b8:19 brd ff:ff:ff:ff:ff:ff link-netnsid 0
  24. inet 10.10.1.3/24 scope global veth2
  25. valid_lft forever preferred_lft forever
  26. inet6 fe80::b851:66ff:fe8e:b819/64 scope link
  27. valid_lft forever preferred_lft forever

现在,有一根网线(veth-pair)把ns和bridg连接起来,但是bridge并没有配置IP地址,也没有启动。如果bridge没有IP地址,Linux协议栈不会给brige转发数据。所以我们需要配置bridge的地址以及启动它。

  1. #配置bridge的地址
  2. ip addr add 10.10.1.1/24 dev bridge0
  3. #配置bridge0启动
  4. ip link set bridge0 up
  5. #查看配置好的bridge0
  6. [root@localhost ~]# ip addr show bridge0
  7. 6: bridge0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
  8. link/ether 52:bf:16:34:9e:31 brd ff:ff:ff:ff:ff:ff
  9. inet 10.10.1.1/24 scope global bridge0
  10. valid_lft forever preferred_lft forever
  11. inet6 fe80::50bf:16ff:fe34:9e31/64 scope link
  12. valid_lft forever preferred_lft forever

验证网络的联通性

  1. [root@localhost ~]# ip netns exec net1 ping -c 4 10.10.1.3
  2. PING 10.10.1.3 (10.10.1.3) 56(84) bytes of data.
  3. 64 bytes from 10.10.1.3: icmp_seq=1 ttl=64 time=0.055 ms
  4. 64 bytes from 10.10.1.3: icmp_seq=2 ttl=64 time=0.057 ms
  5. 64 bytes from 10.10.1.3: icmp_seq=3 ttl=64 time=0.059 ms
  6. 64 bytes from 10.10.1.3: icmp_seq=4 ttl=64 time=0.064 ms
  7. --- 10.10.1.3 ping statistics ---
  8. 4 packets transmitted, 4 received, 0% packet loss, time 3000ms
  9. rtt min/avg/max/mdev = 0.055/0.058/0.064/0.009 ms
  1. [root@localhost ~]# ip netns exec net2 ping -c 4 10.10.1.2
  2. PING 10.10.1.2 (10.10.1.2) 56(84) bytes of data.
  3. 64 bytes from 10.10.1.2: icmp_seq=1 ttl=64 time=0.055 ms
  4. 64 bytes from 10.10.1.2: icmp_seq=2 ttl=64 time=0.060 ms
  5. 64 bytes from 10.10.1.2: icmp_seq=3 ttl=64 time=0.066 ms
  6. 64 bytes from 10.10.1.2: icmp_seq=4 ttl=64 time=0.063 ms
  7. --- 10.10.1.2 ping statistics ---
  8. 4 packets transmitted, 4 received, 0% packet loss, time 3002ms
  9. rtt min/avg/max/mdev = 0.055/0.061/0.066/0.004 ms

默认情况下,每个ns是无法ping通自己的,是因为默认的lo设备是DOWN状态的,所以,我们需要把lo设备启动了,这样就可以ping通自己了。

  1. [root@localhost ~]# ip netns exec net2 ping -c 4 10.10.1.3
  2. PING 10.10.1.3 (10.10.1.3) 56(84) bytes of data.
  3. ^C
  4. --- 10.10.1.3 ping statistics ---
  5. 2 packets transmitted, 0 received, 100% packet loss, time 1000ms
  6. [root@localhost ~]# ^C
  7. [root@localhost ~]# ip netns exec net2 ip link set lo up
  8. [root@localhost ~]# ip netns exec net2 ping -c 4 10.10.1.3
  9. PING 10.10.1.3 (10.10.1.3) 56(84) bytes of data.
  10. 64 bytes from 10.10.1.3: icmp_seq=1 ttl=64 time=0.033 ms
  11. ^C
  12. --- 10.10.1.3 ping statistics ---
  13. 1 packets transmitted, 1 received, 0% packet loss, time 0ms
  14. rtt min/avg/max/mdev = 0.033/0.033/0.033/0.000 ms

以上实验的拓扑图如下所示:

正常的容器中,我们能和宿主机以及外部的网络通信,但是我们在隔离的网络中无法ping通宿主机的,唉?这是怎么回事呢?

  1. [root@localhost ~]# ip netns exec net2 ping 192.168.159.14
  2. connect: Network is unreachable

接下来,我们将实现ns和外部的网络互连。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/999692
推荐阅读
相关标签
  

闽ICP备14008679号