为什么 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 可以看到。
[cc lang=”text”]
cloud_init_modules:
– migrator
– bootcmd
– write-files
– write-metadata
– growpart
– resizefs
– set-hostname
– update-hostname
– update-etc-hosts
– rsyslog
– users-groups
– ssh
– resolv-conf
[/cc]

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

相关日志可以通过 /var/log/cloud-init.log 查看。比如根盘大小没有变化时,可以看到以下日志。
[cc lang=”text”]
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)
[/cc]

参考文档

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