In Google Cloud I often use Debian 9 Stretch for my test instances. Today I was wondering if this OS automatically resizes the root file system if I resize the VM instance disk. I also want to see if this can be done “online” and by using scripts to automate resizing remotely. This answer is Yes to these questions.
The image used is “debian-9-stretch-v20181011”.
One of the items that I appreciate about Google Cloud (and all the major cloud vendors) is their serious approach to providing excellent command line tools.
Having a great GUI console is very important, but having great command line tools is critical for repeatable development processes. It is far easier to document a command line then a lot of GUI screen captures that will be out of date next month.
Important notes:
- Before you modify the file system on your disk, create a snapshot.
- Boot disks use MBR partitions, which are limited to 2 TB in size. Do not resize boot disks beyond 2 TB.
- I recommend shutting down the system before modifying storage.
Step 1 – Create a default instance in the Google Console for testing.
The default disk size is 10 GB.
Step 2 – Connect to the instance.
Go to the Google Console -> Compute Engine. A list of VM instances is displayed. On the line with your instance, click “SSH”. You can also use the CLI: “gcloud compute ssh <instance_name>”.
Execute the “df” command and record the output.
1 |
df > df_before_resize.txt |
1 2 3 4 5 6 7 |
Filesystem 1K-blocks Used Available Use% Mounted on udev 292220 0 292220 0% /dev tmpfs 60672 3184 57488 6% /run /dev/sda1 10253588 1645864 8067156 17% / tmpfs 303352 0 303352 0% /dev/shm tmpfs 5120 0 5120 0% /run/lock tmpfs 303352 0 303352 0% /sys/fs/cgroup |
Step 3 – Shutdown the instance.
Step 4 – Resize the disk to 16 GB.
Go to the Google Console -> Compute Engine -> Disks. Select the disk for the instance. Click the edit button and resize the disk to 16 GB.
Step 5 – Start the instance and connect with SSH.
Step 6 – Execute the “df” command again.
1 2 3 4 5 6 7 |
Filesystem 1K-blocks Used Available Use% Mounted on udev 292220 0 292220 0% /dev tmpfs 60672 3176 57496 6% /run /dev/sda1 15414196 1659504 13004496 12% / tmpfs 303352 0 303352 0% /dev/shm tmpfs 5120 0 5120 0% /run/lock tmpfs 303352 0 303352 0% /sys/fs/cgroup |
Comparing the line for /dev/sda1 confirms that Debian 9 Stretch on Google Compute does automatically resize the root file system. Now I wanted to know how.
Step 7 – Get the serial port console output.
1 |
gcloud compute instances get-serial-port-output --zone us-east4-c instance-1 > console.log |
Documentation for gcloud compute instances get-serial-port-output.
Step 8 – Analyze the Console Output.
This produced about 1,000 lines. To reduce this output I used grep to search for output that is probably related to resizing the file system. Notice how I spelled “resiz”. I want the search to include “resize” and “resizing”.
1 |
grep -e resiz -e expand console.log |
This produced the following:
1 2 3 4 5 6 7 8 9 10 11 |
Oct 28 [ 3.979172] EXT4-fs (sda1): resizing filesystem from 2620928 to 3931643 blocks Oct 28 00:11:57 localhost expand-root.sh[458]: Growing partition /dev/sda1 Oct 28 00:11:57 localhost expand-root.sh[458]: CHANGED: partition=1 start=4096 old: size=20967424 end=20971520 new: size=31453151,end=31457247 Oct 28 00:11:57 localhost expand-root.sh[458]: Resizing ext4 filesystem on /dev/sda1 Oct 28 00:11:57 localhost expand-root.sh[458]: resize2fs 1.43.4 (31-Jan-2017) Oct 28 00:11:57 localhost kernel: [ 3.979172] EXT4-fs (sda1): resizing filesystem from 2620928 to 3931643 blocks [ 4.577767] EXT4-fs (sda1): resized filesystem to 3931643 Oct 28 00:11:57 instance-1 kernel: [ 4.577767] EXT4-fs (sda1): resized filesystem to 3931643 Oct 28 00:11:58 instance-1 expand-root.sh[458]: Filesystem at /dev/sda1 is mounted on /; on-line resizing required Oct 28 00:11:58 instance-1 expand-root.sh[458]: old_desc_blocks = 2, new_desc_blocks = 2 Oct 28 00:11:58 instance-1 expand-root.sh[458]: The filesystem on /dev/sda1 is now 3931643 (4k) blocks long. |
Step 9 – Figure out what command is used to resize the root file system.
From the console output I can see the command “expand-root.sh”. Using the command “which expand-root.sh”, I found this command located at “/usr/bin/expand-root.sh”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#!/bin/bash # Expands a partition and filesystem using growpart and an appropriate # filesystem tool for live filesystem expansion. Takes three arguments: # DEVICE, such as "/dev/sda" # PARTITION, such as "1" # FILESYSTEM, such as "ext4" DEVICE="${1}" PARTITION="${2}" FILESYSTEM="${3}" if [[ -z "${DEVICE}" || -z "${PARTITION}" || -z "${FILESYSTEM}" ]]; then echo "Requires: $0 DEVICE PARTITION FILESYSTEM" exit 1 fi # Grow partition using growpart if [[ -x /usr/bin/growpart ]]; then echo "Growing partition ${DEVICE}${PARTITION}" /usr/bin/growpart "${DEVICE}" "${PARTITION}" else echo "/usr/bin/growpart was not found" exit 1 fi echo "Resizing ${FILESYSTEM} filesystem on ${DEVICE}${PARTITION}" case "${FILESYSTEM}" in xfs) xfs_growfs / ;; ext2) resize2fs "${DEVICE}${PARTITION}" ;; ext3) resize2fs "${DEVICE}${PARTITION}" ;; ext4) resize2fs "${DEVICE}${PARTITION}" ;; *) echo "Unsupported filesystem, unable to expand size." ;; esac |
Debian 9 Stretch running on Google Cloud Compute Engine does resize the root volume automatically if you resize the root disk. Very nice.
Google Cloud offers the feature to resize the disk while the VM instance is running. Can you resize the root disk and the root filesystem while the system is running? If so, how?
Step 1 – Go to the Google Console -> Compute Engine -> Disks. Select the disk for the instance.
Step 2 – Click the “CREATE SNAPSHOT” button to create a recovery snapshot.
Step 3 – Click the edit button and resize the disk to 25 GB.
Step 4 – Connect to the instance.
Step 5 – Execute this command to see the disk size and partition layout:
1 |
fdisk -l |
This command produces the following output:
1 2 3 4 5 6 7 8 9 |
Disk /dev/sda: 25 GiB, 26843545600 bytes, 52428800 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disklabel type: dos Disk identifier: 0x70df3223 Device Boot Start End Sectors Size Id Type /dev/sda1 * 4096 31457246 31453151 15G 83 Linux |
Notice that the disk size is reported as “25 Gib” but the partition size is still “15G”. This means that the disk drive was resized to 25 GB but the root partition (filesystem) stayed the same size. Let’s try to resize the root filesystem while the system is running.
1 |
expand-root.sh /dev/sda 1 ext4 |
1 2 3 4 5 6 7 |
Growing partition /dev/sda1 CHANGED: partition=1 start=4096 old: size=31453151 end=31457247 new: size=52424671,end=52428767 Resizing ext4 filesystem on /dev/sda1 resize2fs 1.43.4 (31-Jan-2017) Filesystem at /dev/sda1 is mounted on /; on-line resizing required old_desc_blocks = 2, new_desc_blocks = 4 The filesystem on /dev/sda1 is now 6553083 (4k) blocks long. |
Automating the Resize
Now let’s take this even further and completely automate resizing a VM disk and resizing the root filesystem from the command line or a script.
Step 1 – Snapshot Disk.
First, we will snapshot the disk just in case.
1 |
gcloud compute disks snapshot instance-1 --snapshot-names instance-1-snapshot --zone us-east4-c --description="This is a test snapshot" |
Documentation for gcloud compute disks snapshot.
Step 2 – Resize Disk.
This command will resize the VM instance disk. Modify for the size you require, disk name and zone. Notice the –quiet flag. This prevents the prompt to confirm the resize.
1 |
gcloud compute disks resize instance-1 --zone us-east4-c --size 30GB --quiet |
Documentation for gcloud compute disks resize.
Step 3 – Resize Root Filesystem.
This command will use SSH to connect to the instance and execute the expand-root.sh program remotely.
1 |
gcloud compute ssh instance-1 --zone us-east4-c --command "sudo expand-root.sh /dev/sda 1 ext4" |
Documentation for gcloud compute ssh.
Step 4 – Verify Resize.
A final “df” command on the on VM instance shows that the new root filesystem is 30 GB (30,896,016 blocks).
1 2 3 4 5 6 7 |
Filesystem 1K-blocks Used Available Use% Mounted on udev 292220 0 292220 0% /dev tmpfs 60672 3180 57492 6% /run /dev/sda1 30896016 1663296 27853564 6% / tmpfs 303352 0 303352 0% /dev/shm tmpfs 5120 0 5120 0% /run/lock tmpfs 303352 0 303352 0% /sys/fs/cgroup |
I design software for enterprise-class systems and data centers. My background is 30+ years in storage (SCSI, FC, iSCSI, disk arrays, imaging) virtualization. 20+ years in identity, security, and forensics.
For the past 14+ years, I have been working in the cloud (AWS, Azure, Google, Alibaba, IBM, Oracle) designing hybrid and multi-cloud software solutions. I am an MVP/GDE with several.
2 Pingbacks