緊急時も安心!OS 起動時に自動でファイルシステムを拡張する方法を試してみた
こんにちは。テクニカルサポートチームのShiinaです。
はじめに
サーバーのディスクが突然いっぱいになり、SSH やリモートデスクトップ、セッションマネージャで接続ができなくなった経験はありませんか?
EBS ボリュームのサイズを変更するだけでは問題は解決せず、インスタンスに接続してファイルシステムを拡張するか、レスキューインスタンスにアタッチして拡張する必要があります。
そこで今回は、OS 起動時に自動でファイルシステムを拡張する方法 を紹介します。
設定しておくと、いざというときに慌てずに対処ができます。
ディスクフルによる一般的な問題
ルートボリュームの使用率が 100% になると、インスタンス接続時に以下のような問題が発生する可能性があります。
- リモートデスクトップ: 接続後、黒い画面のままとなる。
- SSH: "No space left on device" というメッセージが表示される。
- セッションマネージャ: "There is not enough space on the disk. Check [ssm-document-worker]/[ssm-session-worker] log for crash reason." というメッセージが表示される。
自動ファイルシステム拡張の概要
スタートアップやサービスにファイルシステムを拡張するスクリプトを登録します。
ディスクフルが原因でインスタンスに接続できない場合でも、EBS ボリュームのサイズを変更し、インスタンスを再起動すれば、自動的にファイルシステムの拡張が実行されます。
インスタンスに接続せずともファイルシステムの拡張が行えます。
ファイルシステム拡張スクリプトの設定(Windows)
スタートアップ時にファイルシステムを拡張する PowerShell スクリプトを実行するよう、タスクスケジューラのタスクを設定します。
サンプルスクリプトを次の PowerShell コマンドを利用して登録することができます。
# 設定するタスクの名前
$taskName = "Resize Partition on Startup"
# PowerShell スクリプトのパス
$scriptPath = "C:\Scripts\resize_partition.ps1"
# スクリプトを保存するフォルダを作成
$scriptFolder = Split-Path -Path $scriptPath
if (!(Test-Path $scriptFolder)) {
New-Item -ItemType Directory -Path $scriptFolder -Force
}
# スクリプトの内容を作成
if (!(Test-Path $scriptPath)) {
@"
`$driveLetter = "C" # 変更したいドライブのドライブレターを指定
`$size = (Get-PartitionSupportedSize -DriveLetter `$driveLetter).SizeMax
Resize-Partition -DriveLetter `$driveLetter -Size `$size
"@ | Out-File -Encoding UTF8 -FilePath $scriptPath
}
# タスクのトリガー(Windows 起動時)
$trigger = New-ScheduledTaskTrigger -AtStartup
# タスクのアクション(PowerShell スクリプトを実行)
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -File `"$scriptPath`""
# タスクの設定(管理者権限で実行)
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
# タスクを登録(管理者権限で実行)
Register-ScheduledTask -TaskName $taskName -Trigger $trigger -Action $action -Settings $settings -RunLevel Highest -User "SYSTEM"
タスクを登録した後、以下のコマンドの応答が表示されれば成功です。
TaskPath TaskName State
-------- -------- -----
\ Resize Partition on Startup Ready
ファイルシステム拡張スクリプトの設定(Linux)
systemd サービスにファイルシステムの拡張を行う Bash スクリプトを設定します。
サンプルスクリプトを次のコマンドを利用して登録することができます。
# スクリプトの内容を作成
sudo bash -c 'cat > /usr/local/bin/resize_ebs.sh <<EOF
#!/bin/bash
set -e # エラーが発生したらスクリプトを停止
# ルートボリュームのデバイス名を取得
ROOT_DEVICE=\$(findmnt -n -o SOURCE /)
# デバイス名を取得(例: /dev/nvme0n1p1 → /dev/nvme0n1)
if [[ "\$ROOT_DEVICE" =~ ^(/dev/nvme[0-9]+n[0-9]+)p[0-9]+$ ]]; then
DEVICE="\${BASH_REMATCH[1]}" # /dev/nvme0n1p1 → /dev/nvme0n1
elif [[ "\$ROOT_DEVICE" =~ ^(/dev/xvd[a-z]+)[0-9]+$ ]]; then
DEVICE="\${BASH_REMATCH[1]}" # /dev/xvda1 → /dev/xvda
elif [[ "\$ROOT_DEVICE" =~ ^(/dev/sd[a-z]+)[0-9]+$ ]]; then
DEVICE="\${BASH_REMATCH[1]}" # /dev/sda1 → /dev/sda
else
exit 1
fi
# デバイスがブロックデバイスか確認
if [[ ! -b "\$DEVICE" ]]; then
exit 1
fi
# パーティションのリサイズ(GPTの場合)
if lsblk -no FSTYPE "\$ROOT_DEVICE" | grep -q "xfs\|ext4"; then
GROWPART_OUTPUT=\$(sudo growpart "\$DEVICE" 1 2>&1) || true
if echo "\$GROWPART_OUTPUT" | grep -q "NOCHANGE"; then
exit 0
elif echo "\$GROWPART_OUTPUT" | grep -q "failed"; then
exit 1
fi
else
exit 1
fi
# ファイルシステムの拡張
FSTYPE=\$(lsblk -no FSTYPE "\$ROOT_DEVICE")
if [[ "\$FSTYPE" == "xfs" ]]; then
sudo xfs_growfs /
elif [[ "\$FSTYPE" == "ext4" ]]; then
sudo resize2fs "\$ROOT_DEVICE"
else
exit 1
fi
EOF'
# 実行権限を付与
sudo chmod +x /usr/local/bin/resize_ebs.sh
# systemd サービスファイルを作成
sudo bash -c 'cat > /etc/systemd/system/resize-ebs.service <<EOF
[Unit]
Description=Resize EBS Volume on Boot
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/resize_ebs.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF'
# systemd をリロードしてサービスを有効化
sudo systemctl daemon-reload
sudo systemctl enable resize-ebs.service
スクリプトの動作確認(Windows)
- タスクを手動実行します。
Start-ScheduledTask -TaskName "Resize Partition on Startup"
- タスクの実行履歴を確認します。
LastTaskResult が 0 であれば、正常に実行されています。
Get-ScheduledTaskInfo -TaskName "Resize Partition on Startup"
LastRunTime : 3/24/2025 8:25:04 AM
LastTaskResult : 0
NextRunTime :
NumberOfMissedRuns : 0
TaskName : Resize Partition on Startup
TaskPath :
PSComputerName :
スクリプトの動作確認(Linux)
- サービスを手動実行します。
sudo systemctl start resize-ebs.service
- サービスのステータスを確認します。
Active のステータスが active (exited) であれば、正常に実行されています。
sudo systemctl status resize-ebs.service
● resize-ebs.service - Resize EBS Volume on Boot
Loaded: loaded (/etc/systemd/system/resize-ebs.service; enabled; preset: disabled)
Active: active (exited) since Mon 2025-03-24 05:10:36 UTC; 1min 40s ago
Process: 1492 ExecStart=/usr/local/bin/resize_ebs.sh (code=exited, status=0/SUCCESS)
Main PID: 1492 (code=exited, status=0/SUCCESS)
CPU: 130ms
Mar 24 05:10:36 ip-10-0-0-143.ap-northeast-1.compute.internal resize_ebs.sh[1666]: data = bsize=4096 blocks=2094075, imaxpct=25
Mar 24 05:10:36 ip-10-0-0-143.ap-northeast-1.compute.internal resize_ebs.sh[1666]: = sunit=128 swidth=128 blks
Mar 24 05:10:36 ip-10-0-0-143.ap-northeast-1.compute.internal resize_ebs.sh[1666]: naming =version 2 bsize=16384 ascii-ci=0, ftype=1
Mar 24 05:10:36 ip-10-0-0-143.ap-northeast-1.compute.internal resize_ebs.sh[1666]: log =internal log bsize=4096 blocks=16384, version=2
Mar 24 05:10:36 ip-10-0-0-143.ap-northeast-1.compute.internal resize_ebs.sh[1666]: = sectsz=4096 sunit=4 blks, lazy-count=1
Mar 24 05:10:36 ip-10-0-0-143.ap-northeast-1.compute.internal resize_ebs.sh[1666]: realtime =none extsz=4096 blocks=0, rtextents=0
Mar 24 05:10:36 ip-10-0-0-143.ap-northeast-1.compute.internal resize_ebs.sh[1666]: data blocks changed from 2094075 to 20968443
Mar 24 05:10:36 ip-10-0-0-143.ap-northeast-1.compute.internal sudo[1651]: pam_unix(sudo:session): session closed for user root
Mar 24 05:10:36 ip-10-0-0-143.ap-northeast-1.compute.internal systemd[1]: Finished resize-ebs.service - Resize EBS Volume on Boot.
試してみた
検証環境
- Windows:Windows Server 2025
- Linux:Amazon Linux 2023
どちらの環境でも、Nitro ベースのインスタンスを使用しました。
Windows 編
-
Disk Management(diskmgmt.msc)を実行し、ディスク情報、使用率情報を確認します。
C ドライブに 40 GB が割り当てられていることを確認できます。
-
EC2 インスタンスにアタッチされているルート EBS ボリュームのサイズを変更します。
40 GiB から 80 GiB に変更します。
-
EC2 インスタンスの再起動を行います。
-
再度、Disk Management(diskmgmt.msc)を実行し、ディスク情報、使用率情報を確認します。
C ドライブが 80 GB に拡張されていることが確認できました!
Linux 編
- lsblk コマンドと df コマンドで現在のディスク情報、使用率情報を確認します。
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 8G 0 disk
├─nvme0n1p1 259:1 0 8G 0 part /
├─nvme0n1p127 259:2 0 1M 0 part
└─nvme0n1p128 259:3 0 10M 0 part /boot/efi
df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 766M 436K 766M 1% /run
/dev/nvme0n1p1 8.0G 1.6G 6.4G 20% /
tmpfs 1.9G 0 1.9G 0% /tmp
/dev/nvme0n1p128 10M 1.3M 8.7M 13% /boot/efi
tmpfs 383M 0 383M 0% /run/user/0
ルートボリューム (nvme0n1) に 8 GB が割り当てられていることを確認できます。
- EC2 インスタンスにアタッチされているルート EBS ボリュームのサイズを変更します。
8 GiB から 80 GiB に変更します。
-
EC2 インスタンスの再起動を行います。
-
再度、lsblk コマンドと df コマンドで現在のディスク情報、使用率情報を確認します。
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 80G 0 disk
├─nvme0n1p1 259:1 0 80G 0 part /
├─nvme0n1p127 259:2 0 1M 0 part
└─nvme0n1p128 259:3 0 10M 0 part /boot/efi
df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 766M 436K 766M 1% /run
/dev/nvme0n1p1 80G 2.1G 78G 3% /
tmpfs 1.9G 0 1.9G 0% /tmp
/dev/nvme0n1p128 10M 1.3M 8.7M 13% /boot/efi
tmpfs 383M 0 383M 0% /run/user/0
ルートボリューム (nvme0n1) のパーティション(nvme0n1p1)が 80 GB に拡張されていることが確認できました!
まとめ
本記事では、OS 起動時にファイルシステムを自動拡張する方法を紹介しました。
Windows ではタスクスケジューラ、Linux では systemd を活用することで、ディスクフル時の対応を自動化できます。
事前に設定しておくことで、緊急時にもスムーズに対応できるようになります。
本記事が誰かのお役に立てれば幸いです。
参考