ip netns命名空間

ip命令
       linux 的強大的網絡配置命令‘ip’。

 

 

 

netns可以讓一臺機器上模擬多個網絡設備,是網絡虛擬化的重要組成,將不同類型的網絡應用隔離。

一個net namespace有自己獨立的路由表,iptables策略,設備管理。說來說去,它就是用來隔離的。比如將eth0加入了netns 1,那麼netns 2中的應用程序就找不到eth0了。netns 1中的iptables策略,不會去影響netns 2中的iptables策略。

netns的用法

複製代碼
[root@monitor ~]# ip netns help list
Usage: ip netns list
ip netns add NAME
ip netns set NAME NETNSID
ip [-all] netns delete [NAME]
ip netns identify [PID]
ip netns pids NAME
ip [-all] netns exec [NAME] cmd ...
ip netns monitor
ip netns list-id
複製代碼

 


先打開內核的網絡轉發功能。

[root@localhost ~]# vim /etc/sysctl.conf 
[root@localhost ~]# sysctl -p
net.ipv4.ip_forward = 1

 

添加兩個namespace

[root@monitor ~]# ip netns add r1
[root@monitor ~]# ip netns add r2
[root@monitor ~]# ip netns list
r2
r1

 

查看r1的網絡。

複製代碼
[root@monitor ~]# ip netns exec r1 ifconfig -a
lo: flags=8<LOOPBACK> mtu 65536
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
複製代碼

 

爲r1的迴環接口添加一個ip地址。

複製代碼
[root@monitor ~]# ip netns exec r1 ifconfig lo 127.0.0.1 up
[root@monitor ~]# ip netns exec r1 ifconfig -a
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
複製代碼

 

此時的r2並沒有地址,因爲他們是被隔離的


在網絡名稱空間上添加一對網卡,一個在r1,一個在r2.

複製代碼
[root@localhost ~]# ip link add veth1.1 type veth peer name veth1.2
[root@localhost ~]# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT 
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br-ex state UP mode DEFAULT qlen 1000
link/ether 00:0c:29:4b:bb:d0 brd ff:ff:ff:ff:ff:ff
3: br-ex: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT 
link/ether 00:0c:29:4b:bb:d0 brd ff:ff:ff:ff:ff:ff
4: br-in: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT 
link/ether 56:8d:9f:d2:96:21 brd ff:ff:ff:ff:ff:ff
5: [email protected]: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether 7e:ea:fe:98:30:cd brd ff:ff:ff:ff:ff:ff
6: [email protected]: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether a2:48:54:92:c2:ed brd ff:ff:ff:ff:ff:ff
複製代碼

 


將一對網卡分別添加給2個名稱空間。

[root@localhost ~]# ip link set veth1.1 netns r1
[root@localhost ~]# ip link set veth1.2 netns r2

 

查看r1的網絡信息

複製代碼
[root@localhost ~]# ip netns exec r1 ifconfig -a
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

veth1.1: flags=4098<BROADCAST,MULTICAST> mtu 1500
ether a2:48:54:92:c2:ed txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
複製代碼

 


給r1的veth1.1改個名字,爲eth0

[root@localhost ~]# ip netns exec r1 ip link set veth1.1 name eth0

 

爲兩個網卡添加ip地址。

[root@localhost ~]# ip netns exec r1 ifconfig eth0 10.0.1.1/24 up
[root@localhost ~]# ip netns exec r2 ifconfig eth0 10.0.1.2/24 up

 


ping功能

 

複製代碼
[root@localhost ~]# ip netns exec r1 ping 10.0.1.2
PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=0.042 ms
64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.036 ms
64 bytes from 10.0.1.2: icmp_seq=3 ttl=64 time=0.043 ms
^C
--- 10.0.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.036/0.040/0.043/0.006 ms
複製代碼

 


到目前爲止,看吧,此時就好像創建了兩個虛擬機一樣。兩個網絡是互相獨立的。但是在一個網段內的時候,又可以互相聯通。

 

現在利用netns來創建1個虛擬網絡空間。大致內容如下圖。

 

 


創建橋接

複製代碼
[root@localhost ~]# brctl addbr br-ex
[root@localhost ~]# ip link set br-ex up
[root@localhost ~]# ifconfig 
br-ex: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 1e:d6:fd:9b:2a:fc txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
複製代碼

 


給橋設備添加IP地址。

# ip addr del 192.168.217.71/24 dev eno16777736 
# ip addr add 192.168.217.71/24 dev br-ex
# brctl addif br-ex eno16777736

 


再添加一個橋

[root@localhost ~]# brctl addbr br-in
[root@localhost ~]# ip link set br-in up

 

測試兩個虛擬機之間的網絡互通性。

首先先寫一個腳本,自動橋接的。(/etc/qemu-ifup)

複製代碼
#!/bin/bash

bridge=br-in

if [ -n "$1" ];then
ip link set $1 up
brctl addif $bridge $1
[ $? -eq 0 ] && exit 0 || exit 1
else
echo 'Error: no interface specified'
exit 1
fi
複製代碼

 

啓動一個虛擬機實例(cirros)

 

[root@localhost ~]# qemu-kvm -m 256 -smp 1 -name vm2 \
> -drive file=/images/cirros/test2.qcow2,if=virtio,media=disk \
> -net nic,macaddr=52:54:00:aa:bb:dd \
> -net tap,ifname=vif2.0,script=/etc/qemu-ifup \
> --nographic

 

再啓動一個 vm1.
在真機上查看橋接狀態。

[root@localhost ~]# brctl show
bridge name    bridge id    STP enabled    interfaces
br-ex    8000.000c294bbbd0    no    eno16777736
br-in    8000.0e1d0f339fc2    no    vif1.0
vif2.0

 


vif1.0 和vif2.0都是橋接在br-in上了。

好了,現在的情況相當於是vm1,vm2在一個交換機上。這個交換機就是br-in。爲了這兩個vm虛擬機可以和外界通信,必須要再創建一個虛擬的路由器。刪去剛纔的r1,r2。

添加路由器R1.

[root@localhost ~]# ip netns add r1

 

爲路由器R1添加一對網卡並且啓動。

[root@localhost ~]# ip link add rinr type veth peer name rins
[root@localhost ~]# ip link set rinr up
[root@localhost ~]# ip link set rins up

 

將網卡添加到橋上去。

複製代碼
[root@localhost ~]# brctl addif br-in rins
[root@localhost ~]# brctl show
bridge name    bridge id    STP enabled    interfaces
br-ex    8000.000c294bbbd0    no    eno16777736
br-in    8000.0e1d0f339fc2    no    rins
vif1.0
vif2.0
複製代碼

 

給rinr改個名字,並且啓動

[root@localhost ~]# ip link set rinr netns r1 #將網卡rinr添加至r1
[root@localhost ~]# ip netns exec r1 ip link set rinr name eth0
[root@localhost ~]# ip netns exec r1 ip link set eth0 up

 

添加一個IP,作爲網關。

複製代碼
[root@localhost ~]# ip netns exec r1 ifconfig eth0 10.0.1.254/24 up
[root@localhost ~]# ip netns exec r1 ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.1.254 netmask 255.255.255.0 broadcast 10.0.1.255
inet6 fe80::f8b4:bff:fee4:b12d prefixlen 64 scopeid 0x20<link>
ether fa:b4:0b:e4:b1:2d txqueuelen 1000 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 16 bytes 1296 (1.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
複製代碼

 

兩個虛擬機的網關都指向10.0.1.254

$ sudo su -
# ifconfig eth0 10.0.1.2/24 up
# route add default gw 10.0.1.254

 

目前來說整幅圖的左半邊完全好了。
開始右半邊。

添加一對網卡,再把其中一個橋接

 

複製代碼
[root@localhost ~]# ip link add rexr type veth peer name rexs
[root@localhost ~]# brctl addif br-ex rexs
[root@localhost ~]# ip link set rexs up
[root@localhost ~]# brctl show 
bridge name    bridge id    STP enabled    interfaces
br-ex    8000.000c294bbbd0    no    eno16777736
rexs
br-in    8000.0e1d0f339fc2    no    rins
vif1.0
vif2.0
複製代碼

 


將另一個網卡添加到路由器的另一邊,且給個另一個網絡的地址

[root@localhost ~]# ip link set rexr netns r1
[root@localhost ~]# ip netns exec r1 ip link set rexr name eth1
[root@localhost ~]# ip netns exec r1 ifconfig eth1 192.168.217.77/24 up

 

利用防火牆的源地址轉換,實現將內網中的地址轉換。

複製代碼
[root@localhost ~]# ip netns exec r1 iptables -t nat -A POSTROUTING -s 10.0.1.0/24 ! -d 10.0.1.0/24 -j SNAT --to-source 192.168.217.77
[root@localhost ~]# ip netns exec r1 iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination 

Chain INPUT (policy ACCEPT)
target prot opt source destination 

Chain OUTPUT (policy ACCEPT)
target prot opt source destination 

Chain POSTROUTING (policy ACCEPT)
複製代碼

 


測試。vm1可以ping同vm2.vm1可以訪問真機所在局域網的主機。

複製代碼
# hostname 
cirros
# ping 10.0.1.1
PING 10.0.1.1 (10.0.1.1): 56 data bytes
64 bytes from 10.0.1.1: seq=0 ttl=64 time=4.612 ms
# ping 192.168.217.2
PING 192.168.217.2 (192.168.217.2): 56 data bytes
64 bytes from 192.168.217.2: seq=0 ttl=127 time=4.742 ms

target prot opt source destination SNAT all -- 10.0.1.0/24 !10.0.1.0/24 to:192.168.217.77
複製代碼

 

當然。在左邊那個網絡中,還可以運行一個dhcp服務器,並且將網關自動指向10.0.1.254。 

[root@localhost ~]# yum -y install dnsmasq

 

執行命令

 

[root@localhost ~]# ip netns exec r1 dnsmasq -F 10.0.1.1,10.0.1.30 --dhcp-option=option:router,10.0.1.254

 

 
分類: Linux服務
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章