html
橋接:建立一個虛擬橋設備,將虛擬機鏈接至橋設備上,再給橋設備配置一個IP地址,做爲宿主機與外部通訊的地址,便可完成與外網的通訊(一塊兒使用物理網卡的硬件功能),不過此時虛擬機使用的公網地址;linux
隔離:僅將須要互相通訊的虛擬機的後半段網卡添加到同一個虛擬的橋設備上,便可完成虛擬機之間的通訊,且與外網乃至是物理機隔離;數據庫
路由:將虛擬機關聯至虛擬橋設備上,再給橋設備配置一個與虛擬機同段的ip地址(內網地址)做爲虛擬機的網關(物理網卡是鏈接外網的,因此應該與內網IP地址不是一個段),最後再打開物理主機的核心轉達功能,便可讓虛擬機能夠ping外部主機,可是外部主機沒法發送相應包,由於外部主機沒有到達虛擬機的路由;bash
NAT:在路由模型的基礎上,爲其配置SNAT規則,便可完成真正的虛擬機與外網通訊,且本身使用的是內網地址;可是這樣還有一個問題,就是外網不能主動訪問內網的虛擬機,除非再爲其配置DNAT規則;網絡
Linux內核支持的隔離功能:tcp
namespace(名稱空間):netns是在內核中實現的,使用iproute所提供的netsn這個OBJECT來對其進行管理;且Centos6所提供的iproute工具不具備此OBJECT,須要依賴於OpenStack Icehouse源(https://repos.fedorapeople.org/openstack/EOL/openstack-icehouse/epel-6/)來提供;工具
文件系統隔離:讓分離的多個空間都認爲僅有本身在使用文件系統;學習
網絡隔離:主要用於實現網絡資源的隔離,包括隔離網絡設備、IPV4及IPV6地址、IP路由表、防火牆、/proc/net、/sys/class/net以及套接字等;測試
IPC隔離:各個被分離的空間中的進程互不影響,不可通訊;spa
用戶和用戶組隔離
PID隔離:對各名稱空間中的PID進行從新標號,兩個不懂的名稱空間可使用相同的PID號;
UTS隔離:提供主機名和域名的隔離;
NETNS:
ip netns list:顯示名稱空間列表;
ip netns add NAME:添加一個名稱空間;
ip [-all] netns delete [NAME]:刪除名稱空間;
ip [-all] netns exec [NAME] cmd ...:在指定名稱空間中運行命令;
例子:~]# ip netns exec r1 ifconfig -a
ip link set { DEVICE | dev DEVICE | group DEVGROUP } [ netns { PID | NAME } ]:將某個網卡設備分配個某個名稱空間;
ip link add DEVICE1 type TYPE(此處爲veth) peer name DEVICE2:建立一對虛擬網卡;
TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
bridge | bond | ipoib | ipip | sit | vxlan |gre | gretap |vti | nlmon |bond_slave | geneve | bridge_slave | macsec }
cgroups:
用於完成資源配置,限制被各namespace隔離起來的資源;還能夠爲資源設置權重(好比某個名稱空間佔用總資源的百分之80,另外一個名稱空間僅佔用總資源的百分之10,由於前者更重要或者他花的錢更多)、計算資源使用量、完成各類所需的管理任務等;
經過虛擬設備(OpenVSwitch)解決跨越物理主機的虛擬機通訊問題:
在linux中咱們能夠經過建立成對的虛擬機網卡接口,而後將這些虛擬網卡接口與隔離出來的namespace相鏈接,從而在linux內部建立複雜的虛擬網絡;好比建立一對虛擬網卡(~]# ip link add veth1.1 type veth peer name veth1.2),再建立出一塊名稱空間(~]# ip netns add r1),將成對兒的虛擬機網卡的一端分配給名稱空間(~]# ip link set vetn1.2 netns r2),將另外一端分配給宿主機上爲虛擬機建立的虛擬橋設備,就能夠實現相似將虛擬機鏈接至路由器(隔離出來的namespace就能夠當作是一個路由器)的功能;
示例:
建立兩個KVM虛擬機,使其鏈接到一個名爲br-in的虛擬橋設備(s)上,建立一個名稱爲r1的namespace做爲路由器,經過一對虛擬網卡(rinr,rins)將br-in與r1相連,使虛擬機能夠經過r1與外網通訊,再建立一對虛擬網卡(rexr,rexs),用於鏈接r1與同外網交互的虛擬網橋,從而實現與外網通訊;
配置過程:
1.建立虛擬機並將虛擬機鏈接至橋br-in:
~]# brctl addbr br-in
~]# ip link set br-in up
~]# brctl addbr br-ex
~]# ip link set br-ex up
~]# ip addr del 192.168.0.8/24 dev ens34; ip addr add 192.168.0.8/24 dev br-ex; brctl addif br-ex ens34 將IP地址配置到橋設備上,使物理網卡做爲硬件設備發送數據包;
~]# mkdir -pv /images/kvm/
~]# cp cirros-no_cloud-0.3.0-x86_64-disk.img /images/kvm/kvm1.qcow2
~]# cp cirros-no_cloud-0.3.0-x86_64-disk.img /images/kvm/kvm2.qcow2
~]# cat /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
~]# chmod +x /etc/qemu-ifup
~]# qemu-kvm -m 128 -smp 2 -name kvm1 -drive file=/images/kvm/kvm1.qcow2,if=virtio,media=disk -net nic,macaddr=52:54:00:12:34:55 -net tap,ifname=vif1.0,script=/etc/qemu-ifup -nographic
登陸虛擬機,爲KVM1配置ip地址:ifconfig eth1 10.0.1.1/24 up
~]# qemu-kvm -m 128 -smp 2 -name kvm2 -drive file=/images/kvm/kvm2.qcow2,if=virtio,media=disk -net nic,macaddr=52:54:00:12:34:66 -net tap,ifname=vif2.0,script=/etc/qemu-ifup -nographic
登陸虛擬機,爲KVM2配置ip地址:ifconfig eth1 10.0.1.2/24 up
2.建立做爲路由器的namespace(建立namespace以前要打開物理機的核心轉發功能:~]# echo 1 > /proc/sys/net/ipv4/ip_forward):
~]# ip netns add r1 建立一個namespace
~]# ip link add rinr type veth peer name rins 添加一個對兒用於鏈接內網的網卡
~]# ip link show
~]# ip link set rinr up
~]# ip link set rins up
~]# brctl addif br-in rins 將路由器與內網交換機相連
~]# ip link set rinr netns r1 將內網成對兒網卡的一端添加至路由器(r1)
~]# ip netns exec r1 ip link set rinr name eth0
~]# ip netns exec r1 ip link set eth0 up
~]# ip netns exec r1 ip addr add 10.0.1.254/24 dev eth0 設置路由器對內網的接口的IP地址,且做爲虛擬機的網關(回到虛擬機裏面設置網關:~]# route add default gw 10.0.1.25)
~]# ip link add rexr type veth peer name rexs 添加一對兒用於鏈接外網的網卡
~]# brctl addif br-ex rexs 將路由器與同外網交互的虛擬網橋相連
~]# ip link set rexr netns r1 將外網成對兒網卡的一端添加至路由器(r1)
~]# ip netns exec r1 ip link set rexr name eth1
~]# ip netns exec r1 ip link set eth1 up
~]# ip netns exec r1 ip addr add 192.168.0.100/24 dev eth1 設置路由器對外網的接口的IP地址
Note:此時能夠作一些ping測試,而且使用tcpdump抓包查看過程;此時虛擬機與外網是沒法通訊的,數據包只能出去,可是回不來;
~]# 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.0.8 添加一條SNAT規則,此時虛擬機纔可與外網互相通訊;
~]# ip netns exec r1 dnsmasq --dhcp-range=10.0.1.100,10.0.1.120 爲虛擬機配置DHCP,使其動態得到地址
# udhcpc -R 虛擬機從新得到IP地址
Note:上面的內容與OpenVswitch沒有直接關係,僅僅是展現linux自己也能夠實現路由交換功能;
OpenVswitch:軟件模擬的交換機;
支持802.1q
支持NIC bonding
支持NetFlow,sFlow
支持Qos
支持GRE,Vxlan
……
OVS的組成部分:
ovs-vswitchd:OVS的守護進程,實現數據報文的交換功能,其與linux內核兼容模塊一塊兒實現了基於流的交換技術;
ovsdb-server:輕量級的OVS數據庫服務,用於存儲OVS的配置信息;
ovs-dpctl:用於配置轉發規則;
ovs-vsctl:用於獲取或者更改ovs-vswitchd的配置信息,將修改信息保存至ovsdb-server中;
經常使用選項:
show:查看已配置的信息;
add-br BRIDGE:添加橋設備;
del-br BRIDGE:刪除橋設備;
add-port BRIDGE PORT:往橋設備上添加端口;
del-port [BRIDGE] PORT:從橋設備上刪除端口;
list-ports BRIDGE:顯示指定橋設備上的端口;
list-br:顯示當前主機上的全部已添加的橋設備;
list TBL [REC]:顯示指定表中的數據;
TBL能夠爲interface、port、br等
set TBL REC COL[:KEY]=VALUE:設置某個表中的某條數據的值;
例子:ovs-vsctl set port vif0.0(name字段) tag=10(欲修改字段)
remove TBL REC COL [KEY=]VALUE:將某個表中的某條數據的值移除;
例子:ovs-vsctl set port vif0.0 tag 10
示例1:
在Vmware中開啓一個虛擬機做爲物理機,而且爲其添加兩塊網卡;一塊做爲管理接口(VMnat8),一塊做爲物理機互相通訊的接口(VMnat2自定義);接着在物理機中建立多個虛擬機,經過OpenVswitch的vlan功能使同一物理主機的相同vlan中的虛擬機通訊;
配置過程:
~]# yum install openvswitch
~]# systemctl restart network.service
~]# ovs-vsctl add-br br-in 建立一個橋設備
~]# ovs-vsctl show
Bridge br-in:橋設備
Port br-in:端口,能夠看做交換機上的物理端口
Interface br-in:接口,能夠看做交換機上的端口號
type: internal:接口類型
~]# cat /etc/qemu-ifup
#!/bin/bash
BRIDGE=br-in
if [ -n "$1" ]; then
ip link set $1 up
sleep 1
ovs-vsctl add-port $BRIDGE $1
[ $? -eq 0 ] && exit 0 || exit 1
else
echo "Error:No port specified."
exit 2
fi
~]# cat /etc/qemu-ifdown
#!/bin/bash
BRIDGE=br-in
if [ -n "$1" ]; then
ip link set $1 down
sleep 1
ovs-vsctl del-port $BRIDGE $1
[ $? -eq 0 ] && exit 0 || exit 1
else
echo "Error:No port specified."
exit 2
fi
~]# chmod +x /etc/qemu-ifdown /etc/qemu-ifup
~]# mkdir -pv /images/kvm/
~]# cp cirros-no_cloud-0.3.0-x86_64-disk.img /images/kvm/kvm1.qcow2
~]# cp cirros-no_cloud-0.3.0-x86_64-disk.img /images/kvm/kvm2.qcow2
~]# cp cirros-no_cloud-0.3.0-x86_64-disk.img /images/kvm/kvm3.qcow2
~]# qemu-kvm -m 128 -smp 2 -name vm1 -drive file=/images/kvm/kvm1.qcow2,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:11:22:33 -net tap,ifname=vif0.0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown -nographic
~]# qemu-kvm -m 128 -smp 2 -name vm2 -drive file=/images/kvm/kvm2.qcow2,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:11:22:55 -net tap,ifname=vif1.0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown -nographic
vm1:# ifconfig eth0 10.0.10.1/24 up 爲vm1配置IP地址
vm2:# ifconfig eth0 10.0.10.2/24 up 爲vm2配置IP地址
Note:能夠互ping一下,看網絡是否暢通;
~]# ovs-vsctl list port 查看接口的vlan tag值;
~]# ovs-vsctl set port vif0.0 tag=10 設置vif0.0接口的tag值爲10,即將其添加至vlan10中;
~]# ovs-vsctl list port 再查看一下接口的vlan tag值,發現已經更改;
Note:在讓vm1與vm2互ping一下,發現已經ping不通了;
~]# ovs-vsctl add-br br-test 再添加一個橋設備
~]# cat /etc/qemu-ifup2
#!/bin/bash
BRIDGE="br-test"
if [ -n "$1" ]; then
ip link set $1 up
sleep 1
ovs-vsctl add-port $BRIDGE $1
[ $? -eq 0 ] && exit 0 || exit 1
else
echo "Error:No port specified."
exit 2
fi
~]# cat /etc/qemu-ifdown2
#!/bin/bash
BRIDGE="br-test"
if [ -n "$1" ]; then
ip link set $1 down
sleep 1
ovs-vsctl del-port $BRIDGE $1
[ $? -eq 0 ] && exit 0 || exit 1
else
echo "Error:No port specified."
exit 2
fi
~]# qemu-kvm -m 128 -smp 2 -name vm3 -drive file=/images/kvm/kvm3.qcow2,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:11:22:55 -net tap,ifname=vif2.0,script=/etc/qemu-ifup2,downscript=/etc/qemu-ifdown2 -nographic
# ifconfig eth0 10.0.10.3/24 up
~]# ip link add s0 type veth peer name s1 添加一對兒鏈接br-in與br-test的網卡
~]# ip link set s0 up
~]# ip link set s1 up
~]# ovs-vsctl add-port br-in s0
~]# ovs-vsctl add-port br-test s1
將br-in與br-test鏈接起來,且接口默認就爲trunk類型;可是兩個虛擬交換機上的虛擬機在都沒有添加vlan tag時是沒法通訊的,只有配置其爲某一vlan才能夠通訊;
~]# ovs-vsctl set port vif2.0 tag=10 將vm3的vlan tag改成10
Note:用vm1 ping vm3發現能夠通訊,用vm2 ping vm3沒法通訊,至此目的完成;
示例2:
經過GRE技術鏈接使不在同一網段中的物理機中的虛擬機通訊;
在Vmware中開啓兩個虛擬機做爲物理機,而且爲其添加兩塊網卡;一塊做爲管理接口(VMnat8),一塊做爲物理機互相通訊的接口(VMnat2自定義);接着在物理機中建立多個虛擬機,經過OpenVswitch的vlan與GRE功能使不一樣物理主機的相同vlan中的虛擬機通訊;
配置過程:
Host1:
~]# ip netns add r0 建立一個namespace名爲r0
~]# ip link add sif0 type veth peer name rif0 添加一對兒網卡用於鏈接r0與br-in;
~]# ip link set sif0 up
~]# ip link set rif0 up
~]# ip link set rif0 netns r0 將其一端的網卡分配給r0
~]# ovs-vsctl add-port br-in sif0 將另外一端鏈接至br-in
~]# ip netns exec r0 ip link set rif0 up
~]# ip netns exec r0 ip addr add 10.0.20.254/24 dev rif0
~]# ip netns exec r0 dnsmasq --dhcp-range=10.0.20.200,10.0.20.250,86400 --dhcp-option=option:router,10.0.20.154 在r0中配置dhcp服務,用於給Host1中的vm1與mv2以及Host2中的vm1分配IP地址;
~]# qemu-kvm -m 128 -smp 2 -name vm1 -drive file=/images/kvm/kvm1.qcow2,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:11:22:33 -net tap,ifname=vif0.0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown -nographic
~]# qemu-kvm -m 128 -smp 2 -name vm2 -drive file=/images/kvm/kvm2.qcow2,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:11:22:55 -net tap,ifname=vif1.0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown -nographic
vm1:# udhcpc -R 使虛擬機自動獲取IP地址;
vm2:# udhcpc -R
~]# ifconfig ens34 192.168.20.1/24 up 爲VMnet2中的物理網卡配置IP地址;
~]# ovs-vsctl add-port br-in gre0 在br-in橋上添加一個名爲gre0的端口;
~]# ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.20.2 將gre0端口的類型改成gre,而且指定遠端IP地址;
~]# ovs-vsctl list interface gre0
Host2:
~]# ovs-vsctl add-br br-in
~]# mkdir -pv /images/kvm/
~]# cp cirros-no_cloud-0.3.0-x86_64-disk.img /images/kvm/kvm1.qcow2
~]# cp cirros-no_cloud-0.3.0-x86_64-disk.img /images/kvm/kvm2.qcow2
~]# cat /etc/qemu-ifup
#!/bin/bash
BRIDGE=br-in
if [ -n "$1" ]; then
ip link set $1 up
sleep 1
ovs-vsctl add-port $BRIDGE $1
[ $? -eq 0 ] && exit 0 || exit 1
else
echo "Error:No port specified."
exit 2
fi
~]# cat /etc/qemu-ifdown
#!/bin/bash
BRIDGE=br-in
if [ -n "$1" ]; then
ip link set $1 down
sleep 1
ovs-vsctl del-port $BRIDGE $1
[ $? -eq 0 ] && exit 0 || exit 1
else
echo "Error:No port specified."
exit 2
fi
~]# chmod +x /etc/qemu-ifdown /etc/qemu-ifup
~]# qemu-kvm -m 128 -smp 2 -name vm1 -drive file=/images/kvm/kvm1.qcow2,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:11:22:66 -net tap,ifname=vif0.0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown -nographic
~]# ifconfig ens34 192.168.20.2/24 up
~]# ovs-vsctl add-port br-in gre0 在br-in橋上添加一個名爲gre0的端口;
~]# ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.20.1 將gre0端口的類型改成gre,而且指定遠端IP地址;
Note:如今Host2中的vm1虛擬機也能夠經過Host1中的r0中的dnsmasq獲取IP地址了(別忘記關閉防火牆);且Host1與Host2中的虛擬機都是互通的;
在Host1的ens34上的抓包結果:
如今咱們已經啓動了三個虛擬機,其中Host1中有vm1和vm2,Host2中有vm1,且三者能夠互通;咱們能夠經過vlan功能,讓Host1的vm2與Host2中的vm1通訊,可是Host1的vm1卻不能與本身的 vm2通訊;可是由於示例1已經演示過了,這裏就不贅述了!!!
示例3:
經過VxLAN技術實現不一樣物理主機上的虛擬機互通;
相比於VLAN,VxLAN能夠支持更多的vlan;且VxLAN能夠完成相似GRE(隧道)的功能;
拓撲同示例2
配置過程:
在示例2的基礎上繼續配置(沒有添加vlan控制);
Host1:
~]# ovs-vsctl del-port gre0
~]# ovs-vsctl add-port br-in vx0 -- set interface vx0 type=vxlan options:remote_ip=192.168.20.2
Host2:
~]# ovs-vsctl del-port gre0
~]# ovs-vsctl add-port br-in vx0 -- set interface vx0 type=vxlan options:remote_ip=192.168.20.1