你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

学习下Linux网络虚拟化技术

[复制链接]
gaosmile 发布时间:2020-9-6 20:47
背景

在Linux虚拟化技术中,网络层面,通常重要的三个技术分别是Network Namespace、veth pair、以及网桥或虚拟交换机技术。今天就通过实验带大家一起学习下Linux网络虚拟化技术。

我们首先了解下Network Namespace,它是由Linux内核提供,是实现网络虚拟化的重要功能。通过创建多个隔离的网络空间,实现网络资源的隔离。

不同的Network Namespace的资源互相不可见,彼此之间无法通信。如下图所示:

微信图片_20200906204301.png Network Namespace6 Y/ [7 D1 u7 e0 R( \

- d/ Z' W* u7 b# J- z9 Yip netns命令

Network Namespace是Linux内核提供的功能,本文借助ip命令来完成各种操作。ip命令来自于iproute2安装包,一般系统默认安装,如果没有的话,读者可自行安装。

ip命令管理的功能很多,和Network Namespace有关的操作都在其子命令ip netns下进行的,可以通过ip netns help查询命令帮助信息

[root@qll253 ~]# ip netns help4 e$ G0 s* ]. r, A# n& k; n
Usage: ip netns list2 _1 ^  i( s/ {+ |
       ip netns add NAME6 C! w$ Y. ]3 R0 h% x% [
       ip netns set NAME NETNSID
/ H2 U' t- M1 L9 h0 @* J& V) l       ip [-all] netns delete [NAME]
5 Z/ i8 K" X" V8 N2 s       ip netns identify [PID]
/ G  m/ I. w& h8 F7 s5 Y/ R( `       ip netns pids NAME
  @2 p8 d% `4 ~' {$ m; q3 d( s0 L- {       ip [-all] netns exec [NAME] cmd ...
' G3 ]+ o& `3 T       ip netns monitor# A) e  q! g  d4 j. @7 c' @  e: b/ A
       ip netns list-id
5 E& J+ u& m& ?& f
创建Network Namespace
, w1 E5 s( y* O/ y1、通过 ip netns add 命令创建一个名为ns0的网络命名空间:$ t% v) R$ C( H
[root@1ll253 ~]# ip netns add ns0& H) ]% I. f( {# p
2、查询命名空间# L: `- d0 J( Y7 V
[root@1ll253 ~]# ip netns list, f7 J$ w# y, P3 A4 y' F9 V
ns0. V9 s) g! t/ h5 e' E
3、命名空间所在目录
5 ?$ I$ h: K1 M# L, b( Q! f[root@1ll253 ~]# ls /var/run/netns/- Q5 R2 F3 s! V! I
ns0
" ^+ _3 _% s4 K& T" K

注意:新创建的 Network Namespace 会出现在/var/run/netns/目录下。如果需要管理其他不是 ip netns 创建的 network namespace,只要在这个目录下创建一个指向对应 network namespace 文件的链接即可。

操作Network Namespace

对于每个 Network Namespace 来说,它会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源。ip命令提供了ip netns exec子命令可以在对应的 Network Namespace 中执行命令。

1、查看网络命名空间 ns0 的网卡信息
- y' n: U- \8 @; l+ G[root@1ll253 ~]# ip netns exec ns0 ip addr- g/ r/ c5 Q, p! H7 U( M
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 10004 c: L) Y5 t# j) Y3 e, z, g
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
1 Q" G3 R+ E4 |$ T# s+ c- ^/ }: `

每个 namespace 在创建时会自动创建一个回环接口lo,默认不启用。它的作用和Linux系统中默认看到的lo一样,都是为了实现loopback通信,如果希望lo口能工作,可以通过下面的步骤2启用它。

2、启用lo回环网卡:
) ]" p3 m2 I% B& k( K9 O6 o8 A/ ][root@1ll253 ~]# ip netns exec ns0 ip link set lo up" n" z# M+ @: `* O/ F

再次检查回环网卡状态:

[root@1ll253 ~]# ip netns exec ns0 ip addr+ x$ i6 `9 K; ^* T; r) {
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000# [+ o9 v) A* `: o& C7 z( v3 S
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00! A% G) D: O' ?( I9 @3 T. o% u
    inet 127.0.0.1/8 scope host lo9 F/ _  u! A$ i  D6 W5 d: T! H# E
       valid_lft forever preferred_lft forever
* T$ R# [+ i5 B, ?% n  Z! L" C    inet6 ::1/128 scope host / r2 m  z  m, Z& c% E  @- t, x+ _2 C
       valid_lft forever preferred_lft forever
) h3 z, A9 a: t

会发现此时回环口卡处于UP状态,并且系统分配127.0.0.1/8的ip地址。

3、在 ns0 中打开一个shell终端
* ]( {- X) f  \7 o- G+ w/ R[root@1ll253 ~]# ip netns exec ns0 /bin/bash
" p$ l6 l! P4 u  |2 ]( i6 g' D[root@1ll253 ~]# ip addr
; |- v9 M) x5 t% j! a: P. W( r  D+ y1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
; d/ a2 K* \2 y% @; n    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
) |8 m' h5 V. h6 c( j# V% h    inet 127.0.0.1/8 scope host lo
; M8 H) H& \1 c  T9 N       valid_lft forever preferred_lft forever% M7 B, A( h" o+ V! Y% W$ j
[root@1ll253 ~]# exit  a2 ]- s) o" p/ p; o
exit& K4 I  t9 l# m, h

通过执行ip netns exec ns0 /bin/bash进入ns0的shell终端,后面所有的命令都在这个Network Namespace中执行,好处是不用每次执行命令时都要带上ip netns exec ,缺点是我们无法清楚知道自己当前所在的shell,容易混淆。

可以采用下面的方法解决:

[root@1ll253 ~]# ip netns exec ns0 /bin/bash --rcfile <(echo "PS1=\"ns0> \"")2 D: T1 b2 x( l$ i6 I* {* o
ns0> 9 Z! z/ E' f1 M7 Y  K
Network Namespace 之间的通信

默认情况下,network namespace 是不能和主机网络,或者其他 network namespace 通信的。

可以使用 Linux 提供的veth pair来完成通信,veth pair你可以理解为使用网线连接好的两个接口,把两个端口放到两个namespace中,那么这两个namespace就能打通。

接下来我们通过实验进行验证:

微信图片_20200906204306.png 实验拓扑图
) a4 [$ X- U1 }/ a+ O1、创建veth pair
" v/ l& @6 z# U+ G[root@1ll253 ~]# ip link add type veth
. u0 X8 g* @% j* k6 G. \[root@1ll253 ~]# ip link' z6 b3 j/ ?& f) k  ~7 t' O9 S
14: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000# f- G6 O4 z# {* P+ N
    link/ether 06:17:62:85:64:fc brd ff:ff:ff:ff:ff:ff
* h( o7 k: s: q' y15: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
% k- ~5 \5 W* q! ?/ X* w9 h    link/ether fe:9a:48:e4:a3:99 brd ff:ff:ff:ff:ff:ff' u1 M( K& Z$ _+ _' `) k
[root@1ll253 ~]# 4 [  L/ x. e7 M* [. Z' ?

可以看到,此时系统中新增了一对veth pair:veth0和veth1,需要记住的是veth pair无法单独存在,删除其中一个,另一个也会自动消失。

如果需要指定veth pair两个端点的名称,可以使用下面的命令:

[root@1ll253 ~]# ip link add veth001 type veth peer name veth002
# M8 {) j) N! X4 V1 B[root@1ll253 ~]# ip link
4 T) W! l5 n- ]6 B1 |0 i# V" N* E12: veth002@veth001: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000" q7 B( r: |! o( e- j$ n0 l
    link/ether aa:3e:04:da:a7:69 brd ff:ff:ff:ff:ff:ff
- m# @; E6 f% n5 x13: veth001@veth002: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
$ R7 h4 F8 F* \    link/ether 3e:5d:5f:4e:06:2b brd ff:ff:ff:ff:ff:ff3 L1 }: a7 a& B( e
2、创建Network Namespace

我们已创建了一个名为ns0的Network Namespace,下面再创建一个名称为ns1的网络命名空间。

[root@1ll253 ~]# ip netns add ns1% }# f5 e9 D: A# |" j: q1 M7 f) a
[root@1ll253 ~]# ip netns list
' _4 n$ [# I' f6 M/ Bns1! ^; y6 Z3 ]7 X) P9 A( ~9 G
ns0
) S# {6 |6 u5 x: w0 n0 E
3、把veth pair分别加入到这两个namespace中

将veth0加入到ns0,将veth1加入到ns1,如下所示:

[root@1ll253 ~]# ip link set veth0 netns ns0
) r/ a+ _6 e, m4 `/ \; J( w2 f[root@1ll253 ~]# ip link set veth1 netns ns1
6 n/ l5 n& a# p& ~+ ]6 I
4、分别为这对veth pair配置上ip地址,并启用

1)为veth0配置IP,并启用该虚拟网卡

[root@1ll253 ~]# ip netns exec ns0 ip addr add 192.168.1.1/24 dev veth00 C1 ~" Y2 L+ R! ~, W5 Q" @( i
[root@1ll253 ~]# ip netns exec ns0 ip link set veth0 up
3 X, I3 G9 t: B0 G5 ]/ R, y

2)为veth1配置IP,并启用该虚拟网卡

[root@1ll253 ~]# ip netns exec ns1 ip addr add 192.168.1.2/24 dev veth1: W' U( F& K' t' n& p4 k
[root@1ll253 ~]# ip netns exec ns1 ip link set veth1 up6 f7 R0 F2 w  C2 N. `
5、查看这对veth pair的状态. O) q0 R" R; Q4 c. m; u
微信图片_20200906204312.png & d4 V% T% D; I
6、验证两个Network Namespace之间的互通. Y5 Z% q- I3 Y6 L3 ]1 ]$ b
微信图片_20200906204317.png

可以看到,veth pair成功实现了两个不同Network Namespace之间的网络交互。

网桥

虽然veth pair可以实现两个 Network Namespace 之间的通信,但 veth pair 有一个明显的缺陷,就是只能实现两个网络接口之间的通信。如果多个network namespace需要进行通信,则需要借助bridge。

下面我们通过实验来进行讲解:

微信图片_20200906204334.png 实验拓扑图) |4 @, ?0 f9 d" G% E/ ~- V
0、还原网络环境

为方便接下来的实验,我们把刚刚创建的Network Namespace及veth pair删除,保证纯净的网络环境。

[root@1ll253 ~]# ip netns delete ns0
3 \3 I! g, j- k* b- X[root@1ll253 ~]# ip netns delete ns1
: a# [+ P# c2 k7 d# B; z& W/ I
1、创建3个Network Namespace0 M7 J1 ?8 e) I. E* N% E4 M
[root@1ll253 ~]# ip netns add ns0: Y6 R, Q- [: ?6 q4 n
[root@1ll253 ~]# ip netns add ns1
( M' h2 i% \7 m8 h( C0 E[root@1ll253 ~]# ip netns add ns2& ~/ O. ], \* D  ^
2、创建3对veth pair4 _7 l5 H9 U* v1 P
[root@1ll253 ~]# ip link add type veth& V/ w2 h% U. N+ \) f
[root@1ll253 ~]# ip link
0 }, `1 K7 A& U5 ?2 q16: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
* ]  N! v: X/ w" ~/ J; L4 Z2 w$ o    link/ether ba:fa:d6:14:e1:32 brd ff:ff:ff:ff:ff:ff
* a9 g+ Q- G. z17: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 10004 e# x; ~6 I8 N) C& C# Y  a
    link/ether a2:ef:d9:a5:96:51 brd ff:ff:ff:ff:ff:ff3 t. b; H* y7 M8 u: z; Z
18: veth2@veth3: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
! [: G+ v$ _* Q$ D7 Q+ A9 B    link/ether a2:5b:e7:9e:b1:55 brd ff:ff:ff:ff:ff:ff
. J# M& f! [0 y* U4 v& E1 d6 ^2 X! O( t19: veth3@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 10008 q% _% U/ Y( t! O3 d9 y
    link/ether 92:91:67:ab:69:ac brd ff:ff:ff:ff:ff:ff/ v: Q: Y) q& b) r
20: veth4@veth5: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000. ]1 j' M& v% I. O
    link/ether 8a:c8:35:f6:11:3f brd ff:ff:ff:ff:ff:ff3 E" i2 K8 M4 S" }0 A9 D: \: g
21: veth5@veth4: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 10008 X8 K* ~0 P; d7 w  ]4 k1 F
    link/ether 2a:b7:82:d4:49:d5 brd ff:ff:ff:ff:ff:ff
3 Q; h, K$ C) a. j8 }& E% a
  ?$ {$ M& f" p3 X, B
3、创建网桥2 I; v# c( D; _: w
// 创建名为 docker0 的网桥
8 x: U' o& J1 k9 M# F[root@1ll253 ~]# ip link add docker0 type bridge
% u3 {% ^" `$ X7 \! Z# W4 D/ e5 f2 a- j9 S
//启动 docker0 网桥
% m& V/ T; x& M* ?  a2 L[root@1ll253 ~]# ip link set dev docker0 up
& l4 B+ l( h- Y7 E" |1 K
) Z9 j- A$ v5 h" i" P5 n1 h. B! N+ j" k//为docker0网桥配置IP
* y' Z/ c+ O9 }' \8 S* _[root@1ll253 ~]# ifconfig docker0 172.17.0.1/16; {* \9 y0 E; G

此时可以通过ifconfig命令查看:

微信图片_20200906204341.png docker07 ?/ S4 n# @& {5 p; O, e/ h
4、绑定网口

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

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

// 将veth1添加进ns09 B7 v* m5 e' ]# T- A$ g% R$ P: H. s
[root@1ll253 ~]# ip link set dev veth1 netns ns0
0 \1 {) O  k% p9 I+ U9 a1 }
; A6 x" Z; F! A+ m4 x9 g& F0 S2 c//将veth1重命名为eth03 x  F. N3 N) q# h! u  ]
[root@1ll253 ~]# ip netns exec ns0 ip link set dev veth1 name eth0
4 g3 J" b8 [8 K& P4 d+ z: C0 @8 _* j1 a: z% r0 O4 I7 g% y
//为ns0中的eth0配置ip" E0 b1 X+ H& `" _" m
[root@1ll253 ~]# ip netns exec ns0 ip addr add 172.17.0.101/16 dev eth0
2 k0 B! h3 v6 b5 X8 n- p2 e6 M$ [% o" b
// 启动ns0中的eth0网卡$ @) k5 g5 F0 A$ X. T( H" S5 P+ L
[root@1ll253 ~]# ip netns exec ns0 ip link set dev eth0 up+ q( V+ Q% x& w
7 z# G3 U# L- p
// 将veth0添加加网桥docker0
3 E  r* K/ l5 m[root@1ll253 ~]# ip link set dev veth0 master docker0
! O  {1 M  V& w0 t: L" t* `8 `# z6 ^2 B3 k7 E& X$ b
// 启动veth0网卡  o6 m  F4 {" {7 t2 G' ^* z
[root@1ll253 ~]# ip link set dev veth0 up! f# a# Q3 R. _6 T: m7 S4 W

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

[root@1ll253 ~]# ip link set dev veth3 netns ns14 d9 t. ]4 F/ y; M8 H2 `2 T
[root@1ll253 ~]# ip netns exec ns1 ip link set dev veth3 name eth0
, G$ l7 K2 Q4 P[root@1ll253 ~]# ip netns exec ns1 ip addr add 172.17.0.102/16 dev eth03 z* z* i+ K8 x& V) j# l
[root@1ll253 ~]# ip netns exec ns1 ip link set dev eth0 up1 K( L: d: E6 X) e9 \  L
[root@1ll253 ~]# ip link set dev veth1 master docker0/ K. x; J& H8 j5 Q1 s- }1 u
[root@1ll253 ~]# ip link set dev veth3 up
4 f8 N/ ?. _. X7 L* w' }; a( b8 D

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

[root@1ll253 ~]# ip link set dev veth5 netns ns2
  b) ]$ A3 T( Q; h% |! Q* O( I8 f[root@1ll253 ~]# ip netns exec ns2 ip link set dev veth5 name eth0
2 s/ V, k; n( m3 {[root@1ll253 ~]# ip netns exec ns2 ip addr add 172.17.0.103/16 dev eth03 A) c' c- y1 z* |/ B. X# _
[root@1ll253 ~]# ip netns exec ns1 ip link set dev eth0 up# t+ [; C" d3 K
[root@1ll253 ~]# ip link set dev veth5 master docker0
+ Z0 f# M+ N% ]: c[root@1ll253 ~]# ip link set dev veth5 up+ M3 e; f- c( C; x' U
5、查看绑定端口
3 X- l2 a; S3 u1 d2 m 微信图片_20200906204347.png

和网桥有关的操作还可以使用brctl,这个命令来自 bridge-utils安装包。这里使用brctl show来查询网桥docker0下绑定的网卡。

6、验证多个namespace之间的通信
6 G! c" j  ?8 ]- h' z( L// 进入ns0 bash终端( l; _- ?6 M2 q4 e
[root@1ll253 ~]# ip netns exec ns0 /bin/bash --rcfile <(echo "PS1=\"ns0> \"")2 ]7 O& ~  h: m* g, \' t" a* ?

: b2 d8 G( i9 w% c! n  g// ping 网桥docker0
( E8 u* E% @3 O+ a' Q5 `ns0> ping -c 1 172.17.0.1
0 E% z1 ^' o; O6 jPING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
8 p0 e; E$ ]$ T3 Y) \) \6 C# A64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.033 ms
' g. ]  H& F( ?$ r2 @* x...7 ?3 G$ `9 X$ w: [* t6 G' V
6 w: u/ `- S/ S. Y% l, J' g' h
// ping ns1上的eth0网卡0 E3 d6 ]" x& r  `+ s# g
ns0> ping -c 1 172.17.0.102
4 l6 X' c7 }2 v: F- o) `- EPING 172.17.0.102 (172.17.0.102) 56(84) bytes of data.
, j$ v# a# L0 C6 U* X* t- l( {# L64 bytes from 172.17.0.102: icmp_seq=1 ttl=64 time=0.049 ms4 ?4 P  P  h0 |$ E; c7 }5 V/ s& L# S
...
+ K' [) ^$ [  z: `' p. Z' A0 z$ l" J9 s7 P
// ping ns2上的eth0网卡
( {2 ~- l1 t& v2 Ans0> ping -c 1 172.17.0.103
' S4 z$ Q) G: IPING 172.17.0.103 (172.17.0.103) 56(84) bytes of data.
) {- q- h6 |& e1 _64 bytes from 172.17.0.103: icmp_seq=1 ttl=64 time=0.038 ms
* R& f* y9 r: t: ]% Q, r6 v8 ]; _...
& k) t  x) n  C! `( ?
$ O) s; i) G% z- a. ?
赞 收藏 评论0 发布时间:2020-9-6 20:47

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版