扩大 EC2 实例很容易(例如,创建一个 AMI,从中启动一个实例,然后更改存储大小)。
但减少它变得更加困难。我想减少 Amazon Web Services (AWS) EC2 实例 Elastic Block Store (EBS) 根卷的大小。网上有几个旧的高级程序。我找到的更详细的版本是一年前在 StackOverflow 问题上找到的答案:如何减少我的 ebs 卷容量,步骤的水平相当高:
创建所需大小的新 EBS 卷(例如 /dev/xvdg)
启动一个实例,并将两个 EBS 卷附加到该实例
检查文件系统(原始根卷):(例如)e2fsck -f /dev/xvda1
最大限度地缩小原始根卷:(例如 ext2/3/4)resize2fs -M -p /dev/xvda1
使用 dd 复制数据:
选择块大小(我喜欢 16MB)
计算块的数量(使用 resize2fs 输出中的块数):blocks*4/(chunk_size_in_mb*1024) - 为了安全起见,稍微向上舍入一点
复制数据:(例如)dd if=/dev/xvda1 ibs=16M of=/dev/xvdg obs=16M count=80
调整新的(较小的)EBS 卷上的文件系统大小:(例如)resize2fs -p /dev/xvdg
检查文件系统(原始根卷):(例如)e2fsck -f /dev/xvdg
分离新的 EBS 根卷,并将其附加到原始实例
我无法找到详细的逐步“如何”解决方案。
我的 EBS 根卷已附加到 HVM Ubuntu 实例。
任何帮助将非常感激。
答案1
如果该卷用作根(可启动)设备,则其他解决方案均不起作用。
新创建的磁盘缺少启动分区,因此需要安装 GRUB 并正确设置一些标志,实例才能将其用作根卷。
我的(截至今天,在职的)缩小根卷的解决方案是:
背景:我们有一个实例 A,我们想缩小它的根卷。我们称这个卷为 VA。我们想将 VA 从 30GB 缩小到 10GB
- 创建一个新的 ec2 实例 B,其操作系统与实例 A 相同。此外,内核必须匹配,以便根据需要升级或降级。对于存储,选择与 VA 类型相同但大小为 10GB 的卷。(或任何您的目标大小)。所以现在我们有一个实例 B,它使用这个新卷(我们称之为 VB)作为根卷。
- 一旦新实例 (B) 开始运行,请停止它并分离其根卷 (VB)。
注意:以下步骤主要取自@bill 的解决方案:
停止您想要调整大小的实例 (A)。
创建卷 VA 的快照,然后从该快照创建“通用 SSD”卷。我们将此卷称为 VASNAP。
使用 amazon Linux 创建一个新实例,我们将此实例称为 C。我们将仅使用此实例将 VASNAP 的内容复制到 VB。我们可能也可以使用实例 A 来执行这些步骤,但我更喜欢在独立的机器上执行此操作。
将以下卷附加到实例 C。/dev/xvdf 用于 VB。/dev/xvdg 用于 VASNAP。
重新启动实例 C。
通过 SSH 登录实例 C。
创建以下新目录:
mkdir /source /target
- 使用 ext4 文件系统格式化 VB 的主分区:
mkfs.ext4 /dev/xvdf1
如果没有错误,请继续执行步骤 11。否则,如果您没有/dev/xvdf1
,则需要通过执行以下操作 i-vii 来创建分区:
i) 如果/dev/xvdf1
由于某种原因不存在,则需要创建它。首先输入:
sudo fdisk /dev/xvdf
。
ii)输入以下命令擦除磁盘:
wipefs
iii)输入以下命令创建一个新的分区:
n
iv)输入p
创建主分区
v)继续按回车键继续使用默认设置。
vi)当它再次要求输入命令时,输入w
以写入更改并退出。
vii)通过执行以下操作来验证您是否有/dev/xvdf1
分区:
lsblk
你应该看到类似这样的内容:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 250G 0 disk
└─xvda1 202:1 0 250G 0 part
xvdf 202:80 0 80G 0 disk
└─xvdf1 202:81 0 80G 0 part
xvdg 202:96 0 250G 0 disk
└─xvdg1 202:97 0 250G 0 part
现在继续执行步骤 11。
- 将其挂载到此目录:
mount -t ext4 /dev/xvdf1 /target
- 这非常重要,文件系统需要一个 e2label 以便 Linux 识别并启动它,在活动实例上使用“e2label /dev/xvda1”查看它应该是什么,在本例中标签为:“/”
e2label /dev/xvdf1 /
- 将 VASNAP 挂载到 /source:
mount -t ext4 /dev/xvdg1 /source
- 复制内容:
rsync -vaxSHAX /source/ /target
注意:“/target”后面没有“/”。此外,可能存在一些有关符号链接和属性的错误,但调整大小仍然成功
- 卸载 VB:
umount /target
返回 AWS 控制台:从实例 C 分离 VB,并从 A 分离 VA。
将新大小的卷(VB)附加到实例作为:“/dev/xvda”
启动实例A,现在它的根设备是10GB:)
删除实例 B 和 C,以及除 VB 之外的所有卷,VB 现在是实例 A 的根卷。
答案2
在 AWS 控制台中:
停止要调整大小的实例
创建活动卷的快照,然后从该快照创建“通用 SSD”卷。
创建另一个您想要大小的“通用 SSD”卷。
将这 3 个卷附加到实例,如下所示:
- /dev/sda1 为活动卷。
- /dev/xvdf 为目标大小的卷。
- /dev/xvdg 为由活动卷的快照制作的卷。
启动实例。
通过 SSH 登录到新实例。
创建这些新目录:
mkdir /source /target
- 在新卷上创建一个 ext4 文件系统:
mkfs.ext4 /dev/xvdf
- 将其挂载到此目录:
mount -t ext4 /dev/xvdf /target
- 这非常重要,文件系统需要一个 e2label 以便 Linux 识别并启动它,在活动实例上使用“e2label /dev/xvda1”查看它应该是什么,在本例中标签为:“/”
e2label /dev/xvdf /
- 挂载从快照创建的卷:
mount -t ext4 /dev/xvdg /source
- 复制内容:
rsync -ax /source/ /target
注意:“/target”后面没有“/”。此外,可能存在一些有关符号链接和属性的错误,但调整大小仍然成功
- 卸载文件系统:
umount /target
umount /source
返回 AWS 控制台:停止实例并分离所有卷。
将新大小的卷附加到实例:“/dev/sda1”
启动实例,它应该启动。
第 10 步很重要:如上所述,用“e2label”标记新卷,否则实例将出现在 aws 中启动但不会通过连接检查。
答案3
1. 创建一个新的 ebs 卷并将其附加到实例。
创建一个新的 EBS 卷。例如,如果您原来有 20G,并且想要将其缩小到 8G,则创建一个新的 8G EBS 卷,确保位于同一可用区。将其附加到您需要缩小根分区的实例。
2. 对新创建的 ebs 卷进行分区、格式化和同步文件。
(1.检查分区情况我们首先使用该命令sudo parted -l
来检查原始卷的分区信息:
[root@ip-172-31-16-92 conf.d]# sudo parted -l
Model: NVMe Device (nvme)
Disk /dev/nvme0n1: 20G
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 2097kB 1049kB bbp bios_grub
2 2097kB 20480MB 24G xfs root
可以看到这个20G的根设备卷被分割成了两个分区,一个叫bbp,一个叫root。bbp分区里没有任何文件系统,但是有一个标志位叫bios_grub,说明这个系统是由grub引导的,并且说明这个根卷是使用gpt分区的。至于bios_grub是什么,其实就是BIOS的启动分区,参考如下:
https://en.wikipedia.org/wiki/BIOS_boot_partition https://www.cnblogs.com/f-ck-need-u/p/7084627.html
这个大概有 1MB,其中有一个叫 root 的分区是我们需要重点关注的。这个分区存储了原系统的所有文件。所以,备份的思路就是把这个分区里的文件转移到新 ebs 卷上另一个较小的分区里。
(2 使用parted
对新的 ebs 卷进行分区和格式化。
用于lsblk
列出块:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1 259:0 0 20G 0 disk
├─nvme0n1p1 259:1 0 1M 0 part
└─nvme0n1p2 259:2 0 20G 0 part /
nvme1n1 270:0 0 8G 0 disk
新的ebs卷是设备nvme1n1,我们需要对其进行分区。
~# parted /dev/nvme1n1
GNU Parted 3.2
Using /dev/xvdg
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel gpt #Using the gpt layout would take up the first 1024 sectors
(parted) mkpart bbp 1MB 2MB # Since the first 1024 sectors are used, the start address here is 1024kb or 1MB, and bbp is the partition name, that is, BIOS boot partition, which needs to take up 1MB, so the end address is 2MB
(parted) set 1 bios_grub on #Set partition 1 as BIOS boot partition
(parted) mkpart root xfs 2MB 100% #allocate the remaining space (2MB to 100%) to the root partition.
分区之后lsblk
再次使用,我们可以看到
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1 259:0 0 20G 0 disk
├─nvme0n1p1 259:1 0 1M 0 part
└─nvme0n1p2 259:2 0 20G 0 part /
nvme1n1 270:0 0 8G 0 disk
├─nvme1n1p1 270:1 0 1M 0 part
└─nvme1n1p2 270:2 0 8G 0 part /
可以看到多出了两个分区,分别为nvme1n1p1和nvme1n1p2,其中nvme1n1p2就是我们新的根分区,使用以下命令格式化该分区:
mkfs.xfs /dev/nvme1n1p2
格式化之后,我们需要挂载该分区,例如我们将其挂载到/mnt/myroot。
mkdir -p /mnt/myroot
mount /dev/nvme1n1p2 /mnt/myroot
(3)使用rsync将所有内容传输到新卷相应的根分区。
sudo rsync -axv / /mnt/myroot/
注意上面的-x
参数很重要,因为是备份当前实例的根目录,所以如果不加这个参数,会把/mnt/myroot本身备份到/mnt/myroot,陷入死循环。(–exclude参数也可以)rsync命令和cp命令不一样,cp会覆盖,而rsync是同步增量备份,这样会省很多时间,喝杯咖啡,等同步完成就行了。
3.替换相应文件中的uuid。
因为卷发生了变化,所以卷的uuid也发生了变化。我们需要在启动文件中替换uuid。需要修改以下两个文件:
/boot/grub2/grub.cfg #or /boot/grub/grub.cfg
/etc/fstab
那么需要更改什么呢?首先,您需要通过 blkid 列出相关卷的 uuid:
[root@ip-172-31-16-92 boot]# sudo blkid
/dev/nvme0n1p2: LABEL="/" UUID="add39d87-732e-4e76-9ad7-40a00dbb04e5" TYPE="xfs" PARTLABEL="Linux" PARTUUID="47de1259-f7c2-470b-b49b-5e054f378a95"
/dev/nvme1n1p2: UUID="566a022f-4cda-4a8a-8319-29344c538da9" TYPE="xfs" PARTLABEL="root" PARTUUID="581a7135-b164-4e9a-8ac4-a8a17db65bef"
/dev/nvme0n1: PTUUID="33e98a7e-ccdf-4af7-8a35-da18e704cdd4" PTTYPE="gpt"
/dev/nvme0n1p1: PARTLABEL="BIOS Boot Partition" PARTUUID="430fb5f4-e6d9-4c53-b89f-117c8989b982"
/dev/nvme1n1: PTUUID="0dc70bf8-b8a8-405c-93e1-71c3b8a887c7" PTTYPE="gpt"
/dev/nvme1n1p1: PARTLABEL="bbp" PARTUUID="82075e65-ae7c-4a90-90a1-ea1a82a52f93"
可以看到旧的大EBS卷的根分区的uuid是add39d87-732e-4e76-9ad7-40a00dbb04e5
,新的小EBS卷的uuid是566a022f-4cda-4a8a-8319-29344c538da9
,使用sed命令进行替换:
sed 's/add39d87-732e-4e76-9ad7-40a00dbb04e5/566a022f-4cda-4a8a-8319-29344c538da9/g' /boot/grub2/grub.cfg
sed 's/add39d87-732e-4e76-9ad7-40a00dbb04e5/566a022f-4cda-4a8a-8319-29344c538da9/g' /etc/fstab
当然,您也可以尝试使用grub-install
(在某些系统中grub2-install
)手动生成 grub 文件,只是为了方便。
4.分离两个卷然后重新附加新的小卷。
然后使用umount
卸载新的 ebs 卷:
umount /mnt/myroot/
如果提示target is busy,可以使用fuser -mv /mnt/myroot
看看里面有哪些进程在运行,我发现的是bash,也就是说在bash里要退出这个目录,使用cd
回到主目录,再输入上面的命令就可以umount了。
然后分离两个卷(当然,首先停止实例),并通过在此处填写设备名称将新卷重新附加为根设备。/dev/xvda
如下所示
然后启动实例。如果ssh失败,可以使用以下方法调试:
1. 获取系统日志2.获取屏幕截图
参考:
1.https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/TroubleshootingInstances.html#InitialSteps
2.https://www.daniloaz.com/en/partitioning-and-resizing-the-ebs-root-volume-of-an-aws-ec2-instance/
3.https://medium.com/@m.yunan.helmy/decrease-the-size-of-ebs-volume-in-your-ec2-instance-ea326e951bce
答案4
下面的文章是关于如何减小 EBS 卷大小的优秀且直接的教程。它有易于遵循的分步指南和屏幕截图。