VPSでディスクの健全性を監視する方法
VPSでは物理ディスクのSMARTを取得できないことが多く、smartctlが失敗する理由もあります。I/Oエラー、再マウント、遅延、空き容量を監視して、書き込み障害の前に通知する方法を解説します。
VPS で実際に確認できるディスク健全性監視
VPS のディスク健全性監視は、多くのガイドが避ける事実から始まります。ディスクは利用者の所有物ではありません。ゲストから見えるのは仮想ブロックデバイスです。物理ドライブと、そこに保存されているすべてのカウンターはホストが管理します。smartctl /dev/vda が失敗するのは、コマンドの入力を誤ったからではありません。そのデバイスの背後に、質問へ応答できる対象が存在しないためです。
SMART(self-monitoring, analysis and reporting technology)は、ドライブ自体に保持されるカウンターの一覧です。再割り当てセクター、保留中のセクター、電源投入時間、メディアエラーなどが含まれます。この一覧を読み取るには、ATA または NVMe(non-volatile memory express)コマンドを実際のハードウェアまで届ける経路が必要です。準仮想化ディスクにはその経路がないため、ゲストに提供されるストレージからテレメトリは取り除かれています。
テナントが監視できるのは、ハードウェアではなく、その影響です。ゲスト内から確認できるシグナルは 4 つあります。カーネルログの I/O(input/output)エラー、読み取り専用で再マウントされるファイルシステム、上昇するレイテンシ、そして枯渇する空き容量です。4 つすべてを今すぐアラート対象にでき、4 つすべてがユーザーから苦情を受ける前に現れます。まずこれらを設定してください。責任分界については最後に扱います。どこに作業を割くべきかが変わるためです。
自分のサーバーが公開している内容を確認する
自分の環境がどのケースに該当するかを推測しないでください。まず確認し、その結果に一致するセクションを読んでください。
sudo apt update && sudo apt install -y smartmontools nvme-cli
lsblk -o NAME,TYPE,SIZE,MODEL,TRAN
sudo smartctl -a /dev/vdavirtio-blk、一般的な KVM (kernel-based virtual machine) のディスク。 デバイスは /dev/vda で、smartctl は何も送信する前に停止します。
/dev/vda: Unable to detect device type
Please specify device type with the -d option.virtio-blk は、背後に ATA または SCSI のコマンドセットを持たない準仮想化トランスポートです。そのため、SMART 要求を伝送する経路がありません。-d sat と -d scsi も同じ理由で失敗します。問題はフラグではなく、トランスポートにあります。
エミュレートされた SATA または SCSI ディスク。 デバイスは /dev/sda で、smartctl はデバイスを識別できるところまで進みます。モデル行には QEMU HARDDISK と表示されます。この文字列だけで判断できます。エミュレーターが作成したデバイスを参照しており、利用可能な SMART 機能は報告されていません。
NVMe namespace。 sudo nvme smart-log /dev/nvme0n1 は完全なログを返します。ここで誤判断しやすくなります。まず sudo nvme id-ctrl /dev/nvme0 | grep -E '^(mn|sn)' でコントローラーの識別情報を確認してください。ネットワークストレージ製品を示すモデル番号であれば、コントローラーはソフトウェアです。その場合、percentage_used と media_errors はデータを格納しているフラッシュではなく、そのエミュレーションを示しています。実際のストレージを確認するには、プランの説明を信頼せず、Linux で NVMe ディスクを確認するを参照してください。
LXC (Linux containers) や OpenVZ などのコンテナ。 自分専用のブロックデバイスはありません。lsblk にはホストのデバイスが表示されるか、何も表示されません。また、コンテナは CAP_SYS_RAWIO を保持していないため、smartctl の実行は拒否されます。
Smartctl open device: /dev/sda failed: Permission denied動作するケースについて、1 つ注意があります。VPS 上の smartctl が完全な属性テーブルを返す場合は、その値を利用する前にシリアル番号を確認してください。一部のホストはパススルーされたデバイスノードを公開しており、そこに表示されるカウンターは、そのマシン上のすべてのテナントが共有するハードウェアのものです。そこで Reallocated_Sector_Ct が増加していても、サポートチケットの対象です。自分のデータに関する状態を示すものではありません。
カーネルログに I/O エラーが記録される
これはテナントが取得できる中で最も価値の高いシグナルで、エージェントは必要ありません。
sudo journalctl -k -p err -b
sudo journalctl -k --since "7 days ago" | grep -iE 'i/o error|remount|ext4-fs error|buffer i/o'仮想ディスクへのリクエストが失敗すると、次のように表示されます。
blk_update_request: I/O error, dev vda, sector 2101248 op 0x1:(WRITE) flags 0x800 phys_seg 1 prio class 0ブロック層がホストに書き込みを要求し、ホストが失敗を返しています。VPS でフラッシュセルが故障していることは、ほとんどありません。通常は、ホストのストレージ層またはネットワーク接続ストレージへのネットワーク経路の問題です。つまり、プロバイダー側のイベントです。タイムスタンプ、デバイス名、セクターをチケットに記載してください。ストレージ担当チームは、これらの情報を自分たちのログと照合できます。
ext4 で最も重要なシーケンスは、次の 2 行です。
EXT4-fs error (device vda1): ext4_journal_check_start:83: comm cron: Detected aborted journal
EXT4-fs (vda1): Remounting filesystem read-only問題なのは 2 行目です。マシンは稼働し続けるためです。ping には応答し、SSH にも接続できますが、すべての書き込みが失敗します。通常の HTTP チェックは成功し続ける一方で、アプリケーションはリクエストごとにエラーを返します。
XFS は代わりにファイルシステムを停止します。
XFS (vda1): metadata I/O error in "xfs_trans_read_buf_map+0x1c0/0x2e0" at daddr 0x2 len 1 error 5
XFS (vda1): I/O Error Detected. Shutting down filesystemjournalctl -k は、ジャーナルがディスクに保存されていない限り、現在のブートのログだけを読み取ります。多くのイメージでは、RAM 上に存在する揮発性ジャーナルが使用されます。永続化を有効にしてください。そうしないと、トラブルシューティング中に実行する再起動によって、まさに必要な証拠が消失します。
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
journalctl --list-boots次回の再起動後、journalctl --list-boots で複数のブートが表示されるはずです。永続化を有効にしていても、読み取り専用になったファイルシステムには、その後の状況を記録できません。そのため、ログをサーバー外へ送信することが重要です。
読み取り専用での再マウントを検知する: シグナル 2
検知を試みる前に、障害を明確に表面化させます。
findmnt -no SOURCE,FSTYPE,OPTIONS /オプションに errors=remount-ro があるか確認します。Ubuntu と Debian の cloud image では /etc/fstab に設定されているため、メタデータエラーが発生すると、破損した状態で処理を続行せず、ファイルシステムを読み取り専用にします。設定されていない場合は、/etc/fstab の root エントリに追加するか、sudo tune2fs -e remount-ro /dev/vda1 で superblock に設定します。静かに破損が進むより、処理を停止して明確に失敗させる方が安全です。
mount flag が設定されているだけでは、書き込み可能である証拠になりません。実際に書き込みを試します。
touch /var/tmp/.disk-probe読み取り専用の root では、次の内容がそのまま出力されます。
touch: cannot touch '/var/tmp/.disk-probe': Read-only file system/tmp ではなく /var/tmp を使用します。多くのイメージでは /tmp はメモリ上に保持される tmpfs であるため、そこへの書き込みに成功しても、ディスクについては何も証明できません。
書き込みテストと空き容量の確認をまとめ、すべてのチェックに成功した場合だけ heartbeat を送信します。
sudo tee /usr/local/sbin/disk-probe >/dev/null <<'EOF'
#!/bin/sh
set -eu
probe=/var/tmp/.disk-probe
echo ok > "$probe"
test "$(cat "$probe")" = ok
rm -f "$probe"
used=$(df --output=pcent / | tail -n1 | tr -dc '0-9')
test "$used" -lt 90
inodes=$(df --output=ipcent / | tail -n1 | tr -dc '0-9')
test "$inodes" -lt 90
curl -fsS --max-time 10 "https://status.example.com/api/push/REPLACE_TOKEN?status=up&msg=OK" >/dev/null
EOF
sudo chmod 755 /usr/local/sbin/disk-probe
sudo /usr/local/sbin/disk-probe && echo probe-ok最後の行にある probe-ok は、チェーン全体が成功したことを示します。set -eu は、curl 行が実行される前に、いずれかのチェックが失敗すると終了ステータスを non-zero にします。そのため heartbeat は送信されません。これが反転の要点です。何も届かないため monitor が異常になり、書き込みできないサーバーは自身の問題を説明する情報も信頼できません。読み取り専用のファイルシステムでも読み取りは可能なので、スクリプト自体は起動します。
systemd timer から実行します。
# /etc/systemd/system/disk-probe.service
[Unit]
Description=Disk writability and space probe
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/disk-probe# /etc/systemd/system/disk-probe.timer
[Unit]
Description=Run the disk probe every five minutes
[Timer]
OnBootSec=2min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.targetsudo systemctl daemon-reload
sudo systemctl enable --now disk-probe.timer
systemctl list-timers disk-probe.timer
journalctl -u disk-probe.service -n 20 --no-pagersystemctl list-timers には、NEXT の時刻が 5 分以内に設定された unit が表示されます。実行に失敗すると、journalctl -u disk-probe.service に shell 自身のエラーテキストが表示されます。ログインしなくても、読み取り専用のファイルシステムと空き容量不足を区別できます。
この push URL は Uptime Kuma の push monitor です。Push タイプの monitor を作成し、その token をスクリプトにコピーします。1 回の実行が遅れても 03:00 に通知されないよう、monitor の heartbeat interval は timer interval より少し長く設定します。まだ status page がない場合は、自己ホスト型の Uptime Kuma instance にこのチェックを置くのが最も安価です。
注意すべき制限は 2 つあります。1 つ目は、このテストで確認できるのは書き込みが受け付けられたことだけであり、データが永続ストレージに到達したことではありません。read back は page cache から返される可能性があるためです。2 つ目は、監視対象のマシン上で実行されることです。そのため、サーバーが完全に停止すると診断を報告せず、無応答になります。
root ファイルシステムがすでに読み取り専用になっている場合の対処
- 状態を確認します。
findmnt -no OPTIONS /はroから始めます。 - まず証拠を RAM に保存します。
journalctl -k -b > /dev/shm/kernel.logを実行し、その後scp user@server:/dev/shm/kernel.log .で laptop からサーバー外へ取得します。 mount -o remount,rw /を単に実行して処理を続けないでください。ext4 が journal を中断している場合、再マウントは直ちに再度失敗します。成功した場合でも、まだ確認されていない破損箇所に書き込むことになります。- provider の rescue mode で再起動し、unmounted の状態でファイルシステムを確認します。ext4 には
e2fsck -fy /dev/vda1、XFS にはxfs_repair /dev/vda1を使用します。 - timestamp と sector を含む
blk_update_request行を provider に送信します。 - backup から復元して比較します。修復が必要になったファイルシステムでは、直近の書き込みの末尾が失われている可能性があるためです。
レイテンシとスループットの推移
sudo apt install -y sysstat
iostat -xdz 5 3まず r_await と w_await を確認します。これらは、キューでの待機時間を含む、読み取りまたは書き込みにかかった平均ミリ秒数です。次に aqu-sz を確認します。これは、処理中のリクエスト数の平均です。仮想ディスクでは %util を無視してください。これはキューが空でなかったことを示すだけです。多数のリクエストを並列処理できるデバイスは、上限に達していなくても 100 percent 近くになります。await が、ユーザーが体感する遅延を追跡する数値です。
絶対値よりも、自分のベースラインとの比較が重要です。そのため、負荷の低い 1 時間の値を記録して保存してください。カウンターを自分で収集する場合は、/proc/diskstats が生のデータソースです。
意図的に測定する場合は、次のようにします。
sudo apt install -y fio
fio --name=readlat --filename=/var/tmp/fio.probe --size=512M --rw=randread --bs=4k --iodepth=1 --direct=1 --runtime=30 --time_based --group_reporting
rm -f /var/tmp/fio.probeclat percentiles のブロックを確認します。特に 99th の値を確認してください。--direct=1 はページキャッシュを迂回します。ただし、ホストのキャッシュは迂回しません。そのため、結果はプロセスからプラットフォームのストレージまでの経路全体を示します。自分のワークロードと競合するため、サーバーがアイドル状態のときに実行してください。
カーネルログにエラーがないのに await が上昇する場合、通常はドライブの故障ではありません。ホスト上の競合です。ストレージにおける、ノイジーネイバーによる CPU steal time に相当します。毎日同じ時間帯に再発し、チケットの調査結果にも異常がない場合は、I/O が同じ方法で共有されないプランが答えです。ディスク負荷が高いワークロードでは、これは 通常の VPS よりもストレージ VPS を選ぶ理由 になります。
マウント中に実行できるファイルシステム検査
ext4 はスーパーブロックにエラーカウンターを保持します。ログが失われても、このカウンターは再起動後まで残ります。
sudo dumpe2fs -h /dev/vda1 2>/dev/null | grep -iE 'filesystem state|error count|first error|last error'正常なファイルシステムでは、Filesystem state: clean と FS Error count: 0 が表示されます。clean with errors や 0 以外のカウントは、誰も気付かず、ログがローテーション済みであっても、カーネルが過去にメタデータエラーを検出したことを示します。このコマンドは週次の確認項目に含めてください。
マウント中の root ファイルシステムに対して fsck は実行できません。また、稼働中のファイルシステムに対する e2fsck -n は、実行中にデータが変更されたことによる問題を報告します。完全な検査を実行するには、プロバイダーのコンソールから、1 回の起動に限ってカーネルコマンドラインへ fsck.mode=force fsck.repair=yes を追加します。systemd-fsck は、root を read-write でマウントする前に検査を実行します。
XFS にはオンライン検査がありません。xfs_repair -n /dev/vda1 はマウント中のファイルシステムに対して実行できないため、rescue mode で使用します。XFS はその代わりに、メタデータエラーが発生すると処理を継続せず、ファイルシステムを停止します。
Btrfs にはカウンターが組み込まれており、値も保持されます。
sudo btrfs device stats /
sudo btrfs scrub start -B /0 より大きい write_io_errs または corruption_errs は、実際にイベントが発生したことを示します。カウンターの値は、リセットするまで再起動後も保持されます。scrub はすべてのブロックを再読み込みし、チェックサムを検証します。仮想ディスクで実行できるメディア検査としては、これが最も近い方法です。I/O 負荷が高いため、利用の少ない時間帯にスケジュールしてください。
シグナル 5: df が表示しない部分を含む空き容量
空き容量がなくなると、サーバーはディスク障害と同じように停止します。ディスク障害よりも、はるかに頻繁に発生します。
df -h /
df -i /
sudo du -xh --max-depth=1 / | sort -h | tail -n 20No space left on device は df -h の一方で空き容量を表示します。前者が枯渇している場合、バイトではなく inode が不足しています。また、df -i は IUse% が 100 パーセントになっていることを示します。キャッシュディレクトリやメールスプールに大量の小さなファイルがあると、この状態になります。大きなファイルを削除しても解消しません。
ファイルを削除しても空き容量が戻らない場合、通常は、実行中のプロセスが削除済みファイルを開いたまま保持しています。sudo lsof +L1 は、リンク数が 0 になったファイルを一覧表示します。そのファイルを保持しているプロセスを再起動すると、空き容量が解放されます。
journal は、気付かないうちに容量を消費する一般的な要因です。journalctl --disk-usage は、journal が保持している容量を報告します。/etc/systemd/journald.conf で SystemMaxUse=200M を設定し、その後 sudo systemctl restart systemd-journald を実行して上限を適用します。今すぐ容量を回収するには sudo journalctl --vacuum-size=200M を実行します。
バグのように見えて、実際にはバグではないケースもあります。シンプロビジョニングされたホストストレージでは、df に数 GB の空き容量が表示されていても、ホスト側のプールが満杯になることがあります。その場合、書き込みは失敗し、カーネルログに I/O エラーが記録されます。ゲスト内のどこにも容量不足の警告は表示されません。ファイルシステムが満杯でないのにエラーが発生する場合は、同じ時間帯にチケットを起票する価値があります。
メトリクスエージェントにシグナルを接続する
Push probe は yes または no を返します。傾向を把握するにはメトリクスエージェントが必要ですが、Prometheus node_exporter は追加設定なしで上記の値をすべてエクスポートします。基盤として使用するメトリクス名は次のとおりです。
node_filesystem_readonlyはマウントが読み取り専用になると 1 になり、再マウントのアラームに使用できます。node_filesystem_avail_bytesとnode_filesystem_files_freeは、それぞれバイト数と inode 数を示します。node_disk_io_time_seconds_totalとnode_disk_read_time_seconds_totalは、ビジー時間とレイテンシをカウンターとして示すため、グラフ化できます。
実際にページ通知が必要になるケースは、次の 2 つのルールで検出できます。
- alert: FilesystemReadOnly
expr: node_filesystem_readonly{fstype!~"tmpfs|overlay"} == 1
for: 2m
- alert: FilesystemFillingUp
expr: predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[6h], 4*24*3600) < 0
for: 30m2 つ目のルールは、現在の傾向から 4 日以内に値が 0 に達すると発火します。そのため、使用率が 95 パーセントに達して数分しか残っていない時点ではなく、数日前に警告を受け取れます。
担当範囲
物理ドライブを管理するのはプロバイダーです。SMART の読み取り、アレイの運用、再割り当てセクターが増加したドライブの交換をプロバイダーが行います。通常、利用者には通知しません。アレイが障害を吸収するためです。これが VPS 上の RAID 10 の役割です。ドライブが故障しても、停止ではなく再構築になります。利用者がその処理を確認することはできません。仮想サーバーをレンタルする主な理由の 1 つは、この抽象化に料金を支払うことです。
データを所有するのは利用者です。そもそも、ドライブのテレメトリがデータを保護するわけでもありません。テナントのデータを実際に破壊するのは、誤った rm、不適切なデプロイ、SSH key を持つ侵入者、そしてアレイごと停止させるプラットフォーム障害です。SMART の属性では、これらを予測できません。
そのため、テナントにとって実効性のある保護は、サーバー外に保存されたバックアップと、自分で実行したリストアです。プロバイダーのスナップショットは便利ですが、保護対象と同じプラットフォーム上に保存されます。これが スナップショットとバックアップは異なる保護手段 である理由です。カレンダーに訓練の予定を入れてください。四半期に 1 回、最新のバックアップを新しい VPS にリストアし、アプリケーションを起動して、完了までの時間を記録します。その時間が、実際の復旧時間です。最初の訓練は、誰もが想定した時間より必ず長くなります。
SMART が適用される環境
smartctl を解説するガイドは正しく、ハードウェアが実際に自分の管理下に入った時点で適用できます。
- 専用サーバーまたはベアメタルサーバー。
sudo smartctl -a /dev/sdaで完全な属性テーブルを取得でき、属性が変化したときにsmartdからメールを送信できます。 - ゲストに物理ディスクを直接渡すストレージプラン。これは販売上の利点であるため、プロバイダーが明示的に説明しています。
- 自宅またはレンタルしたラックスペースで所有しているハードウェア。
sudo smartctl -a -d megaraid,0 /dev/sdaでアクセスできる RAID コントローラーの背後にあるディスク、または-d satを備えた USB エンクロージャー。
実際の NVMe では、sudo smartctl -a -d nvme /dev/nvme0 と sudo nvme smart-log /dev/nvme0n1 により、ドライブ自体から critical_warning と percentage_used が報告されます。実際の SATA では、故障を予測する属性は Reallocated_Sector_Ct (5)、Current_Pending_Sector (197)、Offline_Uncorrectable (198)、Reported_Uncorrect (187) です。これらのいずれかが 0 以外に変化したら、交換を計画してください。大規模なドライブ調査でも、同じ短い一覧が繰り返し示されています。それ以外の属性の多くはノイズです。
手動で確認するのではなく、デーモンを実行してください。
sudo systemctl enable --now smartd
sudo smartctl -t short /dev/sda
sudo smartctl -l selftest /dev/sdaセルフテストログには、直前に開始した実行について Completed without error と表示されるはずです。Ubuntu と Debian には、2026 年 8 月時点で DEVICESCAN 行を含む /etc/smartd.conf が同梱されています。そのため、デーモンは認識できるすべてのディスクを取得し、変更があれば root にメールを送信します。仮想ディスクではこれらが機能しません。これが、このガイドの後半が必要な理由です。
FAQ
smartctl が VPS で動作しないのはなぜですか?
ディスクが仮想ディスクだからです。virtio-blk を使用する KVM ゲストでは、smartctl -a /dev/vda を実行すると /dev/vda: Unable to detect device type が出力されます。準仮想化ディスクには、SMART 要求を送るための ATA または SCSI コマンドチャネルがないためです。エミュレートされたディスクでは、モデル名が QEMU HARDDISK と表示されるデバイスに接続されますが、その背後に利用可能な SMART データはありません。コンテナ内では、CAP_SYS_RAWIO がないため smartctl は完全に拒否されます。いずれも設定ミスではなく、-d フラグで解決することもできません。
VPS のディスクが故障しているかどうかを確認するにはどうすればよいですか?
ハードウェアそのものではなく、発生している影響を確認します。sudo journalctl -k -p err -b で blk_update_request: I/O error 行と Remounting filesystem read-only を確認します。ログからすでに失われたエラーを調べるには sudo dumpe2fs -h /dev/vda1 | grep -i 'error count' を実行します。iostat -xdz 5 から取得した r_await を、正常時に記録した基準値と比較して追跡します。VPS での I/O エラーは、通常、故障しかけたディスクではなくホスト側のストレージ問題を示します。そのため、発生時刻とセクターを添えてサポートチケットで報告します。
VPS のディスク健全性について、何をアラート対象にすべきですか?
4 つのアラートで対応できます。node_filesystem_readonly == 1 による読み取り専用マウント、または書き込みプローブの失敗です。空き容量と空き inode が 0 に近づいている状態です。直近の間隔で発生したカーネル I/O error です。サーバーからのハートビートです。応答が停止したときに通知を受け取れるようにします。SMART から派生した値は対象外にします。仮想ディスクでは、その値が存在しないか、ハイパーバイザーのエミュレーションを示しているだけだからです。
ファイルシステムが読み取り専用で再マウントされたのはなぜですか?
errors=remount-ro を指定して ext4 をマウントしている場合、メタデータエラーが発生すると意図的にこの動作をします。破損した状態で書き込みを続けるのではなく、書き込みを停止します。原因は通常、再マウント行の直前にあるカーネルログに記録されています。基盤デバイスが I/O エラーを返した後、ジャーナルが中断されたことを示す EXT4-fs error が一般的です。ファイルシステムを確認せずに読み書き可能で再マウントすると、症状だけが隠れ、原因が残ります。まずログを保存し、その後、レスキューモードでアンマウントした状態のファイルシステムを e2fsck -fy /dev/vda1 で確認します。
仮想サーバーで SMART データを読み取れることはありますか?
特定の条件では可能です。専用サーバーやベアメタルサーバーでは、実際の属性を取得できます。物理ディスクをゲストにパススルーするストレージプランでも取得できます。また、自分で所有・管理するホストでも可能です。一部のプラットフォームでは、ゲストに NVMe コントローラーを提示し、nvme smart-log でログを取得できます。そのため、最初に sudo nvme id-ctrl /dev/nvme0 を実行します。モデル番号がネットワークストレージサービスを示している場合、それらのカウンターはソフトウェアコントローラーから提供されています。共有マシン上でパススルーノードが実際のカウンターを公開している場合も、それは他のテナントと共有するハードウェアを示します。そのため、実行すべき対応はサポートチケットの作成だけです。