KVM — 虛擬網絡構建
構建虛擬網絡是虛擬化及容器化的必備的核心技術
構架虛擬網絡的基本組件相關命令
1.虛擬網卡接口管理命令 : ip link
- 創建虛擬網卡接口設備
一般虛擬網卡接口成對創建,類似於現實中的網卡加網線的作用
ip link <options> type veth [peer [ name ] NAME]
- 將成對的網卡接口的一端配置在另一個虛擬路由器上
ip link set IF_DEVICE netns NET_NAMESPACE
2.網絡橋設備管理命令 : brctl
- 創建網絡橋虛擬設備
brctl addbr <bridge>
- 向橋設備上添加虛擬網卡(成對出現)中的一個接口
將成對的虛擬網卡接口的一端配置在網橋設備上,類似於現實中將某網卡設備用網線連接至交換機(網橋)
brctl addif <bridge> DEVICE
- 刪除橋設備
brctl delbr <bridge> DEVICE
- 刪除橋設備上的網卡接口
brctl delif <bridge> DEVICE
3.網絡名稱空間管理命令 : ip netns
- 虛擬網絡名稱空間,用於隔離網絡,可以理解爲虛擬路由器
Usage: ip netns list
ip netns add NET_NAMESPACE
- 指定在某個 NET_NAMESPACE (網絡名稱空間) 中執行某個 COMMAND
ip netns exec NET_NAMESPACE COMMAND
構建虛擬網絡過程演示
虛擬機與虛擬路由器連接通信演示
- 創建一對虛擬網卡接口設備
ip link add vethx.1 type veth peer name vethx.2
ip link show
#
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP mode DEFAULT qlen 1000
link/ether 00:0c:29:99:ea:72 brd ff:ff:ff:ff:ff:ff
3: vethx.2@vethx.1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether b2:43:00:1a:41:cf brd ff:ff:ff:ff:ff:ff
4: vethx.1@vethx.2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether 2e:d1:5d:79:3f:b6 brd ff:ff:ff:ff:ff:ff
- 創建虛擬路由器
ip netns add router1
ip netns list --all
#
router1
- 將虛擬網卡接口的一端配置在虛擬路由上
ip link set dev vethx.2 netns router1
ip link show
#
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP mode DEFAULT qlen 1000
link/ether 00:0c:29:99:ea:72 brd ff:ff:ff:ff:ff:ff
3: vethx.1@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether 2e:d1:5d:79:3f:b6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
- 指定在 router1 (網絡名稱空間) 中執行 ifconfig -a 命令
ip netns exec router1 ifconfig -a
#
lo: flags=8<LOOPBACK> mtu 65536
loop txqueuelen 1 (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
vethx.2: flags=4098<BROADCAST,MULTICAST> mtu 1500
ether b2:43:00:1a:41:cf 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
- 將虛擬網絡名稱空間 router1 中的網絡接口 vethx.2 配置一個 IP 地址並查看結果
ip netns exec router1 ifconfig vethx.2 10.0.0.1/24 up
ip netns exec router1 ifconfig
#
vethx.2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.2 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::b043:ff:fe1a:41cf prefixlen 64 scopeid 0x20<link>
ether b2:43:00:1a:41:cf txqueuelen 1000 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 給 vethx.1 網絡接口配置 IP 地址並查看結果
ifconfig vethx.1 10.0.0.2/24 up
ifconfig vethx.1
#
vethx.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::2cd1:5dff:fe79:3fb6 prefixlen 64 scopeid 0x20<link>
ether 2e:d1:5d:79:3f:b6 txqueuelen 1000 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 某個虛擬機與虛擬路由器通過 vethx.1 與 vethx.2 這對網絡接口連接,虛擬機與路由器間可以通信了
ping 10.0.0.2
#
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.067 ms
^C
--- 10.0.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.058/0.062/0.067/0.009 ms
- 刪除網絡接口
ip link delete vethx.1
#刪掉一個,另一個會自動消失
ip netns exec router1 ifconfig
- 刪除虛擬路由器
ip netns delete router1
ip netns list
一個具有 DHCP 服務的僅供內部虛擬機間通信的網絡配置演示
此實驗實現的網絡模型,僅供宿主機內部的虛擬機之間通信,內部虛擬機無法與宿主機通信,類似於實現了 VMware 程序中的 除了 VMnet0 、VMnet1(僅主機模式) 、VMnet8(NAT模式) 之外的的其他自定義網絡通道的功能。
多臺虛擬機之間通過虛擬交換機設備(網絡橋設備)通信,其中一臺虛擬機提供 DHCP 網絡服務
- 創建、激活並查看網絡橋設備
brctl addbr br-int
ifconfig br-int up
ifconfig
#
br-int: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::fc47:88ff:fed1:2c42 prefixlen 64 scopeid 0x20<link>
ether fe:47:88:d1:2c:42 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7 bytes 578 (578.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 配置虛擬機的虛擬網卡並將虛擬網卡連接至虛擬交換機,啓動虛擬機
兩個虛擬機需要預先安裝好操作系統並設置硬盤啓動
- 創建關聯虛擬交換機的腳本
vim /etc/qemu-ifup
#!/bin/bash
#
bridge=br-int
if [ -n "$1" ];then
ip link set $1 up
sleep 1
brctl addif $bridge $1
[ $? -eq 0 ] && exit 0 || exit 1
else
echo "No interface specified."
exit 2
fi
- 配置網絡並啓動第一個虛擬機 C1 進程
qemu-kvm -name c1 -m 256 -cpu host -smp 2,cores=2,sockets=1 -drive file=/vms/centos/cts1.img,if=virtio,media=disk,cache=writeback,format=qcow2 -drive file=/vms/ISOs/CentOS-7-x86_64-Minimal-1511.iso,media=cdrom -boot order=cd -net nic,model=virtio,macaddr=52:54:00:00:00:01 -net tap,script=/etc/qemu-ifup -vnc :0 -daemonize
- 配置網絡並啓動第二個虛擬機 C2 進程
第二臺虛擬機需要修改:名稱、磁盤映像文件、網卡接口的MAC地址、VNC的監聽端口
qemu-kvm -name c2 -m 256 -cpu host -smp 2,cores=2,sockets=1 -drive file=/vms/centos/cts2.img,if=virtio,media=disk,cache=writeback,format=qcow2 -drive file=/vms/ISOs/CentOS-7-x86_64-Minimal-1511.iso,media=cdrom -boot order=cd -net nic,model=virtio,macaddr=52:54:00:00:00:02 -net tap,script=/etc/qemu-ifup -vnc :1 -daemonize
- 查看虛擬機運行狀態
ps aux | grep qemu
#
root 7623 1.8 13.6 729268 277352 ? Sl 16:23 0:20 qemu-kvm -name c1 -m 256 -cpu host -smp 2,cores=2,sockets=1 -drive file=/vms/centos/cts1.img,if=virtio,media=disk,cache=writeback,format=qcow2 -drive file=/vms/ISOs/CentOS-7-x86_64-Minimal-1511.iso,media=cdrom -boot order=cd -net nic,model=virtio,macaddr=52:54:00:00:00:01 -net tap,script=/etc/qemu-ifup -vnc :0 -daemonize
root 7881 0.7 5.6 831664 115776 ? Sl 16:31 0:04 qemu-kvm -name c2 -m 256 -cpu host -smp 2,cores=2,sockets=1 -drive file=/vms/cirros/cirros2.img,if=virtio,media=disk,cache=writeback,format=qcow2 -net nic,model=virtio,macaddr=52:54:00:00:00:02 -net tap,script=/etc/qemu-ifup -vnc :1 -daemonize
ss -tunl
#
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
udp UNCONN 0 0 * %virbr0:67 *:*
tcp LISTEN 0 1 *:5900 *:*
tcp LISTEN 0 1 *:5901 *:*
ifconfig
#
br-int: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::30a5:70ff:fe37:bca7 prefixlen 64 scopeid 0x20<link>
ether 46:53:ba:f9:9e:2e txqueuelen 1000 (Ethernet)
RX packets 160 bytes 25492 (24.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
tap0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::a41f:2ff:fe60:c47d prefixlen 64 scopeid 0x20<link>
ether a6:1f:02:60:c4:7d txqueuelen 1000 (Ethernet)
RX packets 151 bytes 26298 (25.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 17 bytes 2082 (2.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
tap1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::4453:baff:fef9:9e2e prefixlen 64 scopeid 0x20<link>
ether 46:53:ba:f9:9e:2e txqueuelen 1000 (Ethernet)
RX packets 9 bytes 1434 (1.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 98 bytes 16644 (16.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 使用命令 “vncviewer :0” 連接至虛擬機 C1
ifconfig ens33 10.0.0.1/24 up
- 使用命令 “vncviewer :1” 連接至虛擬機 C2
ifconfig ens33 10.0.0.2/24 up
- 兩臺主機間通信
ping 10.0.0.2
僅主機網絡通信模型的實現
在以上實驗的基礎上,給網橋設備一個相同分段的 IP 地址,可以實現僅主機網絡模式,即:宿主機可以和運行與其上虛擬機通信
虛擬設備 br-int 原來工作在OSI七層模型中的二層——數據鏈路層,當分配了IP地址後,br-int 設備工作在三層——網絡層,br-int 在未分配IP地址前,可以理解爲一個虛擬交換機設備,分配IP地址後,具備了虛擬路由器的功能。
- 爲虛擬機之間的虛擬交換機設備配置一個同網段的IP地址
ifconfig br-int 10.0.0.254/24 up
[root@localhost cirros]# ifconfig br-int
#
br-int: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.254 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::30a5:70ff:fe37:bca7 prefixlen 64 scopeid 0x20<link>
ether 46:53:ba:f9:9e:2e txqueuelen 1000 (Ethernet)
RX packets 416 bytes 67220 (65.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 實現宿主機與虛擬機通信
ping 10.0.0.1
ping 10.0.0.2
* NAT 網絡通信模型*的實現
在“僅主機”網絡模型的基礎上,添加 iptables 的 nat 規則(SNAT 或 DNAT), 即可以實現NAT網絡模式,即:宿主機作爲運行與其上虛擬機的正向代理,將公網上的通信請求轉發至對應的虛擬機,而虛擬機以宿主機的身份向公網發出通信請求。
本實驗旨在訪問宿主機上運行的虛擬機的ssh服務,因爲宿主機(172.16.50.18)也提供了ssh服務,所以需要做端口映射
- 將虛擬機 C1 ,C2 的網關指向 br-int 設備的 IP 地址
route add default gw 10.0.0.254
- 啓用宿主機系統的核心轉發功能
sysctl -w net.ipv4.ip_forward=1
#
net.ipv4.ip_forward = 1
- 配置 iptables 的 SNAT 規則
需要進行IP地址和端口映射
iptables -t nat -A PREROUTING -d 172.16.50.18 -p tcp --dport 22922 -j DNAT --to-destination 10.0.0.1:22
iptables -t nat -vnL
#結果爲
Chain PREROUTING (policy ACCEPT 257 packets, 38061 bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp -- * * 0.0.0.0/0 172.16.50.18 tcp dpt:22922 to:10.0.0.1:22
- 在某一臺遠程主機上使用ssh連接至 C1 虛擬機
ssh -p 22922 root@172.16.50.18
- 如果要連接另一臺虛擬機,可以定義另一個端口。
配置內部網絡的 DHCP 服務
- 在宿主機上安裝dnsmasq程序
yum install dnsmasq dnsmasq
- 在宿主機上創建一對虛擬網卡接口設備,一端配置在 br-int 設備上,
ip link add vethy.1 type veth peer name vethy.2
ifconfig vethy.1 up
brctl addif br-int vethy.1
ip netns add dhcpsrv
ip link set dev vethy.2 netns dhcpsrv
ip netns exec dhcpsrv ifconfig -a
ip netns exec dhcpsrv ifconfig vethy.2 10.0.0.253/24 up
ip netns exec dhcpsrv ifconfig
ip netns exec dhcpsrv dnsmasq -F 10.0.0.20,10.0.0.100 -o 3,10.0.0.254
ip netns exec dhcpsrv ps aux | grep dnsmasq
- 重啓虛擬機,查看狀態
ifconfig
route -n
兩臺宿主機之上的虛擬機之間通信
可採用將兩臺宿主機橋接的方式
如果不想將宿主機之上的虛擬機暴露於公網之中,需要使用疊加網絡模型(隧道網絡)。