最後更新: 2022-02-07
目錄
- 查看 Network
- 匯出 / 匯入
- 設定 network 的 XML
- More Example XML
- 修改 Interface settings (iface-*)
- net-destroy 與 net-undefine
- Interface 的狀況 (list/up/down)
- VM 的 Network Interface XML
- libvirt 的 NIC 類型
- Quality Of Service
- Generate a MAC address
- VhostNet
- libvirt openvswitch xml
- DHCP With Static IP
- Port forwarding(iptables)
查看 Network
查看 Host 上的 libvrit 定義了什麼 network
net-list [--all]
e.g.
virsh net-list # State=active 的才顯示出來
Name State Autostart Persistent -------------------------------------------- default active yes yes
virsh net-list --all # 所有都顯示
Name State Autostart Persistent ---------------------------------------------------------- default inactive no yes vmnet inactive no yes
某 network 資料:
virsh net-info default
Name: default UUID: 93299a8c-aac9-48a2-85ad-594c3738fe5f Active: yes Persistent: yes Autostart: yes Bridge: virbr0
修改 network 的 XML:
e.g.
virsh net-edit default
<network> <name>default</name> <uuid>93299a8c-aac9-48a2-85ad-594c3738fe5f</uuid> <forward mode='nat'/> <bridge name='virbr0' stp='on' delay='0'/> <mac address='52:54:00:6a:53:67'/> <ip address='192.168.122.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.122.2' end='192.168.122.254'/> </dhcp> </ip> </network>
Route
A static route added to the virtualization host
default route
<network> <name>openwrt-br0</name> <route address='0.0.0.0' prefix='0' gateway='192.168.18.1'/> </network>
route to net
<route address="192.168.222.0" prefix="24" gateway="192.168.122.2"/>
匯出 / 匯入
匯出 network 設定:
# 建立一個有 DHCP 及 NAT 功能的 Network
virsh net-dumpxml default > openwrt-br0.xml
<network> <name>default</name> <uuid>e3e38ab9-9663-6e24-acba-0742652d1f60</uuid> // 每 network 都有自己的 UUID <forward mode='nat'dev="eth0"/> // 'nat' 係 Default 設定來 <bridge name='virbr0' stp='on' delay='0' /> // 所有 VM 的 interface 都會連此 bridge <ip address='192.168.122.1' netmask='255.255.255.0'> // DHCP Setting <dhcp> <range start='192.168.122.2' end='192.168.122.254' /> </dhcp> </ip> </network>
匯入 network 修改:
virsh net-define openwrt-br0.xml
Persistent network(net-define) 與 Transient network(net-create)
A persistent network => created using net-define
- It lasts until explicitly destroyed
- 建立後 State 係 inactive (net-list --all 時才看到)
- 可以設定 Autostart 成 yes (net-autostart ros-sw0)
- 支持 define 及 modify
virsh # net-list --all
Name State Autostart Persistent
----------------------------------------------
default active yes yes
ros-sw0 inactive no yes
vmbr0 active yes yes
A transient network => created using net-create
- It lasts until destroyed or the libvirt daemon restarts
- 建立後 State 係 active
- 不可以設定成 Autostart
設定 network 的 XML
建立基本的 XML
openwrt-br0.xml
<network> <name>openwrt-br0</name> <bridge name="openwrt-br0"/> </network>
virsh net-create /root/libvirt-xml/vmbr0.xml
* Create 後會有 vmbr0-nic 駁在 vmbr0 上
bridge settings
<bridge name='openwrt-br0' stp='off' delay='0'/>
Forwarding:
如果沒有指定 forward, 那 network 將會是獨立的 (出唔到其他 network)
可用的 forwording mode 有:
- nat ( firewall rules will restrict forwarding to the named device only )
- bridge ( an existing host bridge that was configured outside of libvirt )
- route ( if the attribute is set, firewall rules will restrict forwarding to the named device only)
- private (uses a macvtap "direct" connection)
- passthrough
- hostdev
建立 network 的步驟
- 建立 XML
- 匯入: net-define / net-create
- 修改: net-edit
- 啟動: net-start
- 自動: net-autostart
start / stop network
Start:
virsh net-start openwrt-br0 # Start a (previously defined) inactive network.
Output
Network openwrt-br0 started
Checking
brctl show
bridge name bridge id STP enabled interfaces
openwrt-br0 8000.5254009705b3 no openwrt-br0-nic
ip link show openwrt-br0
37: openwrt-br0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000 link/ether 52:54:00:97:05:b3 brd ff:ff:ff:ff:ff:ff
ip link show openwrt-br0-nic
38: openwrt-br0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master openwrt-br0 state DOWN mode DEFAULT group default qlen 1000 link/ether 52:54:00:97:05:b3 brd ff:ff:ff:ff:ff:ff
iptables -vnL # Isolated bridge
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- openwrt-br0 openwrt-br0 0.0.0.0/0 0.0.0.0/0 0 0 REJECT all -- * openwrt-br0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable 0 0 REJECT all -- openwrt-br0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Stop:
virsh net-destroy openwrt-br0
net-autostart
# Configure a virtual network to be automatically started at boot.
net-autostart <network> [--disable]
More Example XML
Set bridge IP
<network>
<name>openwrt-br0</name>
<bridge name='openwrt-br0' stp='off' delay='0'/>
<ip address='192.168.18.254' netmask='255.255.255.0'/>
</network>
NAT bridge:
<network> <name>default</name> <forward mode='nat'/> <bridge name='virbr0' stp='on' delay='0' /> <ip address='192.168.122.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.122.100' end='192.168.122.199'/> </dhcp> </ip> </network>
* If the "dev" attribute is set, the firewall rules will restrict forwarding to the named device only.
Isolated bridge:
* 沒有 <forward mode="X"/>
<network> <name>default</name> <bridge name='openwrt-br0'/> </network>
使用 Host 上的 br0:
* br0 本身在 host 上是存在的
<network>
<name>host-bridge</name>
<forward mode="bridge"/>
<bridge name="br0"/>
</network>
Route:
<network> <name>local</name> <bridge name="virbr1" /> <forward mode="route" dev="eth1"/> <ip address="192.168.122.1" netmask="255.255.255.0"> <dhcp> <range start="192.168.122.2" end="192.168.122.254" /> </dhcp> </ip> </network>
修改 Interface settings (iface-*)
# 例出 Host 的 NIC
iface-list
Name State MAC Address ------------------------------------- lo active 00:00:00:00:00:00 vmbr0 active c8:60:00:xx:xx:xx vmbr1 active f8:d1:11:xx:xx:xx
# Create a bridge device and attach an existing network device to it
iface-bridge interface bridge [--no-stp] [delay] [--no-start]
# Export & Import
virsh iface-dumpxml NIC > NIC.xml
i.e. virsh iface-dumpxml vmbr0
<interface type='bridge' name='vmbr0'> <protocol family='ipv4'> <ip address='192.168.88.150' prefix='24'/> </protocol> <bridge> <interface type='ethernet' name='eth1'> <link speed='1000' state='up'/> <mac address='c8:60:00:xx:xx:xx'/> </interface> </bridge> </interface>
virsh iface-define NIC.xml
net-destroy 與 net-undefine
# To disable(stop) virbr0
virsh net-destroy openwrt-br0
# 刪除此 network 的設定檔
virsh net-undefine openwrt-br0
Interface 的狀況 (list/up/down)
List:
virsh # domif-getlink win7-iv
Interface Type Source Model MAC ------------------------------------------------------- win7-iv bridge vmbr0 virtio 52:54:00:??:??:??
status:
virsh # domif-getlink debian3 52:54:20:52:75:d3
52:54:20:52:75:d3 up
up/down:
domif-setlink domain interface-MAC state [--persistent]
state: up / down
Example:
virsh # domif-setlink debian3 52:54:20:52:75:d3 down
Device updated successfully
行完後 XML 會如下
<interface type='bridge'>
<mac address='?:?:?:?:?:?'/>
<source bridge='br0'/>
<target dev='admin'/>
<model type='virtio'/>
<link state='down'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
# IP Address
virsh # domifaddr win7-iv
Name MAC address Protocol Address -------------------------------------------------------------------------------
某 VM 的流量(domifstat):
virsh # domifstat centos6a vnet0
vnet0 rx_bytes 2569 vnet0 rx_packets 45 vnet0 rx_errs 0 vnet0 rx_drop 0 vnet0 tx_bytes 1118 vnet0 tx_packets 18 vnet0 tx_errs 0 vnet0 tx_drop 0
VM 的 Network Interface XML
Simple bridge 的 XML:
連接到 host 已有的 bridge
<interface type='bridge'>
<source bridge='br0'/>
</interface>
Bridge (more setting)
<interface type='bridge'> <mac address='52:54:00:f1:63:1b'/> <-- 非必要, 會自動補上 <source bridge='br0'/> <-- 對應了 type <target dev='myvm-nic'/> <-- 可以不填, Default: vnet<n>, 人手的話不可以是 vnet 及 vif 開頭 現在設定會有 if-d3 bridge 到 br0 上 <model type='virtio'/> <-- e1000 亦是個不錯的選擇 <link state='down'/> <-- 多餘的一句來 </interface>
查看:
root@home:~# brctl show
bridge name bridge id STP enabled interfaces br0 8000.00196632d6c4 no eth0 myvm-nic
Host 上的 Networking:
A guest can be connected to the virtual network based on the network name.
<interface type='network'>
<source network='host_network'/> # 行 "net-list" 見到的 "Name"
<target dev='myvm2'/> # 在 host 上行 "ip link" 會見到這個名
</interface>
libvirt 的 NIC 類型
XML
<interface type='network'> <source network='default'/> <model type='e1000'/> </interface>
model type:
- rtl8139 # 建議 winxp 用它 (sp3 都是沒有 e1000 的 driver...) <-- 10/100Mb/s
- pcnet # 建議 NT4 用它 <-- 10Mb/s
- e1000 # 建議 server03 用它 <-- 1Gb/s
- virtio # 建議 debian6 用它 <-- 1Gb/s
- ...
查看所有可用的 NIC:
qemu-system-i386 -net nic,model=?
out
qemu: Supported NIC models: ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio
Quality of Service
<forward mode='nat' dev='eth0'/> <bandwidth> <inbound average='1000' peak='5000' burst='5120'/> <outbound average='128' peak='256' burst='256'/> </bandwidth>
average: kilobytes per second
peak: kilobytes per second
burst: amount of bytes that can be burst at peak speed.
Generate a MAC address
#!/bin/bash
# generate a random mac address for the qemu nic
printf 'DE:AD:BE:EF:%02X:%02X\n' $((RANDOM%256)) $((RANDOM%256))
[說明1] $RANDOM
$RANDOM 是 bash 的 built-in variable
[說明2] printf
Usage:
printf FORMAT [ARGUMENT]
\t horizontal tab
printf "%s\t%s\n" "1" "2 3" "4" "5"
1 2 3 4 5
VhostNet
* in-kernel guest networking performance enhancement (using the Linux kernel rather than QEMU)
guest physical memory mapping to the vhost-net driver
10% less than e1000 on my system and greater throughput (8x the normal virtio, around 7~8 Gigabits/sec here)
* CONFIG_VHOST_NET=y
grep CONFIG_VHOST_NET /boot/config-*-amd64
CONFIG_VHOST_NET=m
Check device
ls -l /dev/vhost-net
crw------- 1 root root 10, 238 Mar 17 17:27 /dev/vhost-net
* 要 qemu-kvm 的 version 0.13.0 才用到
checking version: kvm --version
Load module
modprobe vhost_net
Usage:
kvm -netdev type=tap,id=guest0,script=kvm-ifup,vhost=on -device virtio-net-pci,netdev=guest0,mac=ma:c:a:dd:re:ss ....
Disabling vhost-net
* By default, libvirt uses the vhost-net in-kernel support if it is available.
# libvirt will automatically alter the qemu commandline arguments to take advantage of it
grep 'vhost=on' /var/log/libvirt/qemu/<domain>.log
Disable it
<interface type='bridge'>
...
<model type='virtio'/>
<driver name='qemu'/>
...
</interface>
* DHCP clients have problems with this implementation
During initialization the vhost driver creates a kernel thread called vhost-$pid, where $pid is the QEMU process pid.
ps aux | grep vhost-
libvirt openvswitch xml
* Libvirt 0.9.11 or later.
<interface type='bridge'> <mac address='52:54:00:71:b1:b6'/> <source bridge='ovsbr'/> <virtualport type='openvswitch'/> </interface>
"<virtualport>" element indicates that the bridge in <source> element is an Open vSwitch bridge.
DHCP With Static IP
Add static entry
net-update default add ip-dhcp-host "<host mac='52:54:31:34:7c:05' name='mininet' ip='192.168.122.222'/>" --live --config
# 多行
virsh net-update default add ip-dhcp-host \
"<host mac='52:54:31:34:7c:05' \
name='myvm' ip='192.168.122.45' />" \
--live --config
Output
Updated network default persistent config and live state
Remark: --live --config
Updated network default persistent config and live state
Delete static entry
virsh net-update default delete ip-dhcp-host \
'<host mac="52:54:00:6f:78:f3" ip="192.168.122.222"/>' \
--live --config --parent-index 0
Modify static entry
virsh net-update default modify ip-dhcp-host \
'<host mac="52:54:00:6f:78:f3" ip="192.168.122.222"/>' \
--live --config --parent-index 0
Remark: "--parent-index"
Specifies which element to select if there is more than one <ip> element.
Checking dhcp leases
virsh net-dhcp-leases default
Expiry Time MAC address Protocol IP address Hostname Client ID or DUID ------------------------------------------------------------------------------------------------------------------- 2018-04-17 13:53:06 52:54:00:b8:62:a9 ipv4 192.168.122.236/24 - -
Port forwarding(iptables)
eth0 | virbr0
2222 -> 22
GUEST_IP=192.168.122.222 GUEST_PORT=22 HOST_PORT=2222 HOST_BRIDGE=virbr0 # start iptables -I FORWARD -o $HOST_BRIDGE -d $GUEST_IP -j ACCEPT iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT # stop iptables -D FORWARD -o $HOST_BRIDGE -d $GUEST_IP -j ACCEPT iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT