一種給PVE虛擬機(jī)磁盤擴(kuò)容的方法
PVE(Proxmox Virtual Environment )是一個(gè)基于QEMU/KVM和LXC的開源服務(wù)器虛擬化管理解決方案,可以使用集成的 Web 界面或通過 CLI 管理虛擬機(jī)、容器、高可用性集群、存儲(chǔ)和網(wǎng)絡(luò)。和ESXi相比,易用性不相上下,性能略差(客戶操作系統(tǒng)為Windows時(shí)遲滯感更明顯),基于AGPL協(xié)議,可以免費(fèi)使用,對(duì)于需要跑Linux Server的場(chǎng)景是個(gè)不錯(cuò)的虛擬化方案。
1. 背景和思路
我在家里的低功耗服務(wù)器上用PVE作為虛擬化平臺(tái),在它上面再跑Linux、Windows的各客戶操作系統(tǒng),已經(jīng)運(yùn)行了兩年了,穩(wěn)定可靠,個(gè)人體驗(yàn)不是以Windows為核心的虛擬化業(yè)務(wù)完全可以替代ESXi,ESXi安裝時(shí)有些硬件驅(qū)動(dòng)還不好找,安裝PVE我還沒有遇到類似問題,感覺硬件兼容性比ESXi強(qiáng)。

最近,我在PVE上架設(shè)的OMV(OpenMediaVault)的操作系統(tǒng)磁盤空間已經(jīng)吃光了,于是我花了一些時(shí)間研究PVE虛擬機(jī)磁盤擴(kuò)容的方案,一個(gè)晚上兩遍實(shí)操下來,感覺我用的方法是一種快速、低風(fēng)險(xiǎn)且向后兼容的方案。
按傳統(tǒng)思路,磁盤擴(kuò)容操作就是對(duì)“磁盤”分區(qū)進(jìn)行擴(kuò)大,但是如果要擴(kuò)容的分區(qū)緊鄰分區(qū)存在數(shù)據(jù)就需要移動(dòng)緊鄰分區(qū)的數(shù)據(jù),才能執(zhí)行擴(kuò)容操作,這是高風(fēng)險(xiǎn)且非常耗時(shí)的操作。我要擴(kuò)容的分區(qū)是主分區(qū),后面緊跟交換分區(qū)和其他分區(qū),如下圖所示:

如果操作系統(tǒng)是默認(rèn)安裝,大家普遍會(huì)使用這種分區(qū)結(jié)構(gòu),那就得先收縮后面的分區(qū)且向后挪動(dòng)數(shù)據(jù),再擴(kuò)大主分區(qū)。我最早也是打算采用這個(gè)方案,但考慮到風(fēng)險(xiǎn)猶豫了一段時(shí)間。后來看PVE的“磁盤”其實(shí)是操作系統(tǒng)概念里的文件,并不是直接在物理磁盤上劃分的分區(qū),如下圖所示:

那要增加磁盤在PVE里只是多個(gè)文件而已,結(jié)合我的需求,我OMV系統(tǒng)磁盤上最耗空間的是Docker,則我只要增加一塊磁盤,再把Docker文件移動(dòng)到這塊新磁盤上,最后把磁盤掛載進(jìn)去覆蓋Docker目錄,就是實(shí)現(xiàn)了Docker已用空間的回收,解決了系統(tǒng)盤空間耗光的問題,對(duì)系統(tǒng)整體來說增加了一塊磁盤(雖然它只是定向給Docker使用),也是間接的實(shí)現(xiàn)了擴(kuò)容。

2. 動(dòng)手實(shí)操
2.1 備份
操作前一定要做備份。PVE的備份就是復(fù)制磁盤文件,我在家里千兆網(wǎng)復(fù)制文件平均速度超過100M/秒,不拆磁盤對(duì)拷,通過網(wǎng)絡(luò)復(fù)制,吃個(gè)晚飯它就拷完了,還是比較快的。
在Windows shell /?Linux termial上執(zhí)行類似這樣的命令:
scp -r root@192.168.x.x:/var/lib/vz/images/ .
2.2 增加一塊磁盤
PVE和OMV支持熱撥插(可能還和磁盤陣列/Raid卡相關(guān)),OMV在運(yùn)行狀態(tài)也可以直接操作。

知識(shí)點(diǎn):在PVE上添加磁盤,它并不會(huì)立即分配空間,因此可以指定一個(gè)足夠大的磁盤容量而不用管PVE磁盤上的實(shí)際剩余空間,這樣做的好處是以后遷到更大的物理盤的時(shí)候不用再做邏輯擴(kuò)容。

添加完成后進(jìn)OMV,可以查到新磁盤:

創(chuàng)建分區(qū):
# fdisk /dev/sde
Command (m for help): n
Partition type
? ?p? ?primary (0 primary, 0 extended, 4 free)
? ?e? ?extended (container for logical partitions)
Select (default p):??
Using default response p.
Partition number (1-4, default 1):?
First sector (2048-2147483647, default 2048):?
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-2147483647, default 2147483647):?
Created a new partition 1 of type 'Linux' and of size 1024 GiB.
Command (m for help): p
Disk /dev/sde: 1 TiB, 1099511627776 bytes, 2147483648 sectors
Disk model: QEMU HARDDISK? ?
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x81f4463c
Device? ? ?Boot Start? ? ? ? End? ? Sectors? Size Id Type
/dev/sde1? ? ? ? 2048 2147483647 2147481600 1024G 83 Linux
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
格式化:
# mkfs -t ext4 /dev/sde1
mke2fs 1.46.2 (28-Feb-2021)
Discarding device blocks: done? ? ? ? ? ? ? ? ? ? ? ? ? ??
Creating filesystem with 268435200 4k blocks and 67108864 inodes
Filesystem UUID: 5b09f5c7-cae6-4a64-afc4-19a12691f0a6
Superblock backups stored on blocks:?
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,?
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,?
102400000, 214990848
Allocating group tables: done? ? ? ? ? ? ? ? ? ? ? ? ? ??
Writing inode tables: done? ? ? ? ? ? ? ? ? ? ? ? ? ??
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: done? ? ?
2.3 掛載和復(fù)制
掛載到臨時(shí)路徑:
# mount /dev/sde1 /mnt/hd2
停掉Docker服務(wù):
# systemctl stop docker
移動(dòng)Docker文件夾進(jìn)新磁盤:
#mv?/var/lib/docker/* /mnt/hd2/
知識(shí)點(diǎn):我這里用了mv命令,這其實(shí)是個(gè)高危操作,如果中間被中斷,數(shù)據(jù)被破壞的概率很大,建議的操作是先cp,確認(rèn)成功后再rm。
卸載:
# umount /mnt/hd2
重新掛載,以覆蓋Docker目錄:
# mount /dev/sde1 /var/lib/docker/
# df -h
Filesystem? ? ? Size? Used Avail Use% Mounted on
udev? ? ? ? ? ? 9.8G? ? ?0? 9.8G? ?0% /dev
tmpfs? ? ? ? ? ?2.0G? 155M? 1.9G? ?8% /run
/dev/sda1? ? ? ? 46G? ?29G? ?15G? 66% /
tmpfs? ? ? ? ? ?9.8G? ? ?0? 9.8G? ?0% /dev/shm
tmpfs? ? ? ? ? ?5.0M? ? ?0? 5.0M? ?0% /run/lock
tmpfs? ? ? ? ? ?9.8G? ? ?0? 9.8G? ?0% /sys/fs/cgroup
tmpfs? ? ? ? ? ?9.8G? ? ?0? 9.8G? ?0% /tmp
/dev/sdd2? ? ? ?414G? 4.0G? 389G? ?2% /srv/dev-disk-by-label-data2
/dev/sdc1? ? ? ?2.7T? 1.1T? 1.5T? 43% /srv/dev-disk-by-label-data1
/dev/sdb1? ? ? ?2.7T? 904G? 1.9T? 33% /srv/dev-disk-by-label-parity1
tmpfs? ? ? ? ? ?2.0G? ? ?0? 2.0G? ?0% /run/user/0
/dev/sde1? ? ? 1007G? ?17G? 940G? ?2% /var/lib/docker
啟動(dòng)Docker服務(wù):
# systemctl start docker
檢查Docker運(yùn)行是否正常:
systemctl status docker
docker ps -a
2.4 實(shí)現(xiàn)開機(jī)掛載
前面是手工掛載,系統(tǒng)重啟后就沒有了,要實(shí)現(xiàn)開機(jī)掛載,需要改寫/etc/fstab。
首先要查UUID:
# blkid
/dev/sde1: UUID="5b09f5c7-cae6-4a64-afc4-12345" TYPE="ext4" PARTUUID="81f4463c-01"
寫fstab配置:
# cat /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>? ?<type>? <options>? ? ? ?<dump>? <pass>
# / was on /dev/sda1 during installation
...
UUID=5b09f5c7-cae6-4a64-afc4-12345?/var/lib/docker ext4 defaults 0 0
知識(shí)點(diǎn):fstab對(duì)磁盤掛載支持多種寫法,用“/dev/sde1 /var/lib/docker”這種寫法更直觀,但這里有一個(gè)大坑,就是Linux的磁盤序號(hào)是動(dòng)態(tài)的。我操作時(shí)新磁盤在/dev/sde,重啟后變成/dev/sda了,原來操作系統(tǒng)磁盤由/dev/sda變成了/dev/sde,和新磁盤調(diào)了個(gè)個(gè),Docker服務(wù)啟動(dòng)后往/dev/sde寫數(shù)據(jù),直接破壞操作系統(tǒng),這也是我開篇說一晚上實(shí)操兩遍的原因。同時(shí)也是前面強(qiáng)調(diào)一定要備份的原因!一定要備份!我上面給出的是用UUID的寫法,這樣不受磁盤序號(hào)影響,可以鎖定具體的磁盤。
最后重啟檢查是否正常,有異常檢查前面的步驟,沒有就可以收工了。
操作前后的空間占用情況對(duì)比:
# df -h
Filesystem? ? ? Size? Used Avail Use% Mounted on
udev? ? ? ? ? ? 9.8G? ? ?0? 9.8G? ?0% /dev
tmpfs? ? ? ? ? ?2.0G? 155M? 1.9G? ?8% /run
/dev/sda1? ? ? ? 46G? ?46G? ?0? 100% /
...
# df -h
Filesystem? ? ? Size? Used Avail Use% Mounted on
udev? ? ? ? ? ? 9.8G? ? ?0? 9.8G? ?0% /dev
tmpfs? ? ? ? ? ?2.0G? 155M? 1.9G? ?8% /run
/dev/sda1? ? ? ? 46G? ?29G? ?15G? 66% /
...
/dev/sde1? ? ? 1007G? ?17G? 940G? ?2% /var/lib/docker
...
3. 總結(jié)和建議
用這個(gè)方案操作,相對(duì)傳統(tǒng)的調(diào)整分區(qū)大小的方案,操作難度小很多,操作時(shí)間短很多(相應(yīng)的服務(wù)中斷時(shí)間就短很多),風(fēng)險(xiǎn)小了很多,在有冗余空間的情況下沒有增加硬件成本,且以后PVE增加新的大磁盤后,遷移成本?。ㄊ褂肞VE的預(yù)劃定足夠大的容量,避免以后的二次擴(kuò)容、迭代擴(kuò)容)。
早期我在做我的空間規(guī)劃的時(shí)候,計(jì)劃OMV只是放個(gè)操作系統(tǒng),數(shù)據(jù)全部放在掛載磁盤上,沒有擴(kuò)容需求,但是在使用過程中把OMV作為核心系統(tǒng)使用,Docker服務(wù)基本放在上面,導(dǎo)致空間消耗殆盡,這是當(dāng)時(shí)沒有想到的(包括我的臺(tái)式機(jī)Windows、筆記本MacOS都有遇到系統(tǒng)盤不夠用的情況),因此建議1:系統(tǒng)盤劃分時(shí)盡可能的大。
創(chuàng)建虛擬磁盤時(shí)我習(xí)慣以當(dāng)前宿主物理磁盤大小來做規(guī)劃,其實(shí)很多虛擬化平臺(tái),也包括桌面版本的VMWare 、VirtualBox、Parallels Desktop等,都有指定非預(yù)分配的選項(xiàng),即時(shí)分配,用多少分配多少,因此建議2:根據(jù)業(yè)務(wù)而不是當(dāng)前物理磁盤剩余空間來指定磁盤大小。
不僅是磁盤擴(kuò)容,在運(yùn)維過程中總有一些不確定因素和意外發(fā)生,因此建議3:做好備份!