为什么 EC2 上的根文件系统在启动时会自动扩大到 EBS 的大小?

问题

- 在 Launch 一个新的 instance 的时候,默认根盘的大小是8G。如果指定更大的大小,比如20G,在启动系统时,我们可以发现根文件系统的大小会自动变成 20G,而无需手动执行 resizefs/xfs_grow 之类的操作。
- 如果后期加大根盘EBS的大小,重新启动系统时,根文件系统也会自动扩大。
- 为什么?是什么软件或者机制实现的这个效果?

Cloud-init

在云环境中的 images, 默认会开机启动一个叫 cloud-init 的服务。这个服务负责初始化系统的环境,比如 ssh 的 public key 之类的。在 cloud-init 中,有两个模块,growpart 和 resizefs。在 Amazon Linux 的镜像中,默认加载了这两个 Cloud-init 模块。从 cloud-init 的配置文件 /etc/cloud/cloud.cfg 可以看到。

cloud_init_modules:
 - migrator
 - bootcmd
 - write-files
 - write-metadata
 - growpart
 - resizefs
 - set-hostname
 - update-hostname
 - update-etc-hosts
 - rsyslog
 - users-groups
 - ssh
 - resolv-conf

growpart 会检测根盘大小是否有变,如果根盘大小变大,它会将根文件系统的分区扩大。随后,resizefs 会将根文件系统也扩大。

相关日志可以通过 /var/log/cloud-init.log 查看。比如根盘大小没有变化时,可以看到以下日志。

Nov 22 07:37:36 cloud-init[3044]: util.py[DEBUG]: Running command ['growpart', '--dry-run', '/dev/xvda', '1'] with allowed return codes [0] (shell=False, capture=True)
Nov 22 07:37:36 cloud-init[3044]: util.py[DEBUG]: resize_devices took 0.038 seconds
Nov 22 07:37:36 cloud-init[3044]: cc_growpart.py[DEBUG]: '/' NOCHANGE: no change necessary (/dev/xvda, 1)

参考文档

https://www.elastic.co/blog/autoresize-ebs-root-volume-on-aws-amis
https://cloudinit.readthedocs.io/en/latest/topics/modules.html#growpart
https://cloudinit.readthedocs.io/en/latest/topics/modules.html#resizefs