|
netns是在linux中提供网络虚拟化的一个项目,使用netns网络空间虚拟化可以在本地虚拟化出多个网络环境,目前netns在lxc容器中被用来为容器提供网络。 使用netns创建的网络空间独立于当前系统的网络空间,其中的网络设备以及iptables规则等都是独立的,就好像进入了另外一个网络一样。 netns虚拟网络空间的网络通信依赖于物理接口,光讲听上去很虚,我们来操练点实际的看看: 1.创建虚拟网络空间: ip netns add ns1 这样我们就得到了一个名为ns1的网络空间,虚拟网络空间除了网络是虚的以外,文件系统完全和当前系统共享,也就是说所有本地可以使用的命令都可以在虚拟网络中使用,我们进入ns1看看情况: ip netns exec ns1 bash ifconfig -a ~# ifconfig -a$ I, y( \. o/ l* N k
lo Link encap:Local Loopback
$ U; o3 t/ o: |6 u: g) t; ULOOPBACK MTU:16436 Metric:1
- b( w% @: t: v" X5 VRX packets:0 errors:0 dropped:0 overruns:0 frame:0
2 j/ l& a! K! wTX packets:0 errors:0 dropped:0 overruns:0 carrier:0
* v' l' G+ v3 v1 t* Lcollisions:0 txqueuelen:0 L, @6 u) G' @4 n8 G6 s9 y
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) 可以看到ns1中默认添加了一个本地回路设备,其他神马也没有,下面我们退出ns1,给他添加点网卡,之所以要在外部添加网卡是因为我们要为后面联通网络做准备, exit ip link add name ns1-nic type veth peer name ns1-vnic 这里我们添加了一对veth设备,veth设备是成对出现的,两个设备之间的数据是相互贯通的,我们把ns1-vnic加入到ns1网络空间中: ip link set ns1-vnic netns ns1 这样ns1-vnic就进入到ns1空间了,在本地网络中已经无法查看到,我们重新进入ns1看看现在的情况: ip netns exec ns1 bash # ifconfig -a0 H! P) g3 \4 N0 y+ X# S4 p
lo Link encap:Local Loopback, x6 w& r8 s5 X- B9 J
LOOPBACK MTU:16436 Metric:1
/ X" _8 P7 m8 E E8 I2 h3 l& ZRX packets:0 errors:0 dropped:0 overruns:0 frame:0- q' p: c% e% V# b- k% M
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
- j5 X. f1 ?5 y$ |) Wcollisions:0 txqueuelen:0+ ?1 b) Y x/ J. k
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) ns1-vnic Link encap:Ethernet HWaddr 92:69:39:f3:b3:be
2 s' X9 z. j# _: b6 E0 }BROADCAST MULTICAST MTU:1500 Metric:1
* D, U: p2 T& [( NRX packets:0 errors:0 dropped:0 overruns:0 frame:0
6 E \# Q$ a' T% M3 }TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
5 Y: R1 y" L. ecollisions:0 txqueuelen:1000
! E( L9 v! a' J9 QRX bytes:0 (0.0 B) TX bytes:0 (0.0 B) 可以看到多出来了一块网卡,虽然网卡名字有点丑,不过网卡名字可以随意修改的,我们改一改: ip link set ns1-vnic name eth0
" e1 `9 ^6 \1 x2 R# ifconfig -a p3 o. r! E5 {- W
eth0 Link encap:Ethernet HWaddr 92:69:39:f3:b3:be
& [$ w5 M* T! w7 g5 A* c1 B" Z) Y- nBROADCAST MULTICAST MTU:1500 Metric:1. m. c# F/ d2 v \/ U2 r+ T
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
- Q( C# y5 _+ G6 tTX packets:0 errors:0 dropped:0 overruns:0 carrier:0$ s I5 v+ z1 y% t: j8 |
collisions:0 txqueuelen:1000
6 O) C( v# h: _# X# tRX bytes:0 (0.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback R9 E/ D' ]- t5 i. ~2 \ F: t
LOOPBACK MTU:16436 Metric:1
^- ?$ i" f& A5 L% @9 Z! _/ XRX packets:0 errors:0 dropped:0 overruns:0 frame:0
; |0 w& ~! B: @: STX packets:0 errors:0 dropped:0 overruns:0 carrier:03 t7 k# F8 k9 \8 P) c7 z
collisions:0 txqueuelen:0
1 t9 F- i, T2 G: N; E( B8 FRX bytes:0 (0.0 B) TX bytes:0 (0.0 B) 刚才把默认的名字修改为了eth0,下面我们给他分配一个private ip address: ip addr add 10.0.0.100/24 dev eth0 然后把它启动起来: ip link set eth0 up
. U% p/ t* ]% p) P+ l# ifconfig( j6 O1 W5 z( [: l: U. O
eth0 Link encap:Ethernet HWaddr 92:69:39:f3:b3:be3 F) r2 _# u( t9 ^! p, N( W( I
inet addr:10.0.0.100 Bcast:0.0.0.0 Mask:255.255.255.0# U4 [0 G9 {. F$ G7 g
UP BROADCAST MULTICAST MTU:1500 Metric:10 W* o3 c Z& I% p; I$ {
RX packets:0 errors:0 dropped:0 overruns:0 frame:04 _: |) K% j- o* V
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
$ S" J \% H# z" Ecollisions:0 txqueuelen:1000, ~" b& \9 h' J
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) 然后我们再把回环起起来,ping一下自己感受一下: # ip link set lo up- C" ^+ T+ e7 W5 p( f
root@ubuntu:~# ping 10.0.0.100
) K2 Z% M% f: \2 g7 z# m: K. dPING 10.0.0.100 (10.0.0.100) 56(84) bytes of data.! Z0 l! C) o0 Z7 w
64 bytes from 10.0.0.100: icmp_req=1 ttl=64 time=0.072 ms
% A; L. r5 C3 S+ o: L. C7 x9 f$ m64 bytes from 10.0.0.100: icmp_req=2 ttl=64 time=0.040 ms 嗷嗷!ping自己通了!那么我们怎么样让ns1中的eth0和真实server中的网络进行通信呢?首先让他能和本地物理机通信,我们在物理机网络中采用桥接的方式,把刚才添加veth虚拟网卡的时候被拆开的一对的剩下一只添加的网桥里面,利用成对veth相互之间数据贯通的特性来实现网络互通: 先退出ns1,本地添加网桥: exit brctl addbr testbr brctl addif testbr ns1-nic ip link set ns1-nic up 然后给网桥设置一个ip地址: ip addr add 10.0.0.1/24 dev testbr ip link set testbr up ~# ifconfig testbr
& x) N/ P1 b3 `: f- n7 S5 n5 itestbr Link encap:Ethernet HWaddr 6a:d1:34:5b:3c:99/ v5 d* A5 Y' _6 k( s" u* A- n
inet addr:10.0.0.1 Bcast:0.0.0.0 Mask:255.255.255.05 Y" U0 K# F3 A
inet6 addr: fe80::68d1:34ff:fe5b:3c99/64 Scope:Link) I& t5 D+ y: m) P: i
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
9 U# d2 i% p. w5 O, E- dRX packets:0 errors:0 dropped:0 overruns:0 frame:0
+ L/ Z! S% W# t' g% nTX packets:6 errors:0 dropped:0 overruns:0 carrier:0
: d, _' j: ]/ U' B1 B: Hcollisions:0 txqueuelen:0
& N/ t- [# |' oRX bytes:0 (0.0 B) TX bytes:468 (468.0 B) - A- q. `7 `; c7 R5 z2 {# B U, `/ |
下面来ping一下ns1中的eth0网卡ip10.0.0.100感受一下: ~# ping 10.0.0.100
) r c" ? g, T) J7 X) VPING 10.0.0.100 (10.0.0.100) 56(84) bytes of data.
+ e3 |8 @$ L6 L, Z64 bytes from 10.0.0.100: icmp_req=1 ttl=64 time=0.200 ms9 M/ _5 x' T! A. R
64 bytes from 10.0.0.100: icmp_req=2 ttl=64 time=0.042 ms 嗷嗷!又通了! 我们进入ns1往10.0.0.1来ping一下: ~# ip netns exec ns1 ping 10.0.0.19 W1 V. P W* \; Z V1 v& w
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
1 ^1 m: i) S2 z& g64 bytes from 10.0.0.1: icmp_req=1 ttl=64 time=0.057 ms
% J0 z2 Y* |8 E- x- G& [; e3 |& p64 bytes from 10.0.0.1: icmp_req=2 ttl=64 time=0.063 ms 嗷嗷!是通的! 但是现在ns1中的网络还访问不到外网,那么如何才能让ns1中的网络可以访问到外面的世界呢? 有点晚了,请听下回分解!感兴趣的同学可以这里评论留言给我,或者看博客左上方的微博地址给我at一下。:-) # `! V3 F8 N) }1 u% J5 e& I( @. I
常用的namespace的命令: f0 Z1 {8 n5 y- ^1 }
1. 添加一个namespace sudo ip netns add [name]
1 Q0 H& D) }4 K6 Q r% L
! M# [0 s4 g5 c% R, ~- _0 e) R4 j2. 在namespace中启用一个设备 sudo ip netns exec [name] ip link set lo up
2 e% E- a d) W4 f7 |7 K; V8 Q+ Y
3. 在namespace中新加一个设备 sudo ip link set [dev-name] netns [name] 启用: sudo ip netns exec [name] ip link set [dev-name] up 0 F' R4 f4 _, b6 H* ]) e
/ M2 a9 C9 u3 \! x8 X: Q4. 查看指定namespace中指定设备的参数信息 sudo ip netns exec [name] ip addr show [dev-name] permanent scope global
/ J! M; Z6 G' O+ u" Q
3 I h% p# @1 U5. 为namespace中指定设备设置ip sudo ip netns exec [name] ip -4 addr add 192.168.1.2/24 brd 192.168.1.255 scope global dev [dev-name]
* b* K; a8 h& _& c4 D/ H- m O: }2 L" X3 U/ q: W) ]7 j
6.查看所有network namespace ip netns list
. S* R- `0 ?. c" Y& C ]
3 ~4 ]( n5 b4 K9 d+ \7.ping虚拟机实例 ip netns exec [name] ping 192.168.1.3
. `- _: `4 `. s' T |