1. 隔離模式:虛擬機之間組建網絡,該模式無法與宿主機通信,無法與其他網絡通信,相當於虛擬機只是連接到一台交換機上。
2. 路由模式:相當於虛擬機連接到一台路由器上,由路由器(物理網卡),統一轉發,但是不會改變源地址。
3. NAT模式:在路由模式中,會出現虛擬機可以訪問其他主機,但是其他主機的報文無法到達虛擬機,而NAT模式則將源地址轉換為路由器(物理網卡)地址,這樣其他主機也知道報文來自那個主機,在docker環境中經常被使用。
4. 橋接模式:在宿主機中創建一張虛擬網卡作為宿主機的網卡,而物理網卡則作為交換機。
1. 隔離模型:
Guest1 和 Guest2 都為虛擬機。
Linux在虛擬機中的網卡都包含前半段和后半段,前半段在虛擬機上,后半段在宿主機上。上圖eth0在Guest1虛擬機上的網卡,對應的后半段為vnet0,在Guest1上所有發往eth0的數據就直接發往vnet0了,也可以將vnet0看作一張網卡
Guest1和Guest2如何通信:
在宿主機中創建一個虛擬交換機,讓vnet0和vnet1分別為虛擬交換機的一個接口,交換機也可以叫做bridge,只要兩個虛擬網卡的前半段ip地址在同一個網段內,就可以相互通信,這就是隔離模式。
1.1 使用qemu-kvm創建隔離模式
[root@kvm ~]# yum install bridge-utils qemu-kvm -y # 安裝所需軟件包 # 創建網橋 [root@kvm ~]# brctl addbr br0 [root@kvm ~]# brctl show bridge name bridge id STP enabled interfaces br0 8000.000000000000 no [root@kvm ~]# ip link set br0 up # 必須保持橋接網卡的活躍狀態,否則虛擬機之間無法互通
虛擬機啟動時,網卡的后半段不會自動添加到虛擬網橋,需要一個腳本來實現,首先編寫腳本
添加網卡腳本:
[root@kvm ~]# vim /etc/qemu-ifup #!/bin/bash # BRIDGE=br0 if [ -n $1 ]; then ip link set $1 up sleep 1 brctl addif $BRIDGE $1 [ $? -eq 0 ] && exit 0 || exit 1
else echo "Error: no interface specified." exit 1 fi [root@kvm ~]# sh -n /etc/qemu-ifup # 檢測有無語法錯誤 [root@kvm ~]# chmod +x /etc/qemu-ifup # 給與執行權限 當虛擬機停止時,網卡會自動從網橋中down掉,所以不用編寫停止網卡腳本 [root@kvm ~]# qemu-kvm -smp 1 -m 512 -cpu host -drive file=/images/centos7.img,if=virtio,media=disk,cache=writeback -net nic,model=virtio,macaddr=52:54:00:11:22:33 -net tap,ifname=vnet0.0,script=/etc/qemu-ifup -daemonize VNC server running on `127.0.0.1:5900'
-smp: 虛擬機cpu線程數 -cpu: cpu的類型;host為虛擬機使用物理機cpu類型 -drive: 驅動設備 file: 驅動設備目錄 if: 驅動設備類型,virtio為半虛擬化類型,性能較好 media:驅動設備是disk還是cdrom cache:設備緩存,writeback為回寫 -net nic:虛擬機網卡前半段,這是在虛擬機中使用的網卡 macaddr:設置虛擬機網卡mac地址,在使用qemu-kvm創建虛擬機時,需要手動指定mac地址,否則會出現相同的mac地址虛擬機 model:網卡類型,virtio為半虛擬化類型,性能較好 tap:為虛擬網卡后半段,需要連接到網橋上 ifname:系統中網卡名稱,比如:vnet0.0 script:指定啟動時,需要執行的腳本,該腳本是將虛擬機的后半段網卡添加到網橋中
啟動第二台虛擬機
[root@kvm ~]# qemu-kvm -smp 1 -m 512 -cpu host -drive file=/images/centos7-1.img,if=virtio,media=disk,cache=writeback -net nic,model=virtio,macaddr=52:54:00:11:22:34 -net tap,ifname=vnet0.1,script=/etc/qemu-ifup -daemonize VNC server running on `127.0.0.1:5901'
通過上圖,虛擬主機之間能相互連通。
宿主機是無法訪問到虛擬機,這就是kvm隔離模式
2. 路由模型及NAT模型
NAT模式
該模式網橋要作為路由器對虛擬機地址進行轉發,路由模式是無法修改源地址ip,因此虛擬機可能會成功的將報文發送給目標地址ip,而目標地址ip無法將報文回傳給源地址ip;
NAT模式則是將源地址ip改為物理網卡ip發送給目標地址,目標地址ip回傳給物理網卡,在將報文發送至虛擬主機。
2.1 使用qemu-kvm創建NAT模式
[root@kvm ~]# yum install qemu-kvm iptables-services bridge-utils -y # 安裝需要的程序包,使用iptables規則對報文進行轉發。
編寫虛擬機開啟執行腳本:
[root@kvm ~]# vim /etc/qemu-natup #!/bin/bash # bridge=br0 net="192.168.100.1/24" checkbr() { if brctl show | grep -i $1; then return 0
else
return 1 fi } initbr() { brctl addbr $bridge ip link set $bridge up ip addr add $net dev $bridge } enable_ip_forward() { sysctl -w net.ipv4.ip_forward=1 } setup_nat() { checkbr $bridge if [ $? -eq 1 ]; then initbr enable_ip_forward iptables -t nat -A POSTROUTING -s $net ! -d $net -j MASQUERADE fi } if [ -n $1 ]; then setup_nat ip link set $1 up brctl addif $bridge $1 exit 0
else echo "Error: no interface specified." exit 1 fi
編寫虛擬機關閉執行腳本:
[root@kvm ~]# vim /etc/qemu-natdown #!/bin/bash # bridge=br0 net='192.168.100.0/24' remove_rule() { iptables -t nat -F } isalone_bridge() { if ! brctl show | awk "/^$bridge/{print \$4}" | grep "[^[:space:]]" &> /dev/null; then ip link set $bridge down brctl delbr $bridge remove_rule fi } if [ -n $1 ]; then ip link set $1 down brctl delif $bridge $1 isalone_bridge exit 0
else echo "Error: no interface specified." exit 1 fi
以上兩個腳本對於NAT模型來說非常重要。
使用qemu-kvm 創建虛擬機
[root@kvm ~]# qemu-kvm -smp 1 -m 512 -cpu host -drive file=/images/centos7.img,if=virtio,media=disk,cache=writeback -net nic,model=virtio,macaddr=52:54:00:11:22:33 -net tap,ifname=vnet0.0,script=/etc/qemu-natup,downscript=/etc/qemu-natdown -daemonize net.ipv4.ip_forward = 1 VNC server running on `127.0.0.1:5900' [root@kvm ~]# qemu-kvm -smp 1 -m 512 -cpu host -drive file=/images/centos7-1.img,if=virtio,media=disk,cache=writeback -net nic,model=virtio,macaddr=52:54:00:11:22:34 -net tap,ifname=vnet0.1,script=/etc/qemu-natup,downscript=/etc/qemu-natdown -daemonize br0 8000.9acac824e624 no vnet0.0 VNC server running on `127.0.0.1:5901'
查看兩台虛擬機的后半段網卡都連接在橋br0上,在通過POSTROUTING鏈進行源地址轉換。
[root@kvm ~]# brctl show bridge name bridge id STP enabled interfaces br0 8000.9acac824e624 no vnet0.0 vnet0.1 [root@kvm ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:7b:9f:8c brd ff:ff:ff:ff:ff:ff inet 10.0.0.11/24 brd 10.0.0.255 scope global eno16777736 valid_lft forever preferred_lft forever 6: vnet0.0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN qlen 500 link/ether 9a:ca:c8:24:e6:24 brd ff:ff:ff:ff:ff:ff 7: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP link/ether 9a:ca:c8:24:e6:24 brd ff:ff:ff:ff:ff:ff inet 192.168.100.1/24 scope global br0 valid_lft forever preferred_lft forever 8: vnet0.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN qlen 500 link/ether f6:6c:f7:34:91:d4 brd ff:ff:ff:ff:ff:ff [root@kvm ~]# iptables -L -n -t nat 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) target prot opt source destination MASQUERADE all -- 192.168.100.0/24 !192.168.100.0/24
分別給兩台虛擬機配置ip地址,命令如下:
ip addr add 192.168.100.20/24 dev eth0 ip addr add 192.168.100.30/24 dev eth0
兩台虛擬機之間實現互通了,配置默認路由為br0地址,實現公網的訪問。
路由配置如下:
ip route add default via 192.168.100.1
kvm-nat模型實現成功。
3. 橋接模式
在該模式下,宿主機會虛擬出來一張虛擬網卡作為宿主機本身的通信網卡,而宿主機的物理網卡則成為橋設備(交換機),所以虛擬機相當於在宿主機所在局域網內的一個單獨的主機,他的行為和宿主機是同等地位的,沒有依存關系。
3.1 使用qemu-kvm創建橋接模式
為宿主機創建虛擬網卡,並將物理網卡作為橋設備
[root@kvm ~]# cd /etc/sysconfig/network-scripts/ [root@kvm network-scripts]# cp -a ifcfg-eno16777736 ifcfg-br0 [root@kvm network-scripts]# vim ifcfg-eno16777736 TYPE=Ethernet BOOTPROTO=none DEFROUTE=yes PEERDNS=yes PEERROUTES=yes IPV4_FAILURE_FATAL=no IPV6INIT=no NAME=eno16777736 UUID=9f0bf158-e598-4309-8c0c-7609174ff212 DEVICE=eno16777736 ONBOOT=yes BRIDGE=br0 [root@kvm network-scripts]# vim ifcfg-br0 TYPE=Bridge BOOTPROTO=none DEFROUTE=yes PEERDNS=yes PEERROUTES=yes IPV4_FAILURE_FATAL=no IPV6INIT=no NAME=br0 DEVICE=br0 ONBOOT=yes IPADDR=10.0.0.11 NETMASK=255.255.255.0 GATEWAY=10.0.0.1 DNS1=10.0.0.1 DNS2=114.114.114.114 [root@kvm network-scripts]# systemctl restart network [root@kvm network-scripts]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP qlen 1000 link/ether 00:0c:29:7b:9f:8c brd ff:ff:ff:ff:ff:ff 5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP link/ether 00:0c:29:7b:9f:8c brd ff:ff:ff:ff:ff:ff inet 10.0.0.11/24 brd 10.0.0.255 scope global br0 valid_lft forever preferred_lft forever [root@kvm network-scripts]# brctl show bridge name bridge id STP enabled interfaces br0 8000.000c297b9f8c no eno16777736
物理網卡eno16777736 將作為交換機使用,沒有ip地址
編寫虛擬機啟動腳本,該腳本和隔離模式腳本一致:
[root@kvm network-scripts]# vim /etc/qemu-ifup #!/bin/bash # BRIDGE=br0 if [ -n $1 ]; then ip link set $1 up sleep 1 brctl addif $BRIDGE $1 [ $? -eq 0 ] && exit 0 || exit 1
else echo "Error: no interface specified." exit 1 fi
啟動虛擬機
[root@kvm network-scripts]# qemu-kvm -smp 1 -m 512 -cpu host -drive file=/images/centos7-1.img,if=virtio,media=disk,cache=writeback -net nic,model=virtio,macaddr=52:54:00:11:22:34 -net tap,ifname=vnet0.1,script=/etc/qemu-ifup -daemonize VNC server running on `127.0.0.1:5900'
橋接模式完成。 以上為KVM最簡單是4種網絡模型,最為常見的是橋接模型。虛擬化環境中,目前見過最多的就是使用橋接模型。現在流行的docker一般是基於nat模型實現的。