|
netns是在linux中提供网络虚拟化的一个项目,使用netns网络空间虚拟化可以在本地虚拟化出多个网络环境,目前netns在lxc容器中被用来为容器提供网络。 使用netns创建的网络空间独立于当前系统的网络空间,其中的网络设备以及iptables规则等都是独立的,就好像进入了另外一个网络一样。 netns虚拟网络空间的网络通信依赖于物理接口,光讲听上去很虚,我们来操练点实际的看看: 1.创建虚拟网络空间: ip netns add ns1 这样我们就得到了一个名为ns1的网络空间,虚拟网络空间除了网络是虚的以外,文件系统完全和当前系统共享,也就是说所有本地可以使用的命令都可以在虚拟网络中使用,我们进入ns1看看情况: ip netns exec ns1 bash ifconfig -a ~# ifconfig -a C% y; N3 m+ I1 h
lo Link encap:Local Loopback( Y! B" F: K0 l$ `
LOOPBACK MTU:16436 Metric:1
1 p1 I1 ^& i8 L/ t) i: oRX packets:0 errors:0 dropped:0 overruns:0 frame:0
/ {& J3 o- i/ g3 S. b! D x- PTX packets:0 errors:0 dropped:0 overruns:0 carrier:0$ f, J2 P/ _4 \7 Q; ^7 l7 D. A
collisions:0 txqueuelen:0
* o# r, s6 J. D, rRX 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 -a3 J* t. w4 d6 R- _* r6 h
lo Link encap:Local Loopback: `( g, | B4 v
LOOPBACK MTU:16436 Metric:1
( i* Y$ E. I3 L2 cRX packets:0 errors:0 dropped:0 overruns:0 frame:0" @& q% X, \ e' S- [6 M
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
% K: ]% y. v- P( }! wcollisions:0 txqueuelen:0
; W" D F: [/ G. LRX bytes:0 (0.0 B) TX bytes:0 (0.0 B) ns1-vnic Link encap:Ethernet HWaddr 92:69:39:f3:b3:be
# F: p6 x8 x6 M1 l% ZBROADCAST MULTICAST MTU:1500 Metric:1( L1 |) i& b. V' i; v( O4 y. D
RX packets:0 errors:0 dropped:0 overruns:0 frame:04 c. h4 J: g* `! t- d! M1 M9 P
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
3 x& ^1 Y9 [; {, V8 Pcollisions:0 txqueuelen:10002 P/ N8 _" F9 W2 t; H0 W8 o! m
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) 可以看到多出来了一块网卡,虽然网卡名字有点丑,不过网卡名字可以随意修改的,我们改一改: ip link set ns1-vnic name eth0
: K3 d/ q6 M4 @8 q& t( T1 U# ifconfig -a
' i4 Q# Q, `/ [) G1 a+ D: Yeth0 Link encap:Ethernet HWaddr 92:69:39:f3:b3:be
0 c7 {* u/ D/ g# q$ QBROADCAST MULTICAST MTU:1500 Metric:1
! e0 a' }, {0 Y" g+ o) `$ T' lRX packets:0 errors:0 dropped:0 overruns:0 frame:00 d6 N3 O3 v! x" a1 y# _$ p( j
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0% Y- S. b. A0 M4 J2 @$ j8 `% @" O
collisions:0 txqueuelen:1000/ n/ {6 z% d0 C
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback6 _& J& O/ C) M1 a' q# v
LOOPBACK MTU:16436 Metric:1; j5 Y" t+ T9 l- P" k. T+ e
RX packets:0 errors:0 dropped:0 overruns:0 frame:0& ]% {! u0 T* S. Q. v5 W
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0; I0 F$ Y; o7 _5 e3 ?' h( t
collisions:0 txqueuelen:0; B' J: `) n4 J j
RX 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# j& H. W& F/ W$ ]9 ]
# ifconfig2 Q* u! @! a5 t" f' v# \8 t) }
eth0 Link encap:Ethernet HWaddr 92:69:39:f3:b3:be7 F! |) w- e$ S7 c
inet addr:10.0.0.100 Bcast:0.0.0.0 Mask:255.255.255.0
# j) x7 M0 `1 i w; AUP BROADCAST MULTICAST MTU:1500 Metric:14 c0 f+ f6 _5 q
RX packets:0 errors:0 dropped:0 overruns:0 frame:0: Y! S, N, W1 |6 D$ @
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0! m4 n' W. X7 o L
collisions:0 txqueuelen:1000
5 l% X ^) A- E2 b. BRX bytes:0 (0.0 B) TX bytes:0 (0.0 B) 然后我们再把回环起起来,ping一下自己感受一下: # ip link set lo up
, p* r. y* G. f, Y" Proot@ubuntu:~# ping 10.0.0.100
; ^$ Y, f( D+ @ v0 yPING 10.0.0.100 (10.0.0.100) 56(84) bytes of data.
+ }# M9 x( U& w$ h' u0 b64 bytes from 10.0.0.100: icmp_req=1 ttl=64 time=0.072 ms% k2 U" l$ `/ D! }
64 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$ S: B6 ], Z, o* c5 y5 D! P( k m3 `( M
testbr Link encap:Ethernet HWaddr 6a:d1:34:5b:3c:993 w8 S! D ]( G7 q* {
inet addr:10.0.0.1 Bcast:0.0.0.0 Mask:255.255.255.0& z) K6 F5 L6 J
inet6 addr: fe80::68d1:34ff:fe5b:3c99/64 Scope:Link" v( Q7 [+ I" E0 q$ P+ ]& S# R
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
* x6 W% h: X5 p2 w* O0 `5 QRX packets:0 errors:0 dropped:0 overruns:0 frame:0
3 s8 c) t9 J+ w, r( M2 T: z7 v! lTX packets:6 errors:0 dropped:0 overruns:0 carrier:0
% I9 u: l* m8 ecollisions:0 txqueuelen:0. a8 R7 Y9 X: d; D. P, \5 V: x
RX bytes:0 (0.0 B) TX bytes:468 (468.0 B)
2 [* F) k9 l; `4 l" c下面来ping一下ns1中的eth0网卡ip10.0.0.100感受一下: ~# ping 10.0.0.100
4 c* F& R8 U% U% l8 f4 PPING 10.0.0.100 (10.0.0.100) 56(84) bytes of data.( S, {' B4 Y, l/ q
64 bytes from 10.0.0.100: icmp_req=1 ttl=64 time=0.200 ms: D* a5 @5 `( e8 f- d
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.1; S, A) s0 |4 p: y3 @
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
1 s2 c/ m7 o' O2 F3 \( M) H64 bytes from 10.0.0.1: icmp_req=1 ttl=64 time=0.057 ms
/ ?0 V) p8 y2 V5 N# z% d3 h2 s" \* S64 bytes from 10.0.0.1: icmp_req=2 ttl=64 time=0.063 ms 嗷嗷!是通的! 但是现在ns1中的网络还访问不到外网,那么如何才能让ns1中的网络可以访问到外面的世界呢? 有点晚了,请听下回分解!感兴趣的同学可以这里评论留言给我,或者看博客左上方的微博地址给我at一下。:-)
! o9 s! d2 z8 r* j常用的namespace的命令: / f6 K7 m9 P9 p7 q0 j+ k
1. 添加一个namespace sudo ip netns add [name] % J; o% N7 s/ t7 }% \2 D, n! z
% C( q" P# c/ _6 R |9 T1 q2. 在namespace中启用一个设备 sudo ip netns exec [name] ip link set lo up 8 N% H! A6 q: B. R" t; y
8 e7 D' w1 w% _. N3. 在namespace中新加一个设备 sudo ip link set [dev-name] netns [name] 启用: sudo ip netns exec [name] ip link set [dev-name] up , n) b/ F. J+ a8 E/ O! D1 U; d
( l+ _" U# [9 O, \( x0 L4. 查看指定namespace中指定设备的参数信息 sudo ip netns exec [name] ip addr show [dev-name] permanent scope global
& ]* n. [, {# S" J
. I' K7 U6 i1 a: \, K5. 为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]
: [& x, [& n! ]% U4 O
( V* W$ T: L" A5 ~6.查看所有network namespace ip netns list
Z4 O9 w4 F1 R, \- {/ L) a7 L8 J) Z
7.ping虚拟机实例 ip netns exec [name] ping 192.168.1.3 # i4 \# P y3 L
|