伺服器虛擬化 - PVE

於清樂發表於2020-11-19

伺服器虛擬化 - Hypervisor

伺服器虛擬化軟體,也叫 Hypervisor——虛擬機器管理程式,有時也稱做 Virtual Machine Monitor(VMM),它可以在宿主機上建立並管理多個虛擬機器。
目前比較流行的 Hypervisor 有:

  1. vShpere Hypervisor: 也就是 ESXi,這是一個閉源收費的伺服器虛擬化系統。基於 Linux,可直接安裝在物理機上。

    1. 優點是簡單方便,但是收費。適合中小企業,或者個人搭著玩。
    2. 成熟穩定,使用者眾多。但是各大雲服務提供商全都用 KVM 做了自己的虛擬化平臺,因為免費且自主可控。
    3. ESXi 搭配 vCenter 可以中心化地管理 ESXi 叢集,搭配 terraform/python sdk 可以實現虛擬機器的自動化建立等功能。
  2. ProxmoxVE: 一個開源免費的伺服器虛擬化系統,基於 Debian + QEMU/KVM + LXC.

    1. PVE 開源免費,而 VMware 的全套技術都是閉源收費的
    2. PVE 底層是 QEMU/KVM,儲存方案也是 Ceph/iSCSI/NFS/LVM 這些都是使用很廣泛的開源技術,學會了還可以應用在別的地方。
    3. 提供一套方便的 CLI 工具,以及 RESTful API。不論是 CLI、HTTP API 還是 Python SDK,又或者 terraform 支援,PVE 都比 ESXi 要好用很多!
    4. 文件齊全,而且很接地氣,還包含許多 QEMU/KVM/CEPH 等開源技術的內容。 反觀 VMware 的文件,真的是寫得爛得一批。
    5. 缺點在於,PVE 的 WebUI 功能不全,有些功能必須通過命令列才能實現。(這和路由器類似,高階功能只有 CLI 支援)
  3. KVM: 直接搞 KVM,有一定難度。適合進階使用者,或者大廠自己 DIY。

這裡主要介紹 PVE 的安裝與使用。

安裝 PVE

安裝過程沒啥好說的,安裝好後,需要按下面這篇文章配置國內映象源,啟用 root 賬戶 ssh 登入:

# 設定 debian 的阿里映象源
cp /etc/apt/sources.list /etc/apt/sources.list.bak
sed -i "s@\(deb\|security\).debian.org@mirrors.aliyun.com@g" /etc/apt/sources.list

# 去除煩人的訂閱提示
sed -i "s/data.status !== 'Active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js

# 設定 pve 國內映象源
# https://mirrors.bfsu.edu.cn/help/proxmox/
echo 'deb https://mirrors.bfsu.edu.cn/proxmox/debian buster pve-no-subscription' > /etc/apt/sources.list.d/pve-no-subscription.list

使用 Cloud-Init 自動配置網路卡、SSH金鑰、儲存大小配置

完全參照官方文件 Cloud-Init_Support - PVE Docs

首先下載 Cloud 版本的系統映象:

  1. CentOS Cloud 版本: 提供 qcow2 格式的映象
  2. Debian Cloud Images: 也提供 qcow2 格式的映象
  3. Ubuntu Cloud Images (RELEASED): 提供 img 格式的裸映象(PVE 也支援此格式)

上述映象和我們普通虛擬機器使用的 ISO 映象的區別,一是映象格式不同,二是都自帶了 cloud-init/qemu-guest-agent/cloud-utils-growpart 等 cloud 相關軟體。

上述三個 cloud 映象的預設名稱和系統名稱完全一致,分別為 centos/debian/ubuntu
均沒有預設密碼,並且禁用了 SSH 密碼登入,必須通過 cloud-init 設定私鑰方式進行遠端登入。

建議在 cloud-init 配置中自行設定賬號與私鑰,不要使用預設的賬號名。
比如測試環境,可以直接設定賬號為 root,並設定相應的私鑰。

接下來我們需要將得到的 qcow2 映象匯入 PVE,並用它建立一個虛擬機器模板。

首先建立虛擬機器,並以匯入的磁碟為該虛擬機器的硬碟

# 建立新虛擬機器
qm create 9000 --memory 2048 --net0 virtio,bridge=vmbr0

# 將下載好的 img/qcow2 映象匯入為新虛擬機器的硬碟
qm importdisk 9000 bionic-server-cloudimg-amd64.img local-lvm

# 通過 scsi 方式,將匯入的硬碟掛載到虛擬機器上
qm set 9000 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-9000-disk-1
# 建立一個 cloud-init 需要使用的 CDROM 盤(sr0)
qm set 9000 --ide2 local-lvm:cloudinit
# 設定系統引導盤
qm set 9000 --boot c --bootdisk scsi0
# 設定 serial0 為顯示終端,很多雲映象都需要這個。(?感覺我不需要?)
qm set 9000 --serial0 socket --vga serial0

後續配置:

  1. 手動設定 cloud-init 配置,啟動虛擬機器。
  2. 進入虛擬機器後,安裝所需的基礎環境,如 docker/docker-compose/vim/git/python3
  3. 關閉虛擬機器,然後將虛擬機器設為模板(只讀)。
  4. 接下來就可以從這個模板虛擬機器,克隆各類新虛擬機器了~

cloud-init 高階配置

PVE 使用 CDROM 只讀盤(/dev/sr0)來進行 cloud-init 的配置。
在虛擬機器啟動後,/dev/sr0 將被解除安裝。

可掛載上該只讀盤,檢視其中的初始化配置內容:

$ mkdir cloud-config
$ mount /dev/sr0 cloud-config
mount: /dev/sr0 is write-protected, mounting read-only
$ ls cloud-config
meta-data  network-config  user-data

檢視上述檔案發現 user-data 有如下問題:

  1. 它硬編碼了 manage_etc_hosts: true,這導致我手動在 /etc/cloud/cloud.cfg 裡設定的 manage_etc_hosts: false 被覆蓋。
  2. 它設定了 hostname,但是測試發現 centos7 的 hostname 仍然是 localhost,沒有被修改,原因未知。

修改 cloud-init 相關的硬編碼引數

通過前面的排查,我們發現 proxmox 有很多引數都硬編碼了,沒有通過配置暴露出來,導致我們無法修改。

為了解決這個問題,我們完全可以修改掉 PVE 程式碼裡的硬編碼引數。

首先通過全文搜尋,找到硬編碼引數的位置:

# 在 /usr/share 中全文搜尋 manage_etc_hosts 這個關鍵字
grep -r manage_etc_hosts /usr/share

直接就搜尋到了硬編碼位置是 /usr/share/perl5/PVE/QemuServer/Cloudinit.pm

手動將配置修改為 manage_etc_hosts: localhost,就能讓 cloud-init 只更新 localhost 相關的 hosts 內容。

如果希望 cloud-init 能自動設定 hostname,還可以新增引數 preserve_hostname: False.

perl 和 python 一樣,程式啟動後程式碼就載入到記憶體中了,因此對上述檔案的修改需要重啟 PVE 後,才能生效。

解決 SSH 登入速度慢的問題

貌似所有的 cloud-init 的虛擬機器,SSH 都存在速度慢的問題。
關閉掉 ssh server 的反向 DNS 解析,可以解決這個問題:

echo "UseDNS no" >> /etc/ssh/sshd_config

虛擬機器硬碟擴容

CentOS/Ubuntu/Debian 提供的 Cloud 映象,都自帶了 cloud-utils-growpart 這個元件,可以實現在擴容物理硬碟時,自動調整 Linux 的分割槽大小。

因此需要擴容虛擬機器時,直接通過 UI 皮膚/命令列擴容虛擬機器的硬碟即可, Linux 的分割槽會被 cloud-utils-growpart 自動擴容。

因為這個方便的特性,也為了減少虛擬化的開銷,Cloud 映象預設是不使用 LVM 邏輯分割槽的。
LVM 邏輯分割槽雖然方便,但是它對物理機的作用更大些。虛擬機器因為本身就能動態擴容“物理硬碟”的大小,基本不用不到 LVM。

還有一點,就是虛擬機器通常只需要一個根分割槽就行,尤其是歸 openstack/kubernetes 管的虛擬機器。
只有在使用分散式儲存之類的場景下,資料需要獨立儲存,才需要用到額外的分割槽(/data 之類的)。
一般只有物理機,才需要像網上很多文章提的那樣,為 /boot / /home 去單獨分割槽。
而且現在大家都用 SSD 了,物理機這樣做分割槽的都少了,比如我個人電腦,就是一個 / 分割槽打天下。。。

自動化工具

監控告警

常見問題

1. 匯入已有的 qcow2 映象

必須要命令列操作

先通過 scp 將 qcow2 傳輸到 PVE 上,然後命令列使用如下命令匯入映象:

# 命令格式
qm importdisk <vmid> <source> <storage>
# 示例
qm importdisk 201 vm-201-disk-1.qcow2 local-lvm

匯入完成後,在 WebUI 介面的左側會看到多了一個「未使用的磁碟 0」,
現在新建一臺新虛擬機器,然後刪除掉預設的磁碟(分離+刪除,要兩步),然後掛載這個「未使用的磁碟 0」就大功告成了。

相關文件

相關文章