以下過程都在 root 權限下操作,如果有找不到指令或出現 Premission Denied 權限不足提示,自行視情況加 sudo 或進 root 權限模式操作。
提示符號 $ 並不是指在一般權限下執行,單純只是 root 提示符號 # 容易與註解 # 混淆。
準備工作
- 一台主機
- 2G 以上 USB 隨身碟
- 路環境有 DHCP Server,且取得的 IP 可以連上網路
- Ubuntu Server 安裝 ISO 檔
安裝 Ubuntu server
製作 Live USB 開機安裝碟
Windows 可以用 Rufus 製作。
macOS 環境則可以直接製作:
- 用
磁碟工具程式
清除(格式化) USB 隨身碟,格式選 FAT + GUID - 在終端機執行
diskutil list
確認 USB 隨身碟掛載的裝置代號 (假設 /dev/disk2) - 卸載 USB 隨身碟
diskutil unmountDisk /dev/disk2
- 把 ISO 轉換成 DMG 檔
hdiutil convert -format UDRW -o converted-ubuntu-filename ubuntu-live-server-amd64.iso
- 把的 DMG 檔寫入 USB 隨身碟
dd if=converted-ubuntu-filename.dmg of=/dev/disk2 bs=1m
- 完成後插上要安裝 Ubuntu Server 的主機開機,記得進 BIOS 變更 USB 開機優先。
安裝 Ubuntu server
依提示自行照需求安裝,過程沒幾個步驟,我自己選最小安裝及啟用 OpenSSH Server,其餘都是預值安裝下去。
注意,最小安裝有許多常用基本指令(ping, ifconfig…)及套件(nano…)都沒有。
安裝完成後,先安裝 nano$ apt install nano
如果螢幕有轉 90° 使用習慣的需求,可以參考這裡。
網路設定(netplan)
這裡先設定好網路環境,後續建 VM 就可以直接套用在參數上。
修改網路設定$ nano /etc/netplan/00-installer-config.yaml
以下是設定完成後的範本:
network:
ethernets:
enp1s0:
dhcp4: no # 停用 DHCP,否則開機會多等二分鐘
enp2s0:
dhcp4: no
bridges:
br1:
interfaces: [enp1s0]
br2:
interfaces: [enp2s0]
addresses: [192.168.1.253/24]
routes: # 這部份是 gateway 的替代內容
- to: default
via: 192.168.1.1
nameservers: # 指定 DNS
addresses: [168.95.1.1, 8.8.8.8]
version: 2
重點是 bridge 的部分,把 bridges: 到 version: 2 之間的內容貼到現有內容之下,再自行依需求修改。
注意,YAML 檔對格式非常敏感,大小寫、tab、縮排、版本格式…稍有不對就拒絕套用,建議用上面的內容直接複製貼上再依需求修改。
修改好後執行netplan apply
套用,剩下的部分可以從 ssh 遠端完成設定。
替代指令
過程如果需要用到 ping、ifconfig 可以用指令替代:
ping 用 curl 替代
curl https://www.hinet.net
ifconfig 用 ip 替代
ip a
或 ip addr
下載檔案
wget <url>
或curl -O <url>
安裝 KVM
$ apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst
建立虛擬機
先建立 VM 磁碟
$ qemu-img create -f qcow2 kvm-disk01.qcow2 10g
-f: 指定格式,成長型格式,用多少佔多少,不加 -f 參數預設會用 raw 格式
qcow2:KVM/QEMU 主要使用格式。
10g:要建立給 VM 的磁碟空間。
查看磁碟檔格式
qemu-img -info filename.qcow2
範例一:光碟開機安裝建立 VM
適用於光碟開機安裝。
$ virt-install --name=testvm --os-variant=debian11 --vcpus=2 --memory 2048 --disk test-vm-console-disk.qcow2,size=5 --cdrom=/var/lib/libvirt/ubuntu-22.04.1-live-server-amd64.iso --graphics=vnc,listen=0.0.0.0,password=abcd1234 --network bridge=br1 --autostart --noautoconsole
建立名叫 testvm 的 VM,準備安裝 debian11 作業系統,雙核 cpu,2G 記憶體,5G 磁碟空間,用VNC 輸出畫面,VNC 登入密碼為 abcd1234,光碟開機掛載 ISO,VM guest 跟 KVM 以橋接模式連在同一層網路,執行後立即啟動 VM
查看支援的的作業系統 virt-install --os-variant list
範例二:直接使用現成映象檔建立 VM
適用於已可運行,不需安裝的 VM 映象檔。
如果 VM 映象檔是從別的 VM host 平台建立的映象檔,不是 KVM 原生支援的格式,要先經過轉換才能使用。
以 VirtualBox OVA 映象檔為例:
tar -xvf virtualbox.ova #OVA 檔實際就是 tar 檔
bitnami-wordpress-6.1.1-41-r41-linux-vm-debian-11-x86_64-nami.ovf
bitnami-wordpress-6.1.1-41-r41-linux-vm-debian-11-x86_64-nami.mf
bitnami-wordpress-6.1.1-41-r41-linux-vm-debian-11-x86_64-nami-disk1.vmdk
ls -alh
total 2.9G
drwxr-xr-x 7 root root 4.0K Feb 21 20:59 .
drwxr-xr-x 33 root root 4.0K Feb 19 20:28 ..
-rw-r--r-- 1 64 64 733M Feb 18 01:08 virtualbox-disk1.vmdk
-rw-r--r-- 1 64 64 235 Feb 18 01:07 virtualbox.mf
-rw-r--r-- 1 root root 733M Feb 18 06:51 virtualbox.ova
-rw-r--r-- 1 64 64 4.2K Feb 18 01:07 virtualbox.ovf
# 解包後的 vmdk 檔才是實際的映象檔
qemu-img convert -O qcow2 source.vmdk target.qcow2 # vmdk 轉換成 qcow2 格式
轉換後直接套用
$ virt-install --name=vmfromvirtualbox --os-variant=debian11 --vcpus=2 --memory 2048 --disk virtualbox.qcow2 --graphics=vnc,listen=0.0.0.0,password=abcd1234 --network bridge=br1 --import --autostart --noautoconsole
如果轉檔後檔案大 2-3 倍是因為來源檔是經過壓縮的格式。
範例三:雙磁碟開機 + GUI 輸出
適用於直接掛載原本需要製作成 USB 開機,圖型操作環境的 Live OS/Installer 映象檔。
virt-install --name=LiveOS --os-variant=generic --vcpu=2 --memory 8192 --disk liveOSimage.qcow2 --disk vmLocalDisk.qcow2,size=16 --video virtio --graphics=vnc,listen=0.0.0.0,password=abcd1234 --network bridge=br1 --import --autostart --noautoconsole
幾個地方要注意:
- 除非是光碟映象檔,不然只要來源映象檔是可開機的磁碟格式(包含 USB boot Live OS image),記得先轉換成 qcow2 格式(參考範例二)。
- 如果要安裝的作業系統核心或版本不在清單上或無法確認,–os-variant 參數可填 generic。
- 如果 Live OS 是安裝程式,安裝完後記得先執行 virsh edit 把第一組 <disk> 到 </disk> 的設定刪掉,不然重開機又會重新進入 Live OS。
- 如果開機、安裝後的操作環境是文字介面,可以把 –video virtio 參數拿掉。
無論是直接套用現成映象檔還是從光碟開機安裝建立新的 VM ,執行後就可以立即用 VNC 從遠端登入 KVM 的 IP 操作,到這裡基本上 KVM 就建置完成,後面是建議補充設定。
設定 console 輸出
VM 端啟用 console 輸出
$ sudo systemctl enable serial-getty@ttyS0.service
$ sudo systemctl start serial-getty@ttyS0.service
從 KVM 進入 VM console
virsh list
Id Name State
----------------------------------------------------
1 ubuntu-vm1 running
2 ubuntu-vm2 running
3 ubuntu-vm3 running
virsh console ubuntu-vm1 #輸入 name 或 ID 編號都可以
Connected to domain 'ubuntu-vm2'
Escape character is ^] (Ctrl + ])
# 剛進來不會有反應,按任意鍵讓 VM 回應
debian login: vmuser
Password:
Linux debian 5.10.0-21-amd64 #1 SMP Debian 5.10.162-1 (2023-01-21) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Feb 20 20:22:09 UTC 2023 on ttyS0
vmuser@debian:~$
按 Ctrl + ] 可退出console
要特別注意 console 同一時間只能有一個 session,無論是從 remote terminal 或從 local 進入 VM console,其中一個 session 要先 Ctrl + ] 退出,否則會出現 operation failed 錯誤訊息。
停用 VM VNC
如果 VM 是文字操作環境,建議可移除 VNC 連線提升一些安全性。
$ virsh edit alp
把 <graphic> 到 </graphic> 這幾行全部刪掉,包含 <graphic> 及 </graphic>,刪掉後按 Ctrl + X 離開就會自動儲存。
用 VNC 登入無法複製貼上、終端文字畫面無法回捲…除非有圖形操作或一定要看到最最開頭的 bootloder 的需求再保留。
讓 virsh shutdown 有作用的方法
如果執行virsh shutdown
VM 卻沒反應,照以下方式修改 VM 的設定檔
$ virsh edit <vmname>
找出 <channel type='unix'>
那一行,把裡面改成以下內容:
<channel type='unix'>
<target type='virtio' name='org.qemu.guest_agent.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
KVM 常用指令匯整
VM 開機|關機|暫停|重開機 virsh start|shutdown|suspend|reboot vmname
強迫關機virsh destroy vmname
destroy 聽起來很恐怖,實際上只是強迫關機
刪除 VMvirsh undefine vmname
僅刪掉 VM 設定檔,磁碟映象檔要自己手動刪除
顯示運作中的 VMvirsh list
顯示所有已建立的 VMvirsh list --all
編輯 VM 設定檔virsh edit vmname
建立 Snapshotvirsh snapshot-create vmname
列出已儲存 Sanpshotvirsh snapshot-list vmname
回復 Snapshot virsh snapshot-revert --snapshotname