本文已過時。 請改參考 在 ubuntu 18.04 底下為 kvm 打造的虛擬區域網路
qemu/kvm 是蠻底層的 linux 虛擬化工具, 只適合用於單一虛擬機的場合。 它固定配 10.0.2.15 的 IP 給虛擬機, 這個 IP 僅供虛擬機自嗨用, 從 host 並不能用這個 IP 連到虛擬機; 。 如果要管理一整群虛擬機, 各自要有 ip、 彼此要能互連, 理論上應該改用 virsh 跟 virt-manager 比較好。 不過這兩者的相依套件蠻多的。 對於喜歡騎腳踏車勝過騎機車/開車的人來說, 其實 「含有多部 kvm 虛擬機的區域網路環境」 還是可以用 qemu/kvm 指令徒手建立出來。
假設從 route -n
查出 host
對外的網卡叫做 enp3s0, 而對外的 gateway 是 192.168.0.1。
本文的目標是要建立一個內部區域網路 192.168.29.0/24,
讓 kvm 虛擬機都連到這個內部網路, 再透過 NAT 上網。
測試環境是 lubuntu 16.04。
一、 建立 bridge
請先安裝 bridge-utils 套件, 否則等一下會出現 Cannot find device "br29" 之類的錯誤。 在 host 的 /etc/network/interfaces 最後面加上這一段:
auto br29 iface br29 inet static address 192.168.29.254 netmask 255.255.255.0 # bridge_ports none bridge_stp off bridge_fd 0 post-up echo 1 > /proc/sys/net/ipv4/ip_forward post-up iptables -t nat -A POSTROUTING -s '192.168.29.0/24' -o enp3s0 -j MASQUERADE post-down iptables -t nat -D POSTROUTING -s '192.168.29.0/24' -o enp3s0 -j MASQUERADE
注意: 請把 enp3s0 改成你的真實網卡名稱。
修改之前, 先用 ip link show
、
ip route show
、 brctl show
三個指令查看並儲存目前網路設定。
修改完之後, systemctl restart networking
或 service networking restart
或 ifup br29
或重開機, 然後再次用上述三個指令查看,
應該每句都會看到多出一列 br29。
二、 /etc/qemu-ifup 跟 /etc/qemu-ifdown
把系統原有的 /etc/qemu-if* 改名或備份。 改用以下簡單的兩句完全取代 /etc/qemu-ifup:
#! /bin/sh echo "setting up tap device $1..." # 這一句僅為幫助除錯。 成功後可刪掉。 ip link set "$1" up ip link set "$1" master br29
又用以下一句取代 /etc/qemu-ifdown:
#! /bin/sh ip link set "$1" down
並且 chmod a+x /etc/qemu-if*
開放執行權限。
每當 kvm 指令啟動虛擬機時, 會觸發 /etc/qemu-ifup 設定虛擬機的網卡;
虛擬機關機時, 會觸發 /etc/qemu-ifdown。
三、 在 br29 上面啟動 dhcp 服務
- 安裝 dnsmasq 套件。
- 編輯 /etc/dnsmasq.conf, 分別在各自適當的地方
(每一句範例註解的位置) 加上這兩句:
interface=br29 ... dhcp-range=br29,192.168.29.31,192.168.29.99,4h
- 重新啟動 dnsmasq:
systemctl restart dnsmasq
如果 dnsmasq 無法啟動, 出現 「address already in use」之類的錯誤, 有可能是因為跟 network-manager 套件衝突。 請移除 dnsmasq-base (會同時移除掉 network manager)、 重裝 dnsmasq、 再重裝 network-manager 。 詳見 這個問答。
四、 啟動 finnix 虛擬機
假設你有 中文版 finnix 光碟 (或原始英文版也可以)。
- 啟動虛擬機:
kvm -monitor stdio -cdrom finnix-ckhung16c.iso -device virtio-net,netdev=net0,mac=52:54:00:12:34:13 -netdev tap,id=net0,ifname=tap13
這裡的 mac= 跟 ifname= 可以任意取, 但不可以跟其他 kvm 虛擬機重複; 其他部分可以照抄。 啟動時應該要看到 /etc/qemu-ifup 那句 echo 所印出來的除錯訊息。 - 開機後, 用
ifconfig
查看 dnsmasq 分配給它的 ip、 用route -n
查看 dnsmasq 幫忙設定好的 gateway、 用lynx http://www.eff.org
測試瀏覽網頁。 - 用
passwd
更改密碼。 - 編輯 /etc/ssh/sshd_config, 找到 PermitRootLogin, 把 without-password 或是 no 改成 yes。
- 重新啟動 ssh:
service ssh restart
五、 啟動 SystemRescueCD
一定要開第二部虛擬機來測試一下才能完全確定有學會, 因為如果沒設定好, 兩部機器有可能會搶網卡之類的。 比較懶一點的話, 也可以兩部虛擬機都用同一張光碟來開機測試; 不過用不同的光碟會更有感覺。
因為 finnix 蠻久沒更新了, 所以最近我也常改用 SystemRescueCD。 測試步驟大致同 finnix, 只有幾個地方不太一樣:
- 它需要 256MB 的記憶體才能跑。 又, 啟動第二部虛擬機時,
mac= 跟 ifname= 不能跟先前的重複。 所以完整的指令長這樣:
kvm -monitor stdio -m 256 -cdrom systemrescuecd-x86-4.9.6.iso -device virtio-net,netdev=net0,mac=52:54:00:12:34:14 -netdev tap,id=net0,ifname=tap14
- 它好像沒裝 lynx 跟 w3m, 所以改用
wget http://www.eff.org
測試網路連線。
最後, 請從 finnix 視窗登入 SystemRescueCD, 又從 SystemRescueCD 視窗登入 finnix, 虛擬區網測試成功!
六、 除錯
如果虛擬機的網路不通, 請 (比方說, 由內向外) 依序檢查:
- dhcp 有成功嗎?
route -n
- 可以 ping 得到虛擬網路的 gateway (br29) 嗎?
ping 192.168.29.254
- 可以 ping 得到 host 的實體網卡的 IP 嗎?
- 可以 ping 得到 host 對外的實體 gateway 嗎?
如果可以 ping 得到 host 的實體網卡的 IP,
但卻出不去, 那就有可能是 iptables 沒設定好。
請下 iptables-save | grep MASQ
檢查 --
也許對外網卡的名稱打錯了?
七、 補充說明
如果新開的虛擬機並不需要跟其他虛擬機互動, 一樣可以用簡單的 (不含 -device 跟 -netdev 那兩段的) kvm 指令啟動它。 原先預設的 User Networking (SLIRP) 還是有效。 (不要用 ping 測試! 直接用瀏覽器或 ssh 測試。)
上面的 (高效率的 para-virtualization 版驅動程式)
-netdev virtio-net,...
只適用於 linux guests。 如果是 windows guests 的話, 則必須改成
-netdev e1000,...
或 -netdev rtl8139,...
。
如果希望 dnsmasq (根據虛擬機的 mac address)
派送固定的 IP 給特定的虛擬機, 可以在
/etc/dnsmasq.conf 裡加上類似這句。
dhcp-host=52:54:00:12:34:13,192.168.29.13
寫這篇時, 搜尋到 qemu 的 wiki、 2015 年的文章、 2009 年的文章 等等幾篇。 不過想要把虛擬機群直接接到實體網卡對外網路時, 一直失敗。 反正就算成功了, 也會有 (1) 不適用於 wifi (2) 比較危險 (3) 需要動到真實網卡的設定 等等幾大缺點。 所以最後還是改參考我自己寫的、 解釋得很詳盡的、 已經快忘光的 「我的免費有線分享器」 那篇, 改用 NAT 間接上網比較簡單。
騎腳踏車就是比較辛苦, 不過也特別有感就感啊!
沒有留言:
張貼留言
因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。