【话在前头】

这么些年微软 Azure 创建虚拟机一直不能修改系统盘大小,但很多时候实际又用不了这么大的操作系统磁盘。微软自己甚至还针对 Windows 服务器镜像推出一个 smalldisk 的镜像版本(https://azure.microsoft.com/en-us/blog/new-smaller-windows-server-iaas-image/),在原有 127GB 的镜像外提供一个 32GB 版本的操作系统镜像,可以根据自己的需要进行扩容。但是 Azure 提供的 Linux 服务器镜像却都是 30GB 的版本,网上其他人的解决办法通常是下载磁盘 vhd 文件,然后本地打开后用 Hyper-V 进行缩小后再上传,或者直接用 Azure 的存储账户进行在线编辑 vhd 文件(见相关链接1、2)。本文通过创建小容量磁盘,直接复制磁盘分区的方式来解决这个问题。

【文章索引】

  1. 缩减操作系统分区容量
  2. 复制分区到小容量磁盘
  3. 修改小容量磁盘配置
  4. 相关链接

【一、缩减操作系统分区容量】

Azure 支持修改托管磁盘的容量,但是只支持扩大,不支持缩小,如果调整磁盘大小时设置了比之前更小的容量,则会提示下图所示的内容。

首先,与其他方案相同,需要先准备一份已缩减分区容量的系统盘。Linux 不像 Windows 提供了磁盘管理工具,可以在线缩减系统盘容量,需要创建一个当前操作系统磁盘的副本并挂载到系统上进行调整。这里先对当前系统盘创建一份快照,如下图。

然后对这个快照创建磁盘,如下图。

完成后就可以将创建好的系统盘副本附加到虚拟机中,同时再附加一个小容量的空磁盘用于创建最终的小容量系统盘。

由于复制后的磁盘分区的Uuid与之前的磁盘分区完全一样,所以如果在虚拟机启动前附加的磁盘,虚拟机启动后根目录(/)挂载点会被后附加的这块磁盘挂载,所以如果要缩减分区需要对第一块磁盘(/dev/sda)进行操作;反之如果是虚拟机启动后附加的磁盘,根目录挂载点还是第一块磁盘(/dev/sda1),如果要缩减分区需要对后挂载的磁盘(/dev/sdc 或 /dev/sdd)进行操作。

这里以启动后附加磁盘为例,小容量空磁盘是 /dev/sdc,操作系统副本磁盘是 /dev/sdd。首先需要缩减文件系统容量,分别执行“e2fsck”和“resize2fs”,其中“resize2fs”设置的大小不能大于后续分区的大小,如果不确认后续使用的各个工具的单位,这里也可以故意设置小一些,如下

root@xxx-vm:/tmp# e2fsck -f /dev/sdd1
e2fsck 1.44.5 (15-Dec-2018)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdd1: 26148/1957888 files (0.2% non-contiguous), 365215/7831547 blocks
root@xxx-vm:/tmp# resize2fs /dev/sdd1 3G
resize2fs 1.44.5 (15-Dec-2018)
Resizing the filesystem on /dev/sdd1 to 786432 (4k) blocks.
The filesystem on /dev/sdd1 is now 786432 (4k) blocks long.

然后可以使用 parted 或 fdisk 进行分区的调整,个人觉得 parted 更简单一些,一条命令即可修改,不像 fdisk 需要还需要先删除再创建,如下

root@xxx-vm:/tmp# parted /dev/sdd
GNU Parted 3.2
Using /dev/sdd
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Warning: Not all of the space available to /dev/sdd appears to be used, you can fix the GPT to use all of the space (an extra 4194304 blocks) or continue with the current setting?
Fix/Ignore? Ignore
Model: Msft Virtual Disk (scsi)
Disk /dev/sdd: 34.4GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags: Number Start End Size File system Name Flags
14 1049kB 4194kB 3146kB bios_grub
15 4194kB 134MB 130MB fat16 boot, esp
1 134MB 32.2GB 32.1GB ext4 (parted) resizepart 1 4G
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? Yes
(parted)
Information: You may need to update /etc/fstab.

完成后可以用 mount 挂载一下分区进行验证,看看是否能进行正常挂载以及文件系统容量是否符合预期。

【二、复制分区到小容量磁盘】

在第一步确认没问题后可以将上述磁盘内的内容复制到小容量磁盘中,这里使用 fdisk 把调小分区容量的磁盘分区表备份下来,如下

root@xxx-vm:/tmp# fdisk /dev/sdd

Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command. The backup GPT table is not on the end of the device. This problem will be corrected by write. Command (m for help): O Enter script file name: os-disk-pt Script successfully saved. Command (m for help): q

然后修改分区表备份文件 os-disk-pt 文件中 last-lba 的值为小容量磁盘的最后一个扇区,然后用 fdisk 对小容量磁盘导入该分区表即可,如下

root@xxx-vm:/tmp# fdisk /dev/sdc

Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command. Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x99a32e79. Command (m for help): I Enter script file name: os-disk-pt Created a new GPT disklabel (GUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX).
Created a new partition 1 of type 'Linux filesystem' and of size 3.6 GiB.
Created a new partition 14 of type 'BIOS boot' and of size 3 MiB.
Created a new partition 15 of type 'EFI System' and of size 124 MiB.
Script successfully applied. Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

完成后分别对所有分区使用 dd 命令复制即可,如下

root@xxx-vm:/tmp# dd if=/dev/sdd1 of=/dev/sdc1 bs=1M
3686+1 records in
3686+1 records out
3865782784 bytes (3.9 GB, 3.6 GiB) copied, 179.995 s, 21.5 MB/s
root@xxx-vm:/tmp# dd if=/dev/sdd14 of=/dev/sdc14 bs=1M
3+0 records in
3+0 records out
3145728 bytes (3.1 MB, 3.0 MiB) copied, 0.147453 s, 21.3 MB/s
root@xxx-vm:/tmp# dd if=/dev/sdd15 of=/dev/sdc15 bs=1M
124+0 records in
124+0 records out
130023424 bytes (130 MB, 124 MiB) copied, 5.775 s, 22.5 MB/s

完成后也可以用 mount 挂载一下新的分区进行验证,没问题后即可关闭该虚拟机。

【三、修改小容量磁盘配置】

通过界面创建的磁盘是不带有操作系统类型的,也没法让虚拟机将该磁盘作为系统盘进行启动,这里需要使用 Azure 的命令行,例如使用 Azure Powershell,可以参考相关链接3进行安装。

然后打开 Powershell,输入 “Connect-AzAccount”,即可弹出登录 Azure 的对话框,并进行确认,完成后会显示账户的所有订阅,如下图

然后输入下列命令设置以下几个环境变量

$DiskID = "磁盘资源ID"
$VMName = "虚拟机名称"
$AzSubscription = "订阅名"

其中“磁盘资源ID”需要进入磁盘页面,并在“属性”页面中找到“资源ID”即为该内容,类似 “/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxxxxxx/providers/Microsoft.Compute/disks/xxxxxxxx”,如下图

然后再执行下列命令即可

# 指定订阅
Select-AzSubscription -Subscription $AzSubscription # 获取虚拟机信息
$VM = Get-AzVm | ? Name -eq $VMName # 获取磁盘信息
$Disk = Get-AzDisk | ? Id -eq $DiskID # 修改磁盘操作系统类型
$Disk.OsType = "Linux" # 修改磁盘 Hyper-V 代数(宿主机为V2时需要手动设置)
$Disk.HyperVGeneration = "V2" # 更新磁盘设置
Update-AzDisk -ResourceGroupName $VM.ResourceGroupName -DiskName $Disk.Name -Disk $Disk

完成后即可在虚拟机页面中,选择“磁盘” -> “交换 OS 磁盘”,刚刚创建的小容量磁盘即会出现在这个页面中,确定后启动虚拟机即可。

【四、相关链接】

  1. How to shrink a managed disk:https://devblogs.microsoft.com/premier-developer/how-to-shrink-a-managed-disk/
  2. Shrink an Azure VMs OS Managed Disk using PowerShell:https://jrudlin.github.io/2019-08-27-shrink-azure-vm-osdisk/
  3. Install the Azure Az PowerShell module:https://docs.microsoft.com/en-us/powershell/azure/install-az-ps

缩减Azure上Linux虚拟机系统盘容量的更多相关文章

  1. Azure上Linux虚拟机Mac地址的持久化

    有些用户在使用Azure Linux 虚拟机安装软件时,有些软件的license会和当前系统的mac地址绑定,那么在Azure VM重启,reszie(改变尺寸大小),停止然后再启动的时候,虚拟机的M ...

  2. Azure 上 Linux 虚拟机 Mac 地址的持久化

    有些用户在使用 Azure Linux 虚拟机安装软件时,有些软件的 license 会和当前系统的 mac 地址绑定,那么在 Azure VM 重启,reszie(改变尺寸大小),停止然后再启动的时 ...

  3. 阿里云至 Windows Azure 的 Linux 虚拟机迁移

    在Windows Azure中,用户可以对部署在Azure中的虚拟机的映像.磁盘以及快照进行生成和下载.用户可以方便地将Azure中的虚拟机实例迁移到本地.私有云甚至其他公有云平台进行测试.扩展或者再 ...

  4. Windows Azure 上 Linux VM 中的交换空间 – 第 2 部分

    本文章由 Azure CAT 团队的 Piyush Ranjan (MSFT) 撰写. 在前一篇文章 Windows Azure 上Linux VM 中的交换空间第 1 部分中,我介绍了在默认情况下, ...

  5. Azure 中 Linux 虚拟机的大小

    本文介绍可用于运行 Linux 应用和工作负荷的 Azure 虚拟机的可用大小与选项. 此外,还提供在计划使用这些资源时要考虑的部署注意事项. 本文也适用于 Windows 虚拟机. 类型 大小 说明 ...

  6. Azure上Linux VM防DDOS攻击:使用Apache mod_evasive

    部署在云端的虚拟机和web服务,很容易受到DoS护着DDoS的服务攻击,让一些新上线的业务苦不堪言,当然各个云服务提供商也有不同层面DDOS的防护,然而由于防护粒度,攻击复杂度的关系,未必可以满足你的 ...

  7. Azure上Linux VM误配防火墙的恢复方法

    在实际运维中,防火墙把自己挡在机器外面的情况会时有发生.如何快速的恢复对运维人员是很重要的. 本文将介绍如何用Azure Extension实现不通过ssh对VM进行操作的方法. 之前写过一遍Blog ...

  8. VMware上Linux虚拟机和Windows共享文件夹

    参考文章:https://blog.csdn.net/qq_19004627/article/details/78689641 操作环境:主机:Windows10,VMware Workstation ...

  9. Xshell、winscp连不上Linux虚拟机

    1.环境 本地机器WIN7环境,使用VMware Workstation Pro安装的CentOS7,系统镜像CentOS-6.1-x86_64-netinstall.iso 2.问题与分析 我的虚拟 ...

随机推荐

  1. 基于ABP落地领域驱动设计-05.实体创建和更新最佳实践

    目录 系列文章 数据传输对象 输入DTO最佳实践 不要在输入DTO中定义不使用的属性 不要重用输入DTO 输入DTO中验证逻辑 输出DTO最佳实践 对象映射 学习帮助 系列文章 基于ABP落地领域驱动 ...

  2. [HTML]图像标签<img>的用法、属性及路径问题

    图像标签:<img>        用法:<img src = "图像地址"> 图像标签的属性 属性 说明 src 指明图像的地址(分为相对路径和绝对路径两 ...

  3. string转char*/char[]

    转char* 主要有三种方法可以将str转换为char*类型,分别是:data(); c_str(); copy(); 1.data() data()仅返回字符串内容,而不含有结束符'\0' std: ...

  4. 通过修改Host实现chrome同步

    问题原因 : 中国的GW屏蔽了google服务,导致无法同步账号信息,这是一个很好的功能.可以同步书签,插件等! 跟chrome的版本号无关,设置hosts文件就能够正常运行(文件位置 : C:\Wi ...

  5. Cobra框架使用手册

    cobra框架使用手册 cobra是go语言的一个库,可以用于编写命令行工具. 概念 Cobra 结构由三部分组成:命令 (commands).参数 (arguments).标志 (flags).最好 ...

  6. 精尽Spring Boot源码分析 - 配置加载

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  7. ubuntu docker开启2375端口,支持远程访问

    1.编辑docker文件:/usr/lib/systemd/system/docker.service vi /usr/lib/systemd/system/docker.service 2.Exec ...

  8. C++ 标准模板库(STL)——算法(Algorithms)的用法及理解

    C++ STL中的算法(Algorithms)作用于容器.它们提供了执行各种操作的方式,包括对容器内容执行初始化.排序.搜索和转换等操作.按照对容器内容的操作可将STL 中的算法大致分为四类: (1) ...

  9. 深度学习之逻辑回归的实现 -- sigmoid

    1 什么是逻辑回归 1.1逻辑回归与线性回归的区别: 线性回归预测的是一个连续的值,不论是单变量还是多变量(比如多层感知器),他都返回的是一个连续的值,放在图中就是条连续的曲线,他常用来表示的数学方法 ...

  10. git的一些常用基础命令

    一些常用的git命令操作简单总结 记录常用的git命令,附带命令的简单使用说明 git区域分布 remote远程仓库 repository本地仓库 index暂存区 workspace工作区 stas ...