以下過程都在 root 權限下操作,如果有找不到指令或出現 Premission Denied 權限不足提示,自行視情況加 sudo 或進 root 權限模式操作。

提示符號 $ 並不是指在一般權限下執行,單純只是 root 提示符號 # 容易與註解 # 混淆。

準備工作

  • 一台主機
  • 2G 以上 USB 隨身碟
  • 路環境有 DHCP Server,且取得的 IP 可以連上網路
  • Ubuntu Server 安裝 ISO 檔

安裝 Ubuntu server

製作 Live USB 開機安裝碟

Windows 可以用 Rufus 製作。

macOS 環境則可以直接製作:

  1. 磁碟工具程式清除(格式化) USB 隨身碟,格式選 FAT + GUID
  2. 在終端機執行diskutil list確認 USB 隨身碟掛載的裝置代號 (假設 /dev/disk2)
  3. 卸載 USB 隨身碟
    diskutil unmountDisk /dev/disk2
  4. 把 ISO 轉換成 DMG 檔
    hdiutil convert -format UDRW -o converted-ubuntu-filename ubuntu-live-server-amd64.iso
  5. 把的 DMG 檔寫入 USB 隨身碟
    dd if=converted-ubuntu-filename.dmg of=/dev/disk2 bs=1m
  6. 完成後插上要安裝 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 aip 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 作業系統,雙核 cpu2G 記憶體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 聽起來很恐怖,實際上只是強迫關機

刪除 VM
virsh undefine vmname
僅刪掉 VM 設定檔,磁碟映象檔要自己手動刪除

顯示運作中的 VM
virsh list

顯示所有已建立的 VM
virsh list --all

編輯 VM 設定檔
virsh edit vmname

建立 Snapshot
virsh snapshot-create vmname

列出已儲存 Sanpshot
virsh snapshot-list vmname

回復 Snapshot
virsh snapshot-revert --snapshotname