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

Linux虚拟化技术

[复制链接]
gaosmile 发布时间:2020-8-31 23:40
背景

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

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

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

微信图片_20200831233815.png Network Namespace+ s- G# ?; X) F  a

) V' M3 K4 D7 i+ u& `ip netns命令

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

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

[root@qll253 ~]# ip netns help
6 P1 b+ S% U% GUsage: ip netns list
6 t) U# c0 d5 M# }: @' W' U       ip netns add NAME+ y6 k; n  Z# @
       ip netns set NAME NETNSID1 ^3 @* O, M# {7 W4 @/ t! E7 l5 |. l
       ip [-all] netns delete [NAME]- C; F7 p  R8 o- z1 \" ^# V; E! j
       ip netns identify [PID]
5 x' {4 i$ F' E, D       ip netns pids NAME
" D/ ~: x, _: W8 D& H4 n. O       ip [-all] netns exec [NAME] cmd ...
) f( L0 S* e6 r# D       ip netns monitor/ b8 b4 r7 m- e0 V, K! {" A
       ip netns list-id& q7 Q% o- M- M5 p/ c- l1 I

- G4 k; m% i( h+ k# c3 V
+ f& X5 X+ k4 O) C4 f
创建Network Namespace
. ^/ f' K( S9 u% r7 k* M8 s1、通过 ip netns add 命令创建一个名为ns0的网络命名空间:[root@1ll253 ~]# ip netns add ns0
) j: H6 i# Q( V& r2 D
2、查询命名空间[root@1ll253 ~]# ip netns list
0 }4 [; T5 l# x7 G% }/ y- Ens0: e0 u3 T  m+ z) d( t! g
3、命名空间所在目录[root@1ll253 ~]# ls /var/run/netns/3 H; X3 W/ }3 d) @2 q; b
ns05 F! O& Y- ?* n+ `

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


, }4 u9 n- }7 R5 l8 U$ z

操作Network Namespace

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

1、查看网络命名空间 ns0 的网卡信息* K8 c4 s) x, R* }# F' F7 T. G9 e
[root@1ll253 ~]# ip netns exec ns0 ip addr
8 T3 z1 c4 E( h1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000" ?  E. o: a1 _! p3 i% y& r4 F
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00  E, @: H& k1 v* h" W

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

2、启用lo回环网卡:1 k# b, {" H% o% b$ I( f+ j/ p
[root@1ll253 ~]# ip netns exec ns0 ip link set lo up. {3 c& `+ P# U/ K

再次检查回环网卡状态:

[root@1ll253 ~]# ip netns exec ns0 ip addr
5 p& q3 B5 [/ n  M9 |( O1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
! @/ i0 V8 z$ t- c) u0 o    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00( {' {# ~3 \' q) r0 }! Z
    inet 127.0.0.1/8 scope host lo
- w: v' `8 U. N- x9 v: b- N" |3 r       valid_lft forever preferred_lft forever2 T; |2 B! _4 N" P/ p4 k
    inet6 ::1/128 scope host
$ ~9 Z, D* |) e. @8 j$ y" b: m       valid_lft forever preferred_lft forever
; K  V& p" _0 B3 D3 G/ e3 F

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

3、在 ns0 中打开一个shell终端
1 J' j1 e" e( T: R7 C2 W  Q[root@1ll253 ~]# ip netns exec ns0 /bin/bash
4 x! q+ Q: u+ j/ C" w; t4 o[root@1ll253 ~]# ip addr+ V; a% C0 [8 g8 n3 d! h
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 10005 [  }7 t% C8 s7 ~' m
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:001 i# k4 V2 f$ E; u/ u
    inet 127.0.0.1/8 scope host lo% n: Y3 l0 O. E4 U, I2 m4 D/ F
       valid_lft forever preferred_lft forever
  G! }9 d/ T0 }. ?[root@1ll253 ~]# exit
- |3 V: o7 S* }) ~+ L+ z! G# X( {exit% T+ ]- [* h  Z6 R

通过执行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> \""); |) V2 e, [' H& y$ |. u
ns0>
" _2 [+ ^2 a% v0 b" n* Q
8 a* x/ `- _, u* x4 D
Network Namespace 之间的通信

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

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

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

微信图片_20200831233818.png 实验拓扑图
+ w% V3 T. Q: f' L. |" T7 `" p  N& v3 t

6 @. r- \9 W& l/ F+ v  u$ J" D# }+ K1、创建veth pair
: P0 x; D' \1 U+ y+ L[root@1ll253 ~]# ip link add type veth
6 V8 o* F1 b' N1 |  O* X! U[root@1ll253 ~]# ip link
& D7 T" x- d+ e) p% m8 l14: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000. g( a( d0 D; d: O3 s- k) M, ~
    link/ether 06:17:62:85:64:fc brd ff:ff:ff:ff:ff:ff
% Z" V2 a# m: }15: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
# H5 W9 q7 e+ G; ~5 {% w& Z# l  ~    link/ether fe:9a:48:e4:a3:99 brd ff:ff:ff:ff:ff:ff7 K2 ~8 J7 k  L; r
[root@1ll253 ~]# # }9 _3 S9 Z: y4 A" x

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

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

[root@1ll253 ~]# ip link add veth001 type veth peer name veth002
) r6 p$ @9 K; k& ?/ @+ d[root@1ll253 ~]# ip link5 i9 n* M: t/ I# Y
12: veth002@veth001: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 10002 i( ~6 v" [* y5 ]7 _4 m/ j
    link/ether aa:3e:04:da:a7:69 brd ff:ff:ff:ff:ff:ff
! B- J* \* g  @! X- `. {) D13: veth001@veth002: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
, ~$ F& S3 G  U7 ~    link/ether 3e:5d:5f:4e:06:2b brd ff:ff:ff:ff:ff:ff
- h! k3 O8 u5 [. S! r/ a
2、创建Network Namespace

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

[root@1ll253 ~]# ip netns add ns1: n2 N! f6 v) L7 n' Y% V
[root@1ll253 ~]# ip netns list1 V% G7 j' @; G: R& V
ns1
9 y5 b+ h7 b4 }/ bns0
% P9 k" k. B4 z2 G
3、把veth pair分别加入到这两个namespace中

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

[root@1ll253 ~]# ip link set veth0 netns ns06 F5 O4 B7 H% Y+ x. @
[root@1ll253 ~]# ip link set veth1 netns ns1
7 T( C7 x8 z( Z! U1 ^
4、分别为这对veth pair配置上ip地址,并启用

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

[root@1ll253 ~]# ip netns exec ns0 ip addr add 192.168.1.1/24 dev veth08 v2 m& E2 T3 e$ ]8 M. ^
[root@1ll253 ~]# ip netns exec ns0 ip link set veth0 up9 A" z6 O2 p8 t  }

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

[root@1ll253 ~]# ip netns exec ns1 ip addr add 192.168.1.2/24 dev veth1
- l( p; |: Q( H( y/ R[root@1ll253 ~]# ip netns exec ns1 ip link set veth1 up
. |# K9 {& `4 z& }: T+ S
5、查看这对veth pair的状态
, z' X6 |3 s( u/ t 微信图片_20200831233821.png
$ c; e' Q' O1 C8 ^& h" }. ~/ z6、验证两个Network Namespace之间的互通# M. l8 H3 v3 m- ~1 A% L
微信图片_20200831233824.png

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

网桥

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

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

微信图片_20200831233826.png 实验拓扑图
6 ~% K, P3 j, q- p9 c0、还原网络环境

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

[root@1ll253 ~]# ip netns delete ns0, z8 {# N- ~5 [. b2 b$ X' e" }- T  O
[root@1ll253 ~]# ip netns delete ns1
/ n. N8 N( \$ y) _" A9 c& H
1、创建3个Network Namespace[root@1ll253 ~]# ip netns add ns0
1 T& S! c- z; Y3 H; |1 B[root@1ll253 ~]# ip netns add ns1
& o& i: x  y1 S9 b6 v# b[root@1ll253 ~]# ip netns add ns2
, L+ @2 ~7 V  ^8 K5 ?/ c
2、创建3对veth pair[root@1ll253 ~]# ip link add type veth
4 {6 U+ k* K4 N- e1 a[root@1ll253 ~]# ip link
; J- b/ H# ^5 m16: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
7 D- o' p  D8 E- |( b# j% `9 ]& W. G    link/ether ba:fa:d6:14:e1:32 brd ff:ff:ff:ff:ff:ff& n/ d5 ^6 a6 n
17: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000) m/ l8 u; x/ l4 K0 _
    link/ether a2:ef:d9:a5:96:51 brd ff:ff:ff:ff:ff:ff
2 [5 |- N6 ?% m( S' F7 j18: veth2@veth3: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
& S2 P% O0 }/ j1 h: Z4 }    link/ether a2:5b:e7:9e:b1:55 brd ff:ff:ff:ff:ff:ff
) f: s2 B# @0 j8 [+ u* M9 f19: veth3@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000! X. ?& u0 E) x4 n: B
    link/ether 92:91:67:ab:69:ac brd ff:ff:ff:ff:ff:ff
; `( \# Z0 e+ B/ f1 U# ~, Y0 `20: veth4@veth5: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000+ ?1 J- S( Z7 u  x
    link/ether 8a:c8:35:f6:11:3f brd ff:ff:ff:ff:ff:ff
$ x' J0 a5 B& u' K21: veth5@veth4: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000! M4 C0 w/ _4 W: Y; k; x+ ?
    link/ether 2a:b7:82:d4:49:d5 brd ff:ff:ff:ff:ff:ff
- [. Y; E9 Z0 P, ]! M5 N: U0 [3 j; _1 R! {. {0 }
3、创建网桥# [2 F5 y  \6 e/ g8 |/ N' D$ y" K
// 创建名为 docker0 的网桥
3 e8 Y% {; }. w! K/ k: k8 J4 I[root@1ll253 ~]# ip link add docker0 type bridge
: F. t; P8 _6 |3 t9 U$ s( E2 r. E9 R2 W( A, P6 i
//启动 docker0 网桥
- V+ N  Q( q, _: L4 ][root@1ll253 ~]# ip link set dev docker0 up- N6 j# w/ {+ T- T9 S0 m

: \: @- X3 |" d* \//为docker0网桥配置IP0 A4 ]+ f9 J2 g0 X
[root@1ll253 ~]# ifconfig docker0 172.17.0.1/16
+ @8 ^: a8 p2 W; V1 |0 B0 N

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

微信图片_20200831233829.png docker03 w/ T4 x1 u7 l& i& V! G
4、绑定网口

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

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

// 将veth1添加进ns0
3 y8 ?, N* j4 {. r[root@1ll253 ~]# ip link set dev veth1 netns ns0
0 N' e6 b2 U, v2 S( ^/ O) e- o4 ]2 b
' R+ S5 @; P; E8 [- i, b4 C; _//将veth1重命名为eth00 G1 g; F3 M: L1 S& D: f6 k: p
[root@1ll253 ~]# ip netns exec ns0 ip link set dev veth1 name eth0
; t" m1 a' Y( c$ K' U+ p5 O# n# O! z! M6 v- o# ^0 O
//为ns0中的eth0配置ip
& F+ i8 P6 u  }9 W8 \1 o[root@1ll253 ~]# ip netns exec ns0 ip addr add 172.17.0.101/16 dev eth0
: {5 M, A4 y* L3 E: y( V5 ~4 y
7 f3 a" V- o( b// 启动ns0中的eth0网卡
6 \( x- T1 y( A  Z/ o/ M[root@1ll253 ~]# ip netns exec ns0 ip link set dev eth0 up2 H" v3 a) t, |4 n3 s/ r6 Q. \# [
' a- g& a; n! T, b3 t9 U0 x
// 将veth0添加加网桥docker0- ?9 L' u8 c: z9 Z9 A* R
[root@1ll253 ~]# ip link set dev veth0 master docker0
# ~! z& b$ n$ {: Z% G# t" j: [# w4 t& r3 l; w+ j
// 启动veth0网卡
+ j  l" s7 V2 U: J: G) z% h[root@1ll253 ~]# ip link set dev veth0 up* J8 \1 q% ]; C) m4 |0 }2 a2 W$ D* ~

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

[root@1ll253 ~]# ip link set dev veth3 netns ns1. C* X/ b6 X) t6 w' h; j$ H& n
[root@1ll253 ~]# ip netns exec ns1 ip link set dev veth3 name eth0
8 h0 I( @" ]. p4 z; t3 N4 d& w[root@1ll253 ~]# ip netns exec ns1 ip addr add 172.17.0.102/16 dev eth0
; b9 x$ d5 v  f[root@1ll253 ~]# ip netns exec ns1 ip link set dev eth0 up
# W7 r7 p  P( T8 U' t" D[root@1ll253 ~]# ip link set dev veth1 master docker0
: d: b, R3 r# {. Z4 r[root@1ll253 ~]# ip link set dev veth3 up9 E: s0 N$ {. t& x+ l2 T6 U1 x0 ?4 w

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

[root@1ll253 ~]# ip link set dev veth5 netns ns2
# F6 `# H5 h3 Z) W- `: }. W$ ][root@1ll253 ~]# ip netns exec ns2 ip link set dev veth5 name eth0" V; C4 t! v! u$ j* {* p5 C9 _/ V
[root@1ll253 ~]# ip netns exec ns2 ip addr add 172.17.0.103/16 dev eth0& W: U' x5 L+ u6 u) n( ~3 t
[root@1ll253 ~]# ip netns exec ns1 ip link set dev eth0 up
7 K+ \+ O# K/ W# F  w; n2 _8 Q[root@1ll253 ~]# ip link set dev veth5 master docker0  H7 F6 C/ h/ W. Z
[root@1ll253 ~]# ip link set dev veth5 up: l, T( i' L- `+ M& i5 d
5、查看绑定端口
/ O# _) r* y  Q3 G4 w5 N* A# R) g 微信图片_20200831233832.png

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

6、验证多个namespace之间的通信
4 Z, T$ y7 j9 a; H// 进入ns0 bash终端' C: X- R2 D+ Q2 {
[root@1ll253 ~]# ip netns exec ns0 /bin/bash --rcfile <(echo "PS1=\"ns0> \"")
7 Z1 b, f* r  \6 f4 s, ?
+ `5 _( H, `2 z; \$ F// ping 网桥docker0& y4 Y+ n7 m; h5 i' h3 k; U
ns0> ping -c 1 172.17.0.1
' B% f3 W  a6 d6 r' s" yPING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
. V1 W# Y1 g7 R64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.033 ms# z% s9 {1 b& c8 b9 l7 _
...
: t5 v" ~! O& `# j+ N, ?
, b: A7 U+ i& o( Y  O// ping ns1上的eth0网卡9 B1 P6 l& a, R
ns0> ping -c 1 172.17.0.102
/ T: ~4 t8 \- [; n: K5 lPING 172.17.0.102 (172.17.0.102) 56(84) bytes of data.: O+ S* F8 t& T7 b% z  v
64 bytes from 172.17.0.102: icmp_seq=1 ttl=64 time=0.049 ms
. s/ f+ r: m$ f..., S% V$ Y7 ]' p$ r# q
- I8 g2 O5 |% @/ n3 U: }! j, H
// ping ns2上的eth0网卡0 Y1 Z( G8 Z4 N( q( W
ns0> ping -c 1 172.17.0.103/ _6 ?1 W0 c* m# W  p/ m
PING 172.17.0.103 (172.17.0.103) 56(84) bytes of data.1 D2 v* O! W5 S4 l
64 bytes from 172.17.0.103: icmp_seq=1 ttl=64 time=0.038 ms: P( Q2 ?5 o  }, E
...

- B+ v' R8 W9 b# k: w
0 c  T& O* B! Q0 F" ~
赞 收藏 评论0 发布时间:2020-8-31 23:40

举报

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