【话在前头】

这么些年微软 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. QObject::startTimer: timers cannot be started from another thread 一则输出调试:关于QT的线程关联性

    开始 今天在调试输出里看见QObject::startTimer: timers cannot be started from another thread QTimer类 从Qt的帮助文档里可以得到 ...

  2. Vue3全家桶升级指南二ref、toRef、toRefs的区别

    ref是对原始数据的拷贝,当修改ref数据时,模板中的视图会发生改变,但是原始数据并不会改变. toRef是对原始数据的引用,修改toRef数据时,原始数据也会发生改变,但是视图并不会更新. 在vue ...

  3. 13、win10系统远程桌面oracle修正问题

    1.A电脑(Windows 10)远程连接B电脑(Widows Server 2016), 出现错误: 出现身份验证错误.要求的函数不受支持 远程计算机:xx.xx.xx.xx 这可能是由于CredS ...

  4. Docker:redis容器使用redis.conf启动失败,不报错

    查看redis.conf配置信息 daemonize no :redis默认是不作为守护进程使用的,这也就是说为什么在你不修改配置文件时直接使用redis-server /redis/redis.co ...

  5. SpringBoot:WebSocket使用Service层的方法

    方法一: 创建工具类 ApplicationContextRegister.java import org.springframework.beans.BeansException; import o ...

  6. ESP32构建系统 (传统 GNU Make)

    概述: 一个 ESP-IDF 项目可以看作是多个不同组件的集合,ESP-IDF 可以显式地指定和配置每个组件.在构建项目的时候,构建系统会前往 ESP-IDF 目录.项目目录和用户自定义目录(可选)中 ...

  7. ESP32低功耗模式

    1.ESP32 系列芯片提供三种可配置的睡眠模式,针对这些睡眠模式,我们提供了了多种低功耗解决方案,用户可以结合具体需求选择睡眠模式并进行配置.三种睡眠模式如下: Modem-sleep 模式:CPU ...

  8. 华为交换机5855设置ssh

    配置思路 配置交换机密钥对 #生成RSA密钥对 设置vty登陆用户界面的认证方式为AAA认证 #设置远程认证方式 设置aaa用户信息 #本地用户名和密码 #本地用户服务类型 #本地用户授权等级 设置s ...

  9. CF1539A Contest Start[题解]

    Contest Start 题目大意 有 \(n\) 个人报名参加一个比赛,从 \(0\) 时刻开始每隔 \(x\) 分钟有一个人开始比赛,每个人参赛时间相同,均为 \(t\) .定义一个选手的不满意 ...

  10. (精)题解 guP4878 [USACO05DEC] 布局

    差分约束模版题 不过后三个点简直是满满的恶意qwq 这里不说做题思路(毕竟纯模板),只说几个坑点: 1. 相邻的两头牛间必须建边(这点好像luogu没有体现),例如一组数据: 4 1 1 1 4 10 ...