在使用虛擬機時,如果磁盤空間沾滿,我們該怎樣擴容呢?
這篇文章分兩種情況來討論
情況一、虛擬機沒有使用邏輯卷,直接擴容磁盤。
情況二、虛擬機使用了邏輯卷,添加一個磁盤,然后擴容邏輯卷。
情況一
先來聊聊情況一,虛擬機沒有使用邏輯卷,怎樣直接擴容磁盤以及虛擬機內的文件系統。
整體的大致步驟如下,先看一下,有個思路:
一、做好磁盤鏡像備份
二、增加磁盤鏡像的容量
三、登錄虛擬機,擴容文件系統
此處以使用qcow2磁盤鏡像的虛擬機為例,qcow2磁盤只支持增大,不支持縮小,所以我的模板機一般都設置的默認磁盤大小比較小,100G或者200G,而且都不是立即分配磁盤空間的,等真正用滿的時候,再擴容也不遲,除非是一些確定需要大空間的應用,我會在虛擬機投入使用前就完成擴容,還有,生產環境中,一定要提前備份好磁盤鏡像,避免操作失敗后數據丟失。
備份完成后,確認需要擴容的磁盤沒有快照,qcow2磁盤如果有快照,是不能擴容的,可使用virsh snapshot-list命令查看是否有虛擬機快照,或者使用qemu-img snapshot -l查看磁盤鏡像是否有單獨的磁盤快照,比如,查看kvm1的磁盤鏡像的快照,可以使用如下命令
磁盤鏡像如果有快照,無法進行擴容
再次確認,已經備份了需要擴容的磁盤,然后開始操作,此處以kvm4為例,從宿主機可以看到,目前kvm4已經啟動
登錄kvm4,查看虛擬機磁盤狀態,如下
從上述信息可以看出,目前kvm4虛擬機只有一塊vda磁盤,有三個分區,/dev/vda1分區是boot分區,/dev/vda2是swap分區,/dev/vda3是根文件系統,根的大小是46G,44G可用,此處假設,根分區已經沾滿了,我們需要擴容根分區,雖然最終目標是擴容根分區,但是需要先在宿主機上,為kvm4的磁盤進行擴容,擴容完磁盤后,再擴容分區的文件系統。
在宿主機上確認kvm4的磁盤鏡像路徑,如下:
可以看到,kvm4的磁盤鏡像路徑是/var/lib/libvirt/images/kvm4.qcow2,對應掛載到了kvm4的vda磁盤,先看一下目前磁盤鏡像的大小
如上所示,磁盤虛擬大小為50G,目前占用宿主機1.5G空間,磁盤格式是一個qcow2的磁盤。
現在,我們要擴容這個磁盤鏡像,增容20G的空間,但是在操作之前,請先停止虛擬機,雖然不停止也可以增容成功,但是會報錯,目前還不清楚,錯誤是否會對虛擬機以后的運行產生影響,保險起見,先停止虛擬機,然后再執行如下命令對磁盤鏡像進行擴容。
停止虛擬機后,執行如下命令
增容后,再次查看磁盤鏡像信息,如下,磁盤的virtual size已經從50G變成了70G
磁盤擴容成功后,啟動kvm4虛擬機,登錄到虛擬機內,再次查看磁盤信息,發現已經變成了75G
但是,根分區和對應的文件系統還沒有擴容,如下,可以看到/dev/vda3分區仍然識別為48G,根文件系統仍然識別為46G。
我們現在的目標就是擴容根分區和文件系統。
此處可以參考阿里雲的文檔進行擴容操作,鏈接如下:
https://help.aliyun.com/document_detail/113316.html?spm=5176.21213303.J_6028563670.36.241a3edapvGQJG&scm=20140722.S_help
我的虛擬機操作系統是centos7,分區是MBR分區,不是GPT分區,文件系統是xfs,所以,我的擴容過程可能跟實際遇到的情況不太一樣,這里需要以實際情況為准,參考上面的文檔,做出不同的細節處理,生產環境中最好提前克隆出一個機器或者做一個測試機進行模擬。
首先,在虛擬機中安裝cloud-utils-growpart工具(如果是GPT分區,先安裝gdisk),對分區進行擴容,centos7中命令如下
安裝完成后,執行如下命令擴容對應分區,我需要擴容vda3,所以命令中是vda 3,vda和3中間有空格
可以看到,分區的大小已經改變,使用命令確認,vda3分區的大小已經識別為69.9G
如果擴容完成后,再次執行擴容命令,會提示NOCHANGE…it cannot be grown,這是因為,分區已經擴展完成了,沒有富裕的空間可供擴展了,其實,還有一種情況也會報如下錯誤,導致無法擴容分區,我們一會兒再聊,先把一整套擴容流程走完,此處重復執行如下命令不會影響擴容。
vda3分區擴容完成后,需要擴容分區對應的文件系統,此處文件系統是xfs,所以執行xfs_growfs命令即可,如果是ext文件系統,需要使用resize2fs命令,此處運行的命令為xfs_growfs /dev/vda3
如下:
再次查看磁盤使用情況,可以看到,根分區已經從之前的46G擴容到了66G,如下
至此,整個擴容操作已經完成了。
此處有一個坑,剛才已經提到過,在擴容分區時,我們使用了growpart命令,如果重復執行此命令,會提示NOCHANGE…it cannot be grown,這是因為已經沒有更多空間可供分區擴容了,但是,在某些特殊情況下,磁盤明明還有很多空間,在第一次執行growpart命令時就會提示it cannot be grown,現在咱們就來聊聊這種特殊情況。
如果磁盤有很多富裕空間可供分區擴容,但是每次執行growpart命令就提示it cannot be grown,很有可能是因為,你要擴容的分區不是磁盤的最后一個分區,上例中,我要擴容的vda3就是vda磁盤的最后一個分區,如下圖,可以通過分區號或者分區區間很明顯的看出,vda3就是vda的最后一個分區
這種情況下,第一次執行growpart命令擴容分區時,應該是可以正常執行的。
但是,如果你遇到的分區是下面的情況,而你想要擴容的分區恰巧不是磁盤的最后一個分區,則無法擴容成功,會直接提示it cannot be grown
如上,vda一共有三個分區,根對應的分區是vda2,即使vda磁盤有很多富裕空間,如果想要使用growpart命令擴容vda2,也是不行的,會直接提示it cannot be grown,因為上例中,vda2后面還有一個vda3分區,而上例中的情況比較好處理,因為最后一個分區是swap分區,我們只需要刪除這個分區,然后再擴容vda2就好了,擴容完成后,再單獨掛載一個磁盤作為swap分區或者使用文件作為swap分區,所以,在做模板機的時候要避開這個坑,別問我怎么知道的。
情況二
直接擴容磁盤和文件系統的情況已經描述清楚了,現在說說添加一個磁盤,擴展lvm邏輯卷的情況,其實這里描述的重點是怎樣為虛擬機添加一塊磁盤,磁盤添加后,是用來擴展邏輯卷,還是單獨作為一個分區使用,就看具體情況了,所以此處只演示為虛擬機添加磁盤和卸載磁盤的操作,此處以kvm6為例進行演示,kvm6已經啟動了,查看kvm6當前的磁盤有哪些,在宿主機執行如下命令:
可以看到,kvm6已經有兩塊磁盤了,分別對應vda和vdb,現在,創建一塊新的磁盤,我准備將新創建的磁盤對應到kvm6的vdc上,所以直接為磁盤文件命名為kvm6_vdc.qcow2,注意!在同路徑下,不要與現有的盤重名,否則會清空同名盤,命令如下:
我們已經創建好了磁盤,但是還沒有將磁盤添加到kvm6上,在添加磁盤之前,先看看kvm6的配置文件,磁盤部分的配置如下,其他配置省略了
從配置文件中可以再次印證,目前有kvm6有兩塊盤,當我們將次三塊盤添加到kvm6以后,會多出一段第三塊盤的配置。
確保kvm6開機后,使用如下命令,將磁盤添加到kvm6虛擬機上,如下添加磁盤的操作,只能在虛擬機開機的情況下執行。
如上所示,使用virsh attach-disk為指定的虛擬機添加磁盤,–domain指定虛擬機名,–source指定要添加的磁盤文件,–subdriver指定磁盤文件的格式,由於我使用的是qcow2格式的磁盤,所以此處不能省略–subdriver參數,如果省略此參數,默認會被當做raw格式的磁盤,如果被當做raw格式的磁盤,磁盤掛載后,對應的磁盤空間會識別為磁盤實際占用的大小(與宿主機中識別的大小一樣,測試的qcow2沒有預分配空間),所以此處使用–subdriver qcow2指明磁盤格式,–target參數用來指定磁盤文件對應虛擬機中的哪個磁盤,這里有個坑,如果這個磁盤是第一次被使用,那么使用target指定的目標是通常准確的,如果這塊盤其他虛擬機使用過,那么target指定后的目標可能會出現誤差(有一定幾率),這樣描述可能讓你無法理解是什么意思,此處先不聊這個小坑,文章最后再做詳細的解釋。–targetbus virtio用來指定是否使用virtio總線驅動,由於我的虛擬機是centos7,默認支持virtio,所以添加上了,具體還需要根據虛擬機操作系統的實際情況,決定是否添加,–persistent參數表示配置是否永久生效,如果不添加–persistent參數,磁盤只是臨時添加到虛擬機中,虛擬機斷電重啟后,不會再有對應的新磁盤,也就是說,不加–persistent參數,虛擬機的xml配置文件是不會被修改的,如果加上–persistent參數,虛擬機的xml配置文件會被自動修改,添加上新磁盤的配置。
執行上述命令后,再次查看kvm6的xml配置文件,會發現多出了新磁盤的配置,如下
如上所示,最后一塊盤的配置就是我們添加的新盤,因為我們在添加磁盤時,使用了–persistent參數,進入虛擬機,查看磁盤列表,已經可以看到新加入的磁盤了。
現在要做的就是初始化磁盤了,根據需求不同,做出不同的操作,比如,是創建pv加入到卷組中,還是作為一個單獨的分區使用,就看具體情況了,為了方便演示,此處直接當做一個掛載點去使用,需要注意的是,在設置完成后,配置好自動掛載,此處不分區,直接為vdc創建xfs文件系統。
創建一個測試目錄當做掛載點,掛載新的硬盤
實際使用中,記得修改fstab,把磁盤自動掛載(當然如果是邏輯卷就另說),而且需要注意,設置自動掛載時,應該用磁盤的UUID,使用UUID是最准確最保險的。
磁盤掛載已經完成了,現在來看看怎樣卸載磁盤,操作如下
如果之前設置過自動掛載,先把對應的自動掛載配置注釋了,避免卸載磁盤后,找不到對應的磁盤影響啟動。
確定取消自動掛載后,在虛擬機系統內卸載對應的掛載點,卸載掛載點后,確保虛擬機正在運行,在宿主機中執行如下命令,
執行上述命令后,磁盤卸載操作直接生效,並且永久生效,與添加磁盤同理,–persistent參數會修改配置文件,將對應的磁盤配置段刪除。
卸載下來的磁盤也可以掛載到其他虛擬機上使用,比如,我剛剛從kvm6上卸載了kvm6_vdc.qcow2這塊磁盤,現在我想把這塊磁盤掛載到kvm5上使用,也是可以的,但是可能會遇到一些小問題,我們先來查看一下kvm5目前都有哪些磁盤
如上所示,只有一塊磁盤,對應虛擬機中的vda,此時,我們執行如下命令,將kvm6卸載下的盤掛載到kvm5上,臨時掛載命令如下:
如上所示,我們將kvm6_vdc.qcow2掛載到了kvm5上,並且指定kvm6_vdc.qcow2對應kvm5的vde,從宿主機上查看,kvm6_vdc.qcow2的確對應的是vde,但是進入kvm5,會發現,新加入的盤符並不是vde,而是vdc,如下所示
之前實驗過,有時會被識別成順位最新的一個盤符,比如,虛擬機只有一塊vda,在宿主機中指定的target是vdc,但是自動識別成第二個盤符vdb的,不過有時也會准確的按照target指定的盤符去識別,通過實驗無法確定原因,所以這是一個注意點,我們只需要記住,如果磁盤是使用過的,當添加到虛擬機時,使用–target指定盤符后,在虛擬機中實際識別的結果可能是有誤差的,有可能與在宿主機中查看的結果不一致,需要以實際情況為准,最好按照盤符的順位指定target,中間不要隔着沒有使用的盤符,比如vda后應該是vdb,那么就指定用vdb,而不是直接跳過vdb,指定vdc或者vdd,這樣容易出問題,如果出現誤差,可以嘗試卸載后再次掛載。