Linux网络之namespace、bridge、veth

namespace

前言

namespace是Linux虚拟网络的一个重要概念,传统的Linux的许多资源是全局的,如果进程id资源。而namespace的目的首先就是讲这些资源做资源隔离。Linux可以在一个Host内创建许多namespace,于是那些原本是linux的全局资源,就变成了namespace范围内的“全局”资源,而且不同namespace的资源相互不可见,彼此透明。

Linux namespace 可以隔离的资源有:uts_ns(内存、版本等底层信息)、ipc_ns(所有与进程通信的信息)、 mnt_ns(当前装载的文件系统)、 pid_ns(有关进程id的信息)、 user_ns(资源配额的信息)、 net_ns(网络信息)。

一个设备(Linux Device)只能位于一个namespace中,不同namespace中的设备可以利用veth pair进行桥接。

命令实操

Linux 操作namespace的命令是ip netns。

  1. [root@virtual ~]# ip netns help
  2. Usage: ip netns list
  3. ip netns add NAME
  4. ip netns set NAME NETNSID
  5. ip [-all] netns delete [NAME]
  6. ip netns identify [PID]
  7. ip netns pids NAME
  8. ip [-all] netns exec [NAME] cmd ...
  9. ip netns monitor
  10. ip netns list-id
  11. [root@virtual ~]#

首先创建一个namespace:

  1. # 查看namespace列表
  2. [root@virtual ~]# ip netns list
  3. [root@virtual ~]#
  4. # 新增 namespace ns_test
  5. [root@virtual ~]# ip netns add ns_test
  6. [root@virtual ~]#
  7. [root@virtual ~]# ip netns list
  8. ns_test
  9. [root@virtual ~]#

当创建一个namespace后,就可以将一些虚拟设备迁移到这个namespace中去了,比如上一篇中介绍的tap。

  1. # 创建tap,并配置对应IP,详细信息可看上一篇文档
  2. [root@virtual ~]# tunctl -t tap_test
  3. Set 'tap_test' persistent and owned by uid 0
  4. [root@virtual ~]# ip link list
  5. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
  6. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  7. 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
  8. link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff
  9. 3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
  10. link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff
  11. [root@virtual ~]# ip addr show
  12. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
  13. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  14. inet 127.0.0.1/8 scope host lo
  15. valid_lft forever preferred_lft forever
  16. inet6 ::1/128 scope host
  17. valid_lft forever preferred_lft forever
  18. 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  19. link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff
  20. inet 10.0.0.176/24 brd 10.0.0.255 scope global noprefixroute dynamic eth0
  21. valid_lft 75898sec preferred_lft 75898sec
  22. inet6 fe80::f816:3eff:fe56:6a87/64 scope link
  23. valid_lft forever preferred_lft forever
  24. 3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
  25. link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff
  26. [root@virtual ~]# ip addr add local 10.0.0.190/24 dev tap_test
  27. [root@virtual ~]# ip a show
  28. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
  29. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  30. inet 127.0.0.1/8 scope host lo
  31. valid_lft forever preferred_lft forever
  32. inet6 ::1/128 scope host
  33. valid_lft forever preferred_lft forever
  34. 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  35. link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff
  36. inet 10.0.0.176/24 brd 10.0.0.255 scope global noprefixroute dynamic eth0
  37. valid_lft 75813sec preferred_lft 75813sec
  38. inet6 fe80::f816:3eff:fe56:6a87/64 scope link
  39. valid_lft forever preferred_lft forever
  40. 3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
  41. link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff
  42. inet 10.0.0.190/24 scope global tap_test
  43. valid_lft forever preferred_lft forever
  44. [root@virtual ~]#
  45. # 创建namespace后,将前面创建的tap_test迁移到这个namespace中。
  46. # 迁移之后,在外直接 ip a s 已经看不到这个虚拟设备了
  47. [root@virtual ~]#
  48. [root@virtual ~]# ip link set tap_test netns ns_test
  49. [root@virtual ~]#
  50. [root@virtual ~]# ip netns exec ns_test ip a s
  51. 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
  52. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  53. 3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
  54. link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff
  55. [root@virtual ~]# ip netns exec ns_test ip addr add 192.168.10.190/24 dev tap_test
  56. [root@virtual ~]# ip netns exec ns_test ip a s
  57. 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
  58. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  59. 3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
  60. link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff
  61. inet 192.168.10.190/24 scope global tap_test
  62. valid_lft forever preferred_lft forever
  63. [root@virtual ~]#

veth pair

前言

veth pair 不是一个设备,而是一对设备,以连接两个虚拟以太端口。操作veth pair,需要跟namespace一起配合,不然就没有意义。

简单的拓扑图:
70

两个namespace ns1/ns2 中各有一个tap组成veth pair,两个tap 上配置的ip进行互ping。

命令实操

  1. # 创建 veth pair
  2. [root@virtual ~]# ip link add tap1 type veth peer name tap2
  3. [root@virtual ~]# ip a s
  4. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
  5. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  6. inet 127.0.0.1/8 scope host lo
  7. valid_lft forever preferred_lft forever
  8. inet6 ::1/128 scope host
  9. valid_lft forever preferred_lft forever
  10. 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  11. link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff
  12. inet 10.0.0.176/24 brd 10.0.0.255 scope global noprefixroute dynamic eth0
  13. valid_lft 64021sec preferred_lft 64021sec
  14. inet6 fe80::f816:3eff:fe56:6a87/64 scope link
  15. valid_lft forever preferred_lft forever
  16. 6: tap2@tap1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
  17. link/ether a6:74:e9:cb:8f:f1 brd ff:ff:ff:ff:ff:ff
  18. 7: tap1@tap2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
  19. link/ether 02:d1:8c:8b:44:e9 brd ff:ff:ff:ff:ff:ff
  20. [root@virtual ~]#
  21. # 创建namespace,并将tap迁移至namespace中:
  22. [root@virtual ~]# ip netns add ns1
  23. [root@virtual ~]# ip netns add ns2
  24. [root@virtual ~]# ip link set tap1 netns ns1
  25. [root@virtual ~]# ip link set tap2 netns ns2
  26. [root@virtual ~]# ip netns exec ns1 ip addr add local 192.168.10.200/24 dev tap1
  27. [root@virtual ~]# ip netns exec ns2 ip addr add local 192.168.10.201/24 dev tap2
  28. [root@virtual ~]# ip netns exec ns1 ifconfig tap1 up
  29. [root@virtual ~]# ip netns exec ns2 ifconfig tap2 up
  30. [root@virtual ~]#
  31. [root@virtual ~]# ip link list
  32. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
  33. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  34. 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
  35. link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff
  36. [root@virtual ~]# ip netns list
  37. ns2
  38. ns1 (id: 0)
  39. ns_test
  40. [root@virtual ~]#
  41. [root@virtual ~]# ip netns exec ns1 ping 192.168.10.201
  42. PING 192.168.10.201 (192.168.10.201) 56(84) bytes of data.
  43. 64 bytes from 192.168.10.201: icmp_seq=1 ttl=64 time=0.028 ms
  44. 64 bytes from 192.168.10.201: icmp_seq=2 ttl=64 time=0.027 ms
  45. 64 bytes from 192.168.10.201: icmp_seq=3 ttl=64 time=0.026 ms
  46. 64 bytes from 192.168.10.201: icmp_seq=4 ttl=64 time=0.023 ms
  47. ^C
  48. --- 192.168.10.201 ping statistics ---
  49. 4 packets transmitted, 4 received, 0% packet loss, time 2999ms
  50. rtt min/avg/max/mdev = 0.023/0.026/0.028/0.002 ms
  51. [root@virtual ~]# ip netns exec ns1 ip a
  52. 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
  53. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  54. 7: tap1@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
  55. link/ether 02:d1:8c:8b:44:e9 brd ff:ff:ff:ff:ff:ff link-netnsid 1
  56. inet 192.168.10.200/24 scope global tap1
  57. valid_lft forever preferred_lft forever
  58. inet6 fe80::d1:8cff:fe8b:44e9/64 scope link
  59. valid_lft forever preferred_lft forever
  60. [root@virtual ~]# ip netns exec ns2 ip a s
  61. 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
  62. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  63. 6: tap2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
  64. link/ether a6:74:e9:cb:8f:f1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
  65. inet 192.168.10.201/24 scope global tap2
  66. valid_lft forever preferred_lft forever
  67. inet6 fe80::a474:e9ff:fecb:8ff1/64 scope link
  68. valid_lft forever preferred_lft forever
  69. [root@virtual ~]#

通过以上的测试用例,可以了解通过veth pair连接两个namespace的方法。

后面会有依靠Bridge/Switch 实现三个或多个namespace进行互通。

Bridge

前言

在Linux的语境中,Bridge和Switch是一个概念。Bridge是一个虚拟网络设备,所以具有网络设备的特征,可以配置IP、MAC地址等;Bridge是一个虚拟交换机,和物理交换机有类似的功能。对于普通的网络设备来说,只有两端,从一端进来的数据会从另一端出去,如物理网卡从外面网络中收到的数据会转发给内核协议栈,而从协议栈过来的数据会转发到外面的物理网络中。 而Bridge不同,Bridge有多个端口,数据可以从任何端口进来,进来之后从哪个口出去和物理交换机的原理差不多,要看mac地址。

命令实操

Linux实现Bridge功能是brctl模块。可以直接在命令行上查看,如果没有回显的话,可直接使用yum进行安装。

  1. [root@virtual ~]# brctl
  2. -bash: brctl: command not found
  3. [root@virtual ~]# yum -y install bridge-utils
  4. Loaded plugins: fastestmirror
  5. Loading mirror speeds from cached hostfile
  6. ......
  7. Running transaction
  8. Installing : bridge-utils-1.5-9.el7.x86_64 1/1
  9. Verifying : bridge-utils-1.5-9.el7.x86_64 1/1
  10. Installed:
  11. bridge-utils.x86_64 0:1.5-9.el7
  12. Complete!
  13. [root@virtual ~]# brctl
  14. Usage: brctl [commands]
  15. commands:
  16. addbr <bridge> add bridge
  17. delbr <bridge> delete bridge
  18. addif <bridge> <device> add interface to bridge
  19. delif <bridge> <device> delete interface from bridge
  20. hairpin <bridge> <port> {
  21. on|off} turn hairpin on/off
  22. setageing <bridge> <time> set ageing time
  23. setbridgeprio <bridge> <prio> set bridge priority
  24. setfd <bridge> <time> set bridge forward delay
  25. sethello <bridge> <time> set hello time
  26. setmaxage <bridge> <time> set max message age
  27. setpathcost <bridge> <port> <cost> set path cost
  28. setportprio <bridge> <port> <prio> set port priority
  29. show [ <bridge> ] show a list of bridges
  30. showmacs <bridge> show a list of mac addrs
  31. showstp <bridge> show bridge stp info
  32. stp <bridge> {
  33. on|off} turn stp on/off
  34. [root@virtual ~]#

根据如下拓扑图,我们模拟创建相应的虚拟网络设备,进行实现:

拓扑图:
70 1

命令操作:

  1. # 创建对于设备
  2. [root@virtual ~]# ip link add tap1 type veth peer name tap1_peer
  3. [root@virtual ~]# ip link add tap2 type veth peer name tap2_peer
  4. [root@virtual ~]# ip link add tap3 type veth peer name tap3_peer
  5. [root@virtual ~]# ip link add tap4 type veth peer name tap4_peer
  6. [root@virtual ~]#
  7. [root@virtual ~]# ip a s | grep tap
  8. 8: tap1_peer@tap1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
  9. 9: tap1@tap1_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
  10. 10: tap2_peer@tap2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
  11. 11: tap2@tap2_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
  12. 12: tap3_peer@tap3: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
  13. 13: tap3@tap3_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
  14. 14: tap4_peer@tap4: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
  15. 15: tap4@tap4_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
  16. [root@virtual ~]#
  17. [root@virtual ~]# ip netns list
  18. ns_test
  19. [root@virtual ~]# ip netns add ns1
  20. [root@virtual ~]# ip netns add ns2
  21. [root@virtual ~]# ip netns add ns3
  22. [root@virtual ~]# ip netns add ns4
  23. [root@virtual ~]# ip netns list
  24. ns4
  25. ns3
  26. ns2
  27. ns1
  28. ns_test
  29. [root@virtual ~]#
  30. # 将设备迁移至namespace
  31. [root@virtual ~]# ip link set tap1 netns ns1
  32. [root@virtual ~]# ip link set tap2 netns ns2
  33. [root@virtual ~]# ip link set tap3 netns ns3
  34. [root@virtual ~]# ip link set tap4 netns ns4
  35. [root@virtual ~]#
  36. # 创建 Bridge
  37. [root@virtual ~]# brctl addbr br1
  38. [root@virtual ~]# ip a s | grep br1
  39. 17: br1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
  40. [root@virtual ~]#
  41. # 将tap 添加到 Bridge中
  42. [root@virtual ~]# brctl addif br1 tap1_peer
  43. [root@virtual ~]# brctl addif br1 tap2_peer
  44. [root@virtual ~]# brctl addif br1 tap3_beer
  45. interface tap3_beer does not exist!
  46. [root@virtual ~]# brctl addif br1 tap3_peer
  47. [root@virtual ~]# brctl addif br1 tap4_peer
  48. [root@virtual ~]#
  49. # 配置 tap 对应的ip地址
  50. [root@virtual ~]# ip netns exec ns1 ip addr add local 192.168.10.200/24 dev tap1
  51. [root@virtual ~]# ip netns exec ns2 ip addr add local 192.168.10.201/24 dev tap2
  52. [root@virtual ~]# ip netns exec ns3 ip addr add local 192.168.10.202/24 dev tap3
  53. [root@virtual ~]# ip netns exec ns4 ip addr add local 192.168.10.203/24 dev tap4
  54. [root@virtual ~]#
  55. # 将 Bridge 以及所有 tap 状态设置为 up
  56. [root@virtual ~]# ip link set br1 up
  57. [root@virtual ~]# ip link set tap1_peer up
  58. [root@virtual ~]# ip link set tap2_peer up
  59. [root@virtual ~]# ip link set tap3_peer up
  60. [root@virtual ~]# ip link set tap4_peer up
  61. [root@virtual ~]# ip netns exec ns1 ip link set tap1 up
  62. [root@virtual ~]# ip netns exec ns2 ip link set tap2 up
  63. [root@virtual ~]# ip netns exec ns3 ip link set tap3 up
  64. [root@virtual ~]# ip netns exec ns4 ip link set tap4 up
  65. [root@virtual ~]#
  66. # 相互进行ip 互ping ,验证网络连通
  67. [root@virtual ~]# ip netns exec ns1 ping 192.168.10.201
  68. PING 192.168.10.201 (192.168.10.201) 56(84) bytes of data.
  69. 64 bytes from 192.168.10.201: icmp_seq=1 ttl=64 time=0.041 ms
  70. 64 bytes from 192.168.10.201: icmp_seq=2 ttl=64 time=0.032 ms
  71. 64 bytes from 192.168.10.201: icmp_seq=3 ttl=64 time=0.031 ms
  72. 64 bytes from 192.168.10.201: icmp_seq=4 ttl=64 time=0.027 ms
  73. ^C
  74. --- 192.168.10.201 ping statistics ---
  75. 4 packets transmitted, 4 received, 0% packet loss, time 2999ms
  76. rtt min/avg/max/mdev = 0.027/0.032/0.041/0.008 ms
  77. [root@virtual ~]# ip netns exec ns1 ping 192.168.10.202
  78. PING 192.168.10.202 (192.168.10.202) 56(84) bytes of data.
  79. 64 bytes from 192.168.10.202: icmp_seq=1 ttl=64 time=0.041 ms
  80. 64 bytes from 192.168.10.202: icmp_seq=2 ttl=64 time=0.033 ms
  81. 64 bytes from 192.168.10.202: icmp_seq=3 ttl=64 time=0.037 ms
  82. 64 bytes from 192.168.10.202: icmp_seq=4 ttl=64 time=0.027 ms
  83. ^C
  84. --- 192.168.10.202 ping statistics ---
  85. 4 packets transmitted, 4 received, 0% packet loss, time 2999ms
  86. rtt min/avg/max/mdev = 0.027/0.034/0.041/0.007 ms
  87. [root@virtual ~]# ip netns exec ns1 ping 192.168.10.203
  88. PING 192.168.10.203 (192.168.10.203) 56(84) bytes of data.
  89. 64 bytes from 192.168.10.203: icmp_seq=1 ttl=64 time=0.059 ms
  90. 64 bytes from 192.168.10.203: icmp_seq=2 ttl=64 time=0.027 ms
  91. 64 bytes from 192.168.10.203: icmp_seq=3 ttl=64 time=0.033 ms
  92. 64 bytes from 192.168.10.203: icmp_seq=4 ttl=64 time=0.031 ms
  93. ^C
  94. --- 192.168.10.203 ping statistics ---
  95. 4 packets transmitted, 4 received, 0% packet loss, time 2999ms
  96. rtt min/avg/max/mdev = 0.027/0.037/0.059/0.014 ms
  97. [root@virtual ~]#
  98. [root@virtual ~]# ip netns exec ns4 ping 192.168.10.200
  99. PING 192.168.10.200 (192.168.10.200) 56(84) bytes of data.
  100. 64 bytes from 192.168.10.200: icmp_seq=1 ttl=64 time=0.022 ms
  101. 64 bytes from 192.168.10.200: icmp_seq=2 ttl=64 time=0.024 ms
  102. 64 bytes from 192.168.10.200: icmp_seq=3 ttl=64 time=0.033 ms
  103. 64 bytes from 192.168.10.200: icmp_seq=4 ttl=64 time=0.030 ms
  104. ^X^C
  105. --- 192.168.10.200 ping statistics ---
  106. 4 packets transmitted, 4 received, 0% packet loss, time 2999ms
  107. rtt min/avg/max/mdev = 0.022/0.027/0.033/0.005 ms
  108. [root@virtual ~]#
赞(0) 打赏
未经允许不得转载:IT火车 » Linux网络之namespace、bridge、veth

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

1元打赏送给作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏