如何在Vagrant虚拟机上增加磁盘大小?

我有一个由Vagrant管理的虚拟机,使用VirtualBox在Ubuntu主机服务器上。我的Vagrant box使用Puppetlabs Debian 6.0.7 basebox,它使用LVM作为其根分区。
默认情况下,磁盘大小为8GB,对于我的目的来说太小了。我想要做以下几点:
  1. 增加现有磁盘的大小以及其中的文件系统,而不需要销毁和重新创建我的虚拟机。
  2. 配置Vagrant,以便将来为此项目创建更大的磁盘。
有人可以解释一下如何做到这一点吗?

Vagrant已经增加了对自定义磁盘大小的支持(包括磁盘调整大小)。您可以在这里查看我的回答:https://askubuntu.com/a/1402237/598897 - W1M0R
9个回答

我找到了解决这个问题的最简单方法:
  • 安装这个插件: vagrant plugin install vagrant-disksize

  • 编辑Vagrantfile:

    Vagrant.configure('2') do |config|
      ...
      config.vm.box = 'ubuntu/xenial64'
      config.disksize.size = '50GB'
      ...
    end
    
  • vagrant halt && vagrant up

    • 注意:这将不能与vagrant reload一起使用

3像魔法一样好用。似乎是我遇到的最简单的解决方案。谢谢您,先生。 - Rico
2对于Debian9系统,这将增加原始磁盘大小,但不会增加Debian安装所使用的实际分区。增加的磁盘空间不能直接使用。 - Lætitia
@Tonin 你找到解决办法了吗? - Arjun
11我使用了sudo cfdisk /dev/sda工具来调整我的/dev/sda1分区,以适应所有新可用的空间。然后我告诉文件系统利用那个空间,使用命令sudo resize2fs -p -F /dev/sda1 - tutuDajuju
1谢谢。这在我的特定配置上也能正常运行。主机操作系统:Windows 10Virtual Box:6.0虚拟机操作系统:Ubuntu Xenial - Binita Bharati
1@david-edwards Vagrant已经增加了对自定义磁盘大小(包括磁盘调整大小)的支持。您可以在这里查看我的答案:https://askubuntu.com/a/1402237/598897 - W1M0R
添加插件后,您将希望执行以下操作,以确保您的操作系统实际上已经扩展。请参考以下链接:https://packetpushers.net/ubuntu-extend-your-default-lvm-space/ - undefined

个人认为,更容易的方法是附加一个额外的虚拟硬盘,并将其挂载到一个适当的挂载点,例如/opt,然后使用rsync将您的文件转移过去,以解决这个问题。毕竟,puppet vagrant boxes只用于测试目的。 原因是VBoxManage modifyhd只能处理本地VDI镜像。然而,vagrant基础镜像基本上是使用VMDK格式导出的OVF/OVA。
请参阅VirtualBox文档

--resize x选项(其中x是所需的新总空间,以兆字节为单位)允许您更改现有映像的容量;这将调整虚拟磁盘的逻辑大小,而不会对物理大小造成太大影响。[37]目前,这仅适用于VDI和VHD格式,仅适用于动态分配的变体,并且只能用于扩展(而非缩小)容量。

增加Vagrant基础镜像的磁盘容量的步骤如下:

步骤:

要能够调整硬盘大小,您需要先将其转换为VDI格式,例如使用命令VBoxManage clonehd in.vmdk out.vdi --format VDI,然后重新附加它(使用图形界面更容易)。
使用命令VBoxManage modifyhd box.vdi --resize 15360来调整大小,将容量增加到15GB。
但是这只会改变驱动器的容量,您还需要随后扩展虚拟机的文件系统。例如,对于ext{3,4}文件系统,可以使用命令resize2fs -p -F DEVICE

3请注意,在调整大小之后并在重新启动vagrant box之前,您还需要更新VirtualBox存储配置,以便使用新的VDI而不是原始的VMDK: 在VirtualBox中 > 存储 > 删除现有硬盘 > 添加硬盘(选择现有的并指向新的VDI镜像) - Steve Swinsburg
1对于Debian用户,我建议也看一下这篇文章:http://blog.lenss.nl/2012/09/resize-a-vagrant-vmdk-drive/。当我进行到第三步时,并不像运行`resize2fs`那么简单。祝你好运! - phirschybar
2我刚刚写了一份关于这个的综合指南:https://medium.com/@phirschybar/resize-your-vagrant-virtualbox-disk-3c0fbc607817 - phirschybar

我已经在我的Vagrantfile中自动添加了磁盘。
Vagrant.configure("2") do |config|
    ...
    file_to_disk = File.realpath( "." ).to_s + "/disk.vdi"

    if ARGV[0] == "up" && ! File.exist?(file_to_disk) 
       puts "Creating 5GB disk #{file_to_disk}."
       vb.customize [
            'createhd', 
            '--filename', file_to_disk, 
            '--format', 'VDI', 
            '--size', 5000 * 1024 # 5 GB
            ] 
       vb.customize [
            'storageattach', :id, 
            '--storagectl', 'SATA Controller', 
            '--port', 1, '--device', 0, 
            '--type', 'hdd', '--medium', 
            file_to_disk
            ]
   ...
   config.vm.provision "shell", path: "scripts/add_new_disk.sh"
   ...
end

在这里,add_new_disk.sh shell脚本的样子是这样的:

set -e
set -x

if [ -f /etc/disk_added_date ]
then
   echo "disk already added so exiting."
   exit 0
fi


sudo fdisk -u /dev/sdb <<EOF
n
p
1


t
8e
w
EOF

pvcreate /dev/sdb1
vgextend VolGroup /dev/sdb1
lvextend /dev/VolGroup/lv_root
resize2fs /dev/VolGroup/lv_root

date > /etc/disk_added_date

此脚本适用于 CentOS 6.4,但可以轻松适应Ubuntu。
除了添加磁盘外,其他选择包括:
  • 使用具有更大磁盘的盒子,例如 opscode bento,其具有40GB的磁盘
  • 使用 packer 构建自己的盒子。您可以使用opscode boxes packer定义作为起点

嗨,我想尝试一下你们的解决方案。请确认在Vagrant文件的哪个部分添加了这段代码?谢谢! - Rudi Strydom
@RudiStrydom 我已经更新了答案 - 希望现在更有意义了。 - Chris Snow
我已经弄明白了,谢谢你的回复。我相信这会帮助其他人找到答案。 - Rudi Strydom
当我尝试这个时,我遇到了以下错误:"主对象的未定义局部变量或方法'vb'"。 - B T
2这应该在config.vm.provider :virtualbox do |vb|块中添加,以使事情更清晰明了。 - B T
如果您没有卷组,会怎么样呢? - B T
这些东西必须在创建虚拟机之前(即在第一次运行 vagrant up 之前)添加到 VagrantFile 吗? - B T
据我所知,您可以在创建机器之后添加磁盘,它将仅将磁盘添加到现有的卷组中。如果您没有卷组,您需要将磁盘添加并自行挂载到需要额外空间的文件夹(例如/home或/opt)。 - Chris Snow
1如果使用lvextend命令时出现“请指定大小或范围”错误,请尝试使用lvextend -l +100%FREE /dev/VolGroup/lv_root命令。 - Andomar
1您的示例将创建一个5TB的磁盘(--size单位为MB,请参见https://www.virtualbox.org/manual/ch08.html#vboxmanage-createvdi)。 - backflip

安装 Vagrant 插件 vagrant-disksize
vagrant plugin install vagrant-disksize

如果你想在启动Vagrant时确保用户安装了插件,你可以在Vagrantfile的开头添加这个。

# Install vagrant-disksize to allow resizing the vagrant box disk.
unless Vagrant.has_plugin?("vagrant-disksize")
    raise  Vagrant::Errors::VagrantError.new, "vagrant-disksize plugin is missing. Please install it using 'vagrant plugin install vagrant-disksize' and rerun 'vagrant up'"
end

在 Vagrantfile 中设置所需的磁盘大小

vagrant.configure('2') do |config|
    config.disksize.size = '50GB'
end

更新现有的vagrant box

  1. 完成以上所有步骤
  2. 运行vagrant halt & vagrant up(你应该看到类似于“调整磁盘大小:旧 32768 MB,需求 51200 MB,新 51200 MB”)
  3. SSH到vagrant box
  4. 运行sudo cfdisk /dev/sda
  5. 使用箭头键选择你的磁盘,可能是sdaX。我的是sda3。
  6. 然后使用箭头键选择调整大小。接受建议的磁盘大小。
  7. 然后选择写入。并回答是。
  8. 现在你可以选择退出。
  9. 运行sudo resize2fs -p -F /dev/sdaX 你应该看到类似于:“/dev/sda3上的文件系统挂载在/;需要在线调整大小 旧描述块 = 4,新描述块 = 6 /dev/sda3上的文件系统现在已经是11933952(4k)个块长。”
  10. 运行df命令,并查看你的磁盘大小是否增加。

这在Ubuntu上行不通,在第8步之后执行以下操作。``` 详细信息请参考https://packetpushers.net/ubuntu-extend-your-default-lvm-space/。 - undefined


这个操作调整了我的磁盘大小,并且只需要一行配置就扩展了分区。非常流畅! - user1026263

Vagrant最近在VirtualBox提供程序中添加了对自定义磁盘大小(包括磁盘调整大小)的实验性支持。一些常见的使用场景已经在这里这里有所记录。
要激活此功能,请修改您的Vagrantfile(参见下面的示例),在shell中设置VAGRANT_EXPERIMENTAL="disks"环境变量,然后运行vagrant up
以下是一个在Vagrant 2.2.19上测试过的示例Vagrantfile,使用基于LVMbento/ubuntu-20.04基础镜像:

Vagrant.configure("2") do |config|
  ...
  config.vm.disk :disk, size: "150GB", primary: true
  config.vm.box = "bento/ubuntu-20.04"
  config.vm.box_version = "202005.21.0"
  config.vm.box_check_update = false
  ...
end

您应该在 vagrant up 过程中看到类似以下输出(或更多):
==> vagrant: You have requested to enabled the experimental flag with the following features:
==> vagrant:
==> vagrant: Features:  disks
==> vagrant:
==> vagrant: Please use with caution, as some of the features may not be fully
==> vagrant: functional yet.
Bringing machine 'server' up with 'virtualbox' provider...
==> server: Clearing any previously set forwarded ports...
==> server: Clearing any previously set network interfaces...
==> server: Preparing network interfaces based on configuration...
    server: Adapter 1: nat
==> server: Forwarding ports...
    server: 22 (guest) => 49222 (host) (adapter 1)
    server: 4200 (guest) => 49280 (host) (adapter 1)
    server: 4243 (guest) => 49243 (host) (adapter 1)
==> server: Configuring storage mediums...
    server: Disk 'vagrant_primary' needs to be resized. Resizing disk...

这个过程可能需要一段时间才能完成(在我的情况下,需要1到2小时)。

使用vagrant ssh进入您的虚拟机,然后使用以下命令(基于this answer)收集有关您的文件系统的信息,然后扩展LVM卷。如果您的基础框不使用LVM,则不应使用这些命令。

# Understand your partitions.
> lsblk
> df -lhT /
> sudo fdisk -l /dev/sda
> sudo vgdisplay
> sudo parted /dev/sda print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 161GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 
Number  Start   End     Size    Type      File system  Flags
1      1049kB  538MB   537MB   primary   fat32        boot
2      539MB   68.7GB  68.2GB  extended
5      539MB   68.7GB  68.2GB  logical                lvm

# Resize your partitions.
> sudo parted /dev/sda resizepart 2 100%
> sudo parted /dev/sda resizepart 5 100%
> sudo parted /dev/sda print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 161GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 
Number  Start   End    Size   Type      File system  Flags
1      1049kB  538MB  537MB  primary   fat32        boot
2      539MB   161GB  161GB  extended
5      539MB   161GB  161GB  logical                lvm

# Resize your LVM physical volume to match the new partition extents.
> sudo pvresize /dev/sda5
> sudo vgdisplay
Alloc PE / Size       16255 / <63.50 GiB
Free  PE / Size       22016 / 86.00 GiB

# Resize your LVM logical volume to fill the available Free space.
> sudo lvdisplay
--- Logical volume ---
LV Path                /dev/vgvagrant/root
> sudo lvextend -l+100%FREE /dev/vgvagrant/root
Size of logical volume vgvagrant/root changed from <62.54 GiB (16010 extents) to <148.54 GiB (38026 extents).
Logical volume vgvagrant/root successfully resized.

# Apply the changes to the filesystem.
> sudo resize2fs /dev/vgvagrant/root
> df -lhT /
Filesystem                 Type  Size  Used Avail Use% Mounted on
/dev/mapper/vgvagrant-root ext4  146G   55G   85G  40% /

增加VM centos 7的磁盘大小

  1. 在主机上安装插件:

    vagrant plugin install vagrant-disksize

  2. 编辑vagrant文件以设置磁盘大小:

    vagrant.configure('2') do |config| 
        config.vm.box = 'centos/7' 
        config.disksize.size = '50GB'
    end

3:启动虚拟机 4:安装growpart并将磁盘大小扩展到最大

yum install epel-release -y yum install cloud-utils-growpart.x86_64 -y growpart /dev/sda 1

5:下载gparted live iso镜像并将其作为光驱附加到虚拟机,使用Virtualbox GUI引导到gpartedlive 重新启动使用gparted live

6:使用gparted检查分区以清除错误标志


免责声明:答案可能仅适用于使用逻辑卷管理的发行版,例如适用于以下用例的RHEL:
我一直在使用由Red Hat官方提供的Vagrant Box的Red Hat Enterprise 7.2。
(您需要一个可以免费创建的RHEL开发人员帐户)
安装后,我困扰于只有8GB可用的事实。
sudo df -h
[vagrant@rhel-cdk ~]$ sudo df -h
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-root   8G  2,5G   6,5G  28% /
devtmpfs                     234M     0  234M   0% /dev
tmpfs                        245M     0  245M   0% /dev/shm
tmpfs                        245M  4,3M  241M   2% /run
tmpfs                        245M     0  245M   0% /sys/fs/cgroup
/dev/sda2                    297M  134M  164M  45% /boot
tmpfs                         49M     0   49M   0% /run/user/1000

如你所见,大部分空间已经被RHEL安装消耗掉了。
然而,我发现与/dev/mapper/VolGroup00-root文件系统对应的卷组确实有额外的空间(我想,在虚拟机中是动态分配的)。
sudo vgdisplay VolGroup00
  --- Volume group ---
  VG Name               VolGroup00
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  11
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               1
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               39,70 GiB
  PE Size               4,00 MiB
  Total PE              10164
  Alloc PE / Size       7872 / 30,75 GiB
  Free  PE / Size       2292 / 8,95 GiB
  VG UUID               JBVwpl-13KX-HbQw-FqUa-CA9w-swpF-dF6glm

所剩下的事情只有:

a)将我们的逻辑卷大小增加10G左右

sudo lvextend -L+10G /dev/VolGroup00/root

b)更新您的根文件系统,以便它意识到这个变化

sudo xfs_growfs /dev/mapper/VolGroup00-root

(请注意,至少对于rhel 7.2,resize2fs不能用于此目的)。

之后,我的文件系统就有了额外的空间:

sudo df -h
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-root   18G  2,5G   16G  14% /
devtmpfs                     234M     0  234M   0% /dev
tmpfs                        245M     0  245M   0% /dev/shm
tmpfs                        245M  4,3M  241M   2% /run
tmpfs                        245M     0  245M   0% /sys/fs/cgroup
/dev/sda2                    297M  134M  164M  45% /boot
tmpfs                         49M     0   49M   0% /run/user/1000

... 在虚拟机层面没有干预


以下的Vagrantfile(放置在我的食谱文件夹的根目录下)与Chef的test-kitchen一起对我有效:
###########################################################################################################
# The in-line script that will be used to grow our disk partition to the size specified in our Vagrantfile.
###########################################################################################################
$script = <<-SCRIPT
#!/bin/bash
ROOT_DISK_DEVICE="/dev/sda"
ROOT_DISK_DEVICE_PART="/dev/sda5"
LV_PATH=`sudo lvdisplay -c | sed -n 1p | awk -F ":" '{print $1;}'`
FS_PATH=`df / | sed -n 2p | awk '{print $1;}'`
ROOT_FS_SIZE=`df -h / | sed -n 2p | awk '{print $2;}'`
echo "The root file system (/) has a size of $ROOT_FS_SIZE"
echo "> Increasing disk size of $ROOT_DISK_DEVICE to available maximum"
sudo parted /dev/sda resizepart 2 100%
sudo parted /dev/sda resizepart 5 100%
sudo pvresize $ROOT_DISK_DEVICE_PART
sudo lvextend -l +100%FREE $LV_PATH
sudo resize2fs -p $FS_PATH
ROOT_FS_SIZE=`df -h / | sed -n 2p | awk '{print $2;}'`
echo "The root file system (/) has a size of $ROOT_FS_SIZE"
exit 0
SCRIPT

# Fail if the vagrant-disksize plugin is not installed
unless Vagrant.has_plugin?("vagrant-disksize")
  raise 'vagrant-disksize is not installed!'
end

Vagrant.configure("2") do |config|
  config.disksize.size = "150GB"
  config.vm.provision "shell", inline: $script
end

在我的 kitchen.yml 中添加以下小片段:
  vagrantfiles:
    - Vagrantfile
  provision: True

放在下面的位置:
driver:
  name: vagrant

将脚本值替换为您想要的任何内容...此脚本用于扩展Ubuntu 20.04虚拟机映像的文件系统。