【话在前头】

这么些年微软 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 文件(见相关链接12)。本文通过创建小容量磁盘,直接复制磁盘分区的方式来解决这个问题。

【文章索引】

  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. theUnforgiven-冲刺第一天

    每天的冲刺博客分为scrum和PM报告两部分 吴邦天 负责项目整体构思以及对任务安排,承担项目具体设计,编码: 唐嘉诚 负责项目前端页面设计,承担整个项目的后端数据库搭建以及编码 周游 项目美化以及细 ...

  2. 基于SpringBoot 、AOP与自定义注解转义字典值

    一直以来,前端展示字典一般以中文展示为主,若在表中存字典值中文,当字典表更改字典值对应的中文,会造成数据不一致,为此设置冗余字段并非最优方案,若由前端自己写死转义,不够灵活,若在业务代码转义,臃肿也不 ...

  3. 在 raspberry pi pico 上体验 MicroPython

    raspberry pi pico 官方提供 2 种开发方式,其中一种是使用 python3 开发,树莓派提供了 MicroPython 固件,把这个固件烧录进去,就可以 在 pico 上跑 pyth ...

  4. React 开发环境准备

    1. 使用reactjs,一般有以下两种方式: (1)通过script标签引入reactjs.这种方式不推荐使用,如果我们的项目比较大,就需要对项目进行拆分,于是页面就需要通过script标签引入很多 ...

  5. 通过UnityWebRequest得到的纹理转精灵

    private IEnumerator GetImage(string url, Image fileImage) { UnityWebRequest WebRequest = new UnityWe ...

  6. json串向后台传递数值自动四舍五入的问题

    业务需求:传递前台输入的数据,数量要求是小数点(多条数据) 后台服务是使用asp.net写的. 问题:反序列化JSON时总是自动四舍五入. 原因:JSON反序列化的时候数据类型是以第一条数据的类型为准 ...

  7. Docker安装MySQL8.0

    环境 CentOS 7.5 Docker 1.13.1 MySQL 8.0.16 安装 拉取镜像 默认拉取最新版本的镜像 $ docker pull mysql 如果要指定版本,使用下面的命令 $ d ...

  8. python操作elasticsearch增、删、改、查

    最近接触了个新东西--es数据库 这东西虽然被用的很多,但我是前些天刚刚接触的,发现其资料不多,学起来极其痛苦,写个文章记录下 导入库from elasticsearch import Elastic ...

  9. Django基础08篇 filter&tag

    1.Django自带的过滤器filter views.py中代码 def template_tags(request): import datetime content = '三胖content三胖c ...

  10. python使用笔记10--os,sy模块

    os操作文件,可以输入绝对路径,也可以输入相对路径 windows使用路径用\连接 Linux使用路径用/连接 但是我的电脑是windows 用/也没问题 1.os常用方法 1 import os 2 ...