1. 全体概要
今回の作業は、長期間使ってきた4TBのZFS HDDに読取失敗履歴が見つかったことをきっかけに始まった。
検証環境
- Proxmox VE
- USB-SATA 2ベイケース
- Seagate Exos 7E8 8TB
- USB 10Gbps接続
- Netdata
- Beszel Agent
最終的には、次の流れになった。
- 旧4TB HDDのZFSプールとSMART履歴を確認。
SMART PASSEDだけでは健全性を判断できないことを確認。- 旧HDDを交換候補と判断し、ZFSプールを安全に
export。 - 新たに導入したSeagate Exos 7E8 8TBを接続。
- ディスク取り違え防止のため、
/dev/sdaではなく/dev/disk/by-id/を基準に操作。 - SMART詳細情報を保存。
- SMART Short testとConveyance testを実行。
badblocks -wsv -b 4096による破壊的な全面書込・読戻し検査を実行。- 最初の
nohup実行は途中停止したため、systemd-runに切り替え。 - 約87時間の
badblocksが完走し、0 bad blocks、0/0/0 errors。 - SMART Extended/Long self-testを実行し、
Completed without error。 - NetdataでUSB接続HDDのSMART温度・属性を収集できるよう調整。
- Beszel AgentでもSMARTデバイスを監視できるようsystemd drop-inを追加。
- SMB共有設定に新8TB HDDを追加し、
testparmで設定を検証。
2. 最終結果の要約
| 項目 | 結果 |
|---|---|
| 旧4TB ZFS HDD | 過去のExtended self-testに read failure、ATAエラー履歴あり。交換候補と判断 |
| 旧ZFSプール | 一時 DEGRADED。zpool clear 後に ONLINE へ戻ったが、物理劣化が直ったわけではない |
| 新8TB HDD | Seagate Exos 7E8 / ST8000NM000A-2KE101 |
| SMART事前状態 | PASSED、主要不良系属性は0 |
| SMART Short | Completed without error |
| SMART Conveyance | Completed without error |
| badblocks | 4パターン完走、0 bad blocks、0/0/0 errors |
| badblocks所要時間 | 約87時間 |
| SMART Extended/Long | Completed without error |
| Long test推奨待機時間 | 733分 |
LBA_of_first_error | - |
| 主要SMART属性 | Reallocated / Pending / Offline Uncorrectable / Reported Uncorrect / CRC / Timeout = 0 |
| 最高温度 | badblocks中の記録上49℃ |
| USB-SATA SMART | -d sat が必要 |
| Netdata | extra_devices + type: sat で収集成功 |
| Beszel | systemd drop-inでSMARTデバイスと必要Capabilityを追加、再起動後もactive |
| SMB | /mnt/HDD-8TB の共有設定を追加し、testparm -s で構文確認成功。Windows・Androidからの実アクセスも確認 |
3. 時系列
2026-07-07: 旧4TB ZFS HDDの異常を再確認
Proxmoxホスト上のZFSプール HDD が DEGRADED になっていることを確認した。
記録上の主な状態は次のとおり。
pool: HDD
state: DEGRADED
scan: scrub repaired 0B ... with 4 errors
errors: No known data errors
SMARTでは、全体判定は PASSED だった一方、過去のExtended self-testに読取失敗が残っていた。
SMART overall-health self-assessment test result: PASSED
Extended offline Completed: read failure
Reported_Uncorrect: 18
ATA Error Count: 18
UDMA_CRC_Error_Count: 0
ここで重要なのは、SMART PASSED は「完全に正常」を意味しないという点である。
全体判定が PASSED でも、セルフテスト履歴、未訂正エラー、代替処理済みセクタ、保留中セクタ、CRCエラーなどを個別に確認しなければならない。
その後、zpool clear HDD でZFS側の過去エラー表示をクリアし、新しいscrubを実行した。2026-07-09のscrubは約9時間28分で完了し、結果は0 errorsだった。ただし、これは「そのscrubで新しい整合性エラーが検出されなかった」という事実であり、過去のSMART Extended self-testの read failure やATAエラー履歴を消すものではない。そのため、旧HDDは引き続き交換候補として扱った。
2026-07-09: 旧ZFSプールを安全に切り離し、新8TB HDDを接続
旧4TB HDDはSMB用LXCから参照されていたため、先に依存関係を確認した。
grep -R "HDD" /etc/pve/qemu-server /etc/pve/lxc 2>/dev/null
当時の記録では、LXC設定内に次のような参照が確認された。
mp0: /HDD/data,mp=/mnt/HDD/data,acl=1
lxc.mount.entry: /HDD/data mnt/HDD/data none bind,create=dir 0 0
lxc.mount.entry: /HDD/data/test mnt/HDD/data/test none bind,create=dir 0 0
LXCを停止した後、ZFSプールをexportした。
pct shutdown <SMB_LXC_ID>
zpool export HDD
その後、物理的な接続変更前にホストを停止した。
shutdown now
zpool export HDD が成功してから取り外すことで、プールを「稼働中のまま突然消えたデバイス」として扱わせずに済む。
2026-07-09: 新8TB HDDを識別
新たに導入した8TB HDDはUSB-SATAケース経由でProxmoxへ接続した。
構成は次のとおり。
Seagate Exos 7E8 8TB
↓
USB-SATA 2ベイケース
↓
USB 10Gbps
↓
Proxmox
最初に全体を確認した。
lsblk -o NAME,SIZE,MODEL,SERIAL,TRAN,FSTYPE,TYPE,MOUNTPOINTS
zpool list
zpool import
ls -ld /HDD-8TB 2>/dev/null
新8TB HDDはLinux上で /dev/sda として見えていたが、以後の重要操作では /dev/sda を直接使わず、by-idを使った。
ブログ公開用の表記では次のように一般化する。
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
実際のデバイスを確認するコマンド。
readlink -f /dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
モデル、容量、ファイルシステム、マウント状態も確認した。
lsblk -o NAME,SIZE,MODEL,SERIAL,FSTYPE,TYPE,MOUNTPOINTS \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
確認時の重要ポイント。
SIZE: 7.3T
MODEL: ST8000NM000A-2KE101
FSTYPE: 空
MOUNTPOINTS: 空
つまり、対象ディスクが未フォーマット・未マウントであることを確認してから破壊的検査へ進んだ。
さらに、既存シグネチャが残っていないかを非破壊で確認した。
wipefs -n /dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
-n はno-actで、実際には消去せず確認だけ行う。
4. なぜ /dev/sda ではなく /dev/disk/by-id/ を使ったのか
/dev/sda、/dev/sdb のような名前は、接続順、再起動、USBケースの認識順などで変わる可能性がある。
一方、/dev/disk/by-id/ はモデル名やデバイス固有IDを基準にしたシンボリックリンクであり、対象の特定に使いやすい。
利点
- ディスク取り違えの危険を下げられる。
- 再起動後も同じ物理ディスクを指しやすい。
badblocks -wのような破壊的コマンドで特に有効。
欠点
- パスが長い。
- USBブリッジによっては期待したby-idが出ない場合がある。
- 物理的に同じモデルを複数台使う場合は、シリアル相当の部分まで確認する必要がある。
今回の重要ポイント
破壊的コマンドを打つ前に、必ず readlink -f と lsblk で最終確認した。
5. 検査前SMARTを保存
SMART詳細情報をファイルへ保存した。
smartctl -x -d sat \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL> \
| tee /root/smart-before-<DISK_SERIAL>.txt
オプションの意味
| 部分 | 意味 |
|---|---|
smartctl | SMART情報の表示・セルフテスト制御 |
-x | 通常の -a より広範囲なSMART情報を表示 |
-d sat | USB-SATAブリッジ越しにSATとしてATA SMARTへアクセス |
tee FILE | 画面表示しながら同時にファイルへ保存 |
検査前の主要値。
| 項目 | 初期値 |
|---|---|
| SMART overall-health | PASSED |
| Power_On_Hours | 0 |
| Power_Cycle_Count | 1 |
| Reallocated_Sector_Ct | 0 |
| Reported_Uncorrect | 0 |
| Command_Timeout | 0 0 0 |
| Current_Pending_Sector | 0 |
| Offline_Uncorrectable | 0 |
| UDMA_CRC_Error_Count | 0 |
| Total_LBAs_Written | 0 |
| SMART Error Log | No Errors Logged |
この「検査前の基準値」を保存しておくと、badblocks やLong test後に何が増えたかを比較できる。
6. SMART Short test
実行コマンド。
smartctl -t short -d sat \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
結果。
Short offline
Completed without error
目的
短時間で基本的な自己診断を行う。
利点
- 数分程度で終わる。
- 明らかな問題を早期に検出できる。
badblocksのような数日単位のテスト前の足切りに向く。
欠点
- HDD全域を読み切る検査ではない。
- Short test合格だけでは初期不良がないとは言えない。
7. SMART Conveyance test
実行コマンド。
smartctl -t conveyance -d sat \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
結果。
Conveyance offline
Completed without error
目的
主に輸送・取扱いによるダメージを短時間で検査する。
利点
- 新規購入直後や輸送後の確認に向く。
- 数分程度で終了する。
欠点
- 対応していないHDDもある。
- 全面書込・全面読取の代わりにはならない。
8. badblocks -wsv -b 4096 を選んだ理由
今回の目的は、実運用前に弱い個体をできるだけ炙り出すことだった。
使用した主要コマンドは次の形。
badblocks -wsv -b 4096 \
-o /root/badblocks-<DISK_SERIAL>.txt \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
オプションの意味
| オプション | 意味 | 重要点 |
|---|---|---|
-w | 書込モード | データを完全に破壊する |
-s | 進捗表示 | 何%進んだか確認できる |
-v | 詳細表示 | エラーや進捗を確認しやすい |
-b 4096 | ブロックサイズ4096バイト | 対象HDDの物理セクタサイズ4KiBに合わせた |
-o FILE | bad block一覧を書き出す | 問題ブロックがあればファイルに記録 |
-w モードが実際にすること
標準では4種類のパターンを使う。
0xaa
0x55
0xff
0x00
各パターンごとに、
- ディスク全域へ書く。
- ディスク全域を読み戻す。
- 書いた値と一致するか比較する。
つまり8TB HDDなら、概念上は次の8工程になる。
1. 0xaa 書込
2. 0xaa 読戻し比較
3. 0x55 書込
4. 0x55 読戻し比較
5. 0xff 書込
6. 0xff 読戻し比較
7. 0x00 書込
8. 0x00 読戻し比較
単純化すると約64TB相当の読み書きになる。
利点
- 0フィル1回より強いストレスを与えられる。
- 書込と読戻しの両方を複数パターンで確認できる。
- 初期不良や弱いセクタを実運用前に炙り出せる可能性が高まる。
欠点
- 非常に時間がかかる。
- HDDへ大きなI/O負荷をかける。
- 温度が上がる。
- 完全に破壊的であり、既存データは消える。
- 合格しても将来故障しない保証にはならない。
9. 最初の nohup 実行は途中停止した
最初は次のように実行した。
nohup badblocks -wsv -b 4096 \
-o /root/badblocks-<DISK_SERIAL>.txt \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL> \
> /root/badblocks-<DISK_SERIAL>.log 2>&1 & \
echo $! > /root/badblocks-<DISK_SERIAL>.pid
約4分17秒後、
0.81% done, 4:17 elapsed. (0/0/0 errors)
Interrupted at block 15746752
となり停止した。
この時点でSMART主要値に異常はなく、HDD自体の障害と断定できる証拠はなかった。
nohup コマンドの各部分
| 部分 | 意味 |
|---|---|
nohup | SIGHUPを無視してログアウト後も動かすことを狙う |
> FILE 2>&1 | 標準出力と標準エラーをログへまとめる |
& | バックグラウンド実行 |
echo $! | 直前にバックグラウンド起動したPIDを取得 |
> ...pid | PIDをファイルへ保存 |
利点
- 構成が簡単。
- 一般的なSSHセッションでは使いやすい。
欠点
- Webシェルやセッション管理方式によっては、期待どおり残らないことがある。
- プロセス状態、再起動、ログ、終了コードの管理が弱い。
- 今回は実際に途中停止した。
10. systemd-run に切り替えた
最終的に本番で使ったのは次の方式。
systemd-run --unit=badblocks-<DISK_SERIAL> --collect \
/bin/bash -lc \
'badblocks -wsv -b 4096 \
-o /root/badblocks-<DISK_SERIAL>.txt \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL> \
> /root/badblocks-<DISK_SERIAL>.log 2>&1'
開始時刻は2026-07-09 13:07:01 JST。
各部分の意味
| 部分 | 意味 |
|---|---|
systemd-run | 一時的なsystemdサービスとしてコマンドを起動 |
--unit=... | ユニット名を指定 |
--collect | 終了後に一時ユニットを回収しやすくする |
/bin/bash -lc | シェル経由でリダイレクト込みの複合コマンドを実行 |
利点
- ブラウザやWebシェルを閉じても処理を継続しやすい。
systemctlとjournalctlで状態を確認できる。- 終了コードを確認できる。
- tmuxのような対話セッション管理を覚えなくてもよい。
欠点
- コマンドが少し長くなる。
- 一時ユニット名やログの場所を理解しておく必要がある。
- OS再起動をまたぐ継続は別途設計が必要。
11. badblocks進捗確認
badblocks の進捗表示はキャリッジリターン \r で同じ行を書き換えるため、そのまま tail すると読みにくい。
そのため \r を改行に変換した。
tr '\r' '\n' < /root/badblocks-<DISK_SERIAL>.log \
| grep -E 'Testing with pattern|Reading and comparing|done|Interrupted' \
| tail -30
何をしているか
| 部分 | 目的 |
|---|---|
tr '\r' '\n' | 上書き型進捗を通常の複数行ログへ変換 |
grep -E ... | 必要な進捗行だけ抽出 |
tail -30 | 最新30行だけ表示 |
普段の確認用には次の形も使った。
echo "=== now ==="
date
echo "=== progress ==="
tail -c 20000 /root/badblocks-<DISK_SERIAL>.log \
| tr '\r' '\n' \
| grep -E 'Testing|Writing|Reading|done|errors|Interrupted' \
| tail -30
最重要ポイント: % は全体進捗ではない
例えば、
50.32% done, 48:03:08 elapsed. (0/0/0 errors)
の意味は、
50.32%: 現在の工程内の進捗48:03:08: badblocks開始からの累積経過時間0/0/0 errors: 読み取りエラー / 書き込みエラー / データ不一致の件数
である。
工程が変わると、
97%
100%
次の工程へ
1%
のように再び小さい値から始まる。
12. badblocks実行中のSMART確認
進捗だけでなく、SMART主要値と温度も随時確認した。
smartctl -a -d sat \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL> \
| egrep 'SMART overall|Reallocated|Current_Pending|Offline_Uncorrectable|UDMA_CRC|Reported_Uncorrect|Command_Timeout|Power_On_Hours|Temperature'
カーネルログも確認した。
dmesg -T \
| egrep -i 'sda|usb|uas|reset|error|fail|I/O|sense' \
| tail -120
見ていた主要項目
| SMART項目 | 見る理由 |
|---|---|
Reallocated_Sector_Ct | 代替処理済みセクタが増えていないか |
Current_Pending_Sector | 読めず保留中のセクタがないか |
Offline_Uncorrectable | オフライン検査で訂正不能がないか |
Reported_Uncorrect | ホストへ返された訂正不能エラー |
Command_Timeout | コマンドタイムアウトの有無 |
UDMA_CRC_Error_Count | SATA伝送系エラーの有無 |
Temperature | 長時間高負荷時の温度 |
温度について
badblocks中の記録では、最高49℃まで上がった。
SMARTのSCT表示上では推奨範囲が10〜40℃と表示されていたため、全面負荷中に推奨上限を上回る時間帯があったことになる。
これは直ちに故障を意味しないが、長時間の連続書込・読取では冷却状態を監視する価値がある。
13. badblocks完了確認
完了後、systemdユニット、ログ、bad block一覧、SMART、カーネルログをまとめて確認した。
DISK=/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
echo "=== finished at ==="
date
echo "=== service / exit record ==="
systemctl show badblocks-<DISK_SERIAL>.service \
-p ActiveState \
-p SubState \
-p Result \
-p ExecMainStartTimestamp \
-p ExecMainExitTimestamp \
-p ExecMainStatus 2>/dev/null
echo "=== journal tail ==="
journalctl -u badblocks-<DISK_SERIAL>.service \
--since "2026-07-13 00:00:00" \
--no-pager | tail -30
echo "=== final badblocks log ==="
tr '\r' '\n' < /root/badblocks-<DISK_SERIAL>.log \
| grep -E 'Testing with pattern|Reading and comparing|done|Interrupted|errors' \
| tail -50
echo "=== bad block file ==="
ls -l /root/badblocks-<DISK_SERIAL>.txt
wc -l /root/badblocks-<DISK_SERIAL>.txt
cat /root/badblocks-<DISK_SERIAL>.txt
echo "=== SMART after ==="
smartctl -x -d sat "$DISK" \
| tee /root/smart-after-<DISK_SERIAL>.txt
echo "=== kernel errors ==="
dmesg -T \
| egrep -i 'sda|usb|uas|reset|I/O error|medium error|sense key|blk_update_request' \
| tail -150
最終結果
Result=success
ExecMainStatus=0
ActiveState=inactive
SubState=dead
badblocks本体。
Testing with pattern 0xaa: done
Reading and comparing: done
Testing with pattern 0x55: done
Reading and comparing: done
Testing with pattern 0xff: done
Reading and comparing: done
Testing with pattern 0x00: done
Reading and comparing: done
Pass completed, 0 bad blocks found. (0/0/0 errors)
bad block一覧ファイル。
0 /root/badblocks-<DISK_SERIAL>.txt
つまり、問題ブロックは記録されなかった。
所要時間は約87時間。
14. badblocks後のSMART
badblocks後も主要SMART値は0だった。
| 項目 | 結果 |
|---|---|
| SMART overall-health | PASSED |
| Reallocated_Sector_Ct | 0 |
| Reported_Uncorrect | 0 |
| Command_Timeout | 0 0 0 |
| Current_Pending_Sector | 0 |
| Offline_Uncorrectable | 0 |
| UDMA_CRC_Error_Count | 0 |
| SMART Error Log | No Errors Logged |
この時点で、少なくとも次の事実が確認できた。
- 約87時間の破壊的全面書込・読戻し比較を完走した。
- 4パターンすべてでbad block 0。
- 主要SMART異常値は増えていない。
- カーネルログにI/O errorやUSB resetの連発は確認されていない。
ただし、これで将来故障しないことが保証されるわけではない。
今回の目的は「実運用前に弱い個体をできるだけ炙り出すこと」であり、その目的に対してはかなり強い初期検査になった。
15. SMART Extended / Long self-test
badblocks完了後、SMART Long testも実行した。
smartctl -t long -d sat \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
開始時の表示では、
Execute SMART Extended self-test routine immediately in off-line mode.
Testing has begun.
Please wait 733 minutes for test to complete.
と出た。
推奨待機時間は733分、約12時間13分。
進行中の確認
smartctl -a -d sat \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL> \
| egrep 'SMART overall|Reallocated|Current_Pending|Offline_Uncorrectable|UDMA_CRC|Reported_Uncorrect|Command_Timeout|Power_On_Hours|Temperature'
カーネルログも同時に確認。
dmesg -T \
| egrep -i 'sda|usb|uas|reset|error|fail|I/O|sense' \
| tail -120
完了後の確認
smartctl -l selftest -d sat \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
より詳細に見る場合。
smartctl -x -d sat \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
最終結果
# 1 Extended offline Completed without error 00% 103 -
ShortとConveyanceも含め、3種類すべてが Completed without error。
Short offline Completed without error
Conveyance offline Completed without error
Extended offline Completed without error
LBA_of_first_error は -。
16. Short / Conveyance / Long / badblocks の違い
| 検査 | 所要時間 | 書込 | 全域 | 破壊的 | 主な目的 |
|---|---|---|---|---|---|
| SMART Short | 短い | なし | いいえ | いいえ | 基本的な自己診断 |
| SMART Conveyance | 短い | なし | いいえ | いいえ | 輸送ダメージ系の簡易確認 |
| SMART Long | 長い | なし | 原則広範囲 | いいえ | HDD内部の長時間読取自己診断 |
badblocks -w | 非常に長い | あり | はい | はい | 複数パターンで全面書込・読戻し比較 |
役割の違い
- SMART Shortだけでは弱い。
- SMART Longは非破壊で全体読取系の診断ができる。
badblocks -wは強いが、既存データを完全破壊する。- 両方を通すことで、異なる種類の確認ができる。
17. NetdataでUSB接続HDDのSMART監視
問題
USB-SATAケース経由のExosは、通常の自動スキャンでは拾えなかった。
smartctl --scan
または、
smartctl --json --scan
ではNVMeだけが見え、USB-SATA接続HDDは自動認識されなかった。
一方、手動では次の形でSMARTを取得できた。
smartctl -a -d sat \
/dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
つまり、Netdata側にも「このデバイスは sat として読め」と明示する必要があった。
Netdata設定
設定ファイル。
/etc/netdata/go.d/smartctl.conf
構成例。
jobs:
- name: smart_disks
update_every: 10
poll_devices_every: 60
extra_devices:
- name: /dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
type: sat
- name: /dev/disk/by-id/ata-ST4000VN008-2DR166_<OLD_DISK_SERIAL>
type: sat
設定反映
systemctl restart netdata
sleep 10
systemctl is-active netdata
ログ確認。
journalctl -u netdata --since "-2 min" --no-pager \
| grep -i smartctl || true
Netdataユーザーとして直接デバッグ
runuser -u netdata -- \
/usr/libexec/netdata/plugins.d/go.d.plugin \
-d -m smartctl -j smart_disks
必要な行だけ絞る例。
runuser -u netdata -- \
/usr/libexec/netdata/plugins.d/go.d.plugin \
-d -m smartctl -j smart_disks 2>&1 \
| grep -E "ST8000NM000A|ST4000VN008|temperature|success|failed" \
| head -n 80
成功時の確認ポイント
ログ内で、対象HDDに対して次のような呼出しが出れば、type: sat が効いている。
--deviceName /dev/disk/by-id/ata-ST8000NM000A-2KE101_<DISK_SERIAL>
--deviceType sat
さらに、
Device temperature
smart status
Reallocated_Sector_Ct
Current_Pending_Sector
Offline_Uncorrectable
などのチャートが生成されていれば、SMART属性収集が動いている。
利点
- 温度履歴をグラフで追える。
- SMART属性の変化を継続監視できる。
- badblocksやLong test中の温度変化を追いやすい。
欠点
- USB-SATAブリッジは自動認識されないことがある。
-d sat相当の明示設定が必要になる場合がある。- 設定ミスでは「Netdata自体はactiveだがSMARTだけ取れていない」状態になり得る。
18. Beszel AgentでSMART監視
Netdataがめっちゃごちゃごちゃして見づらかったのでNetdataを残したままBeszelを追加し、実画面を比較する方針にした。
インストール時にはHub URL、公開鍵、トークンなどが必要だったが、これらはブログ公開情報に含めない。
公開用テンプレートでは次のように伏せる。
curl -sL https://get.beszel.dev -o /tmp/install-agent.sh
chmod +x /tmp/install-agent.sh
/tmp/install-agent.sh \
-p <AGENT_PORT> \
-k "<PUBLIC_KEY>" \
-t "<TOKEN>" \
-url "<BESZEL_HUB_URL>"
実際のトークン、内部IP、接続URLは公開しない。
SMARTデバイス設定
最終確認では、Beszel Agentのsystemd drop-inとして次のファイルが読み込まれていた。
/etc/systemd/system/beszel-agent.service.d/smart-devices.conf
/etc/systemd/system/beszel-agent.service.d/smart.conf
環境変数。
SMART_DEVICES=/dev/sda:sat,/dev/sdb:sat
Capability。
CapabilityBoundingSet=cap_sys_rawio cap_sys_admin
AmbientCapabilities=cap_sys_rawio cap_sys_admin
注意
Beszelの最終設定では /dev/sda と /dev/sdb を使っていた。
これは動作したが、/dev/sdX は接続順や再起動で変わる可能性があるため、by-id方式より取り違え耐性が弱い。
監視対象の実体が変わっていないかは、再起動後に確認するべきポイントである。
Beszel Agentの確認コマンド
systemctl status beszel-agent --no-pager
有効化と稼働状態。
systemctl is-enabled beszel-agent
systemctl is-active beszel-agent
読み込まれているユニットとdrop-in。
systemctl cat beszel-agent
実際に有効なEnvironmentとCapability。
systemctl show beszel-agent \
-p Environment \
-p CapabilityBoundingSet \
-p AmbientCapabilities
起動ログ。
journalctl -u beszel-agent -b --no-pager | tail -30
最終確認では、
enabled
active
で、再起動後もdrop-inが読み込まれ、AgentはHubへ接続できた。
19. NetdataとBeszelの役割比較
| 項目 | Netdata | Beszel |
|---|---|---|
| 詳細なローカルメトリクス | 強い | 比較的シンプル |
| SMART属性 | go.d smartctlで詳細 | Agent設定次第 |
| USB-SATA | extra_devices + type: sat で対応 | SMART_DEVICES に :sat 指定 |
| UIの情報量 | 多すぎてめっちゃ見づらい | 軽量で見やすい |
| 導入負荷 | やや重い | 軽い |
| 今回の運用 | 削除せず併存 | 横に追加して比較 |
今回の重要な方針は、Netdataを消してからBeszelへ移行するのではなく、並行稼働させて実画面を比較したことである。
これにより、気に入らなければBeszelだけ消す、という戻しやすい構成になった。
20. GPT + 1パーティション + ext4の検討
新8TB HDDの初期検査後、バックアップ用途としてどう初期化するかを検討した。
主な候補は、
GPT
└─ 1パーティション
└─ ext4
だった。
GPT + 1パーティションの利点
- 一般的な構成で、ツールやOSから認識しやすい。
- 将来Windowsなど別環境へ直結したときも「通常のディスク構成」として扱いやすい。
- パーティション単位で管理できる。
欠点
- Linux専用運用なら、ディスク全体へ直接ファイルシステムを作るより1段増える。
- 管理対象が増える。
ext4を選ぶ理由として検討した点
- Linuxで非常に一般的。
- ジャーナリングあり。
- POSIXパーミッションを扱える。
- Samba経由ならWindowsクライアントから普通に使える。
- Linuxネイティブで扱いやすい。
ext4の欠点
- Windowsへ直接USB接続しても標準機能では読めない。
- Windows直結を重視するならNTFS/exFATの方が互換性は高い。
NTFS / exFATとの比較
| 項目 | ext4 | NTFS | exFAT |
|---|---|---|---|
| Linuxネイティブ運用 | 強い | 可能 | 可能 |
| Samba共有 | 問題なし | 可能 | 可能 |
| Windows直結 | 標準では不可 | 強い | 強い |
| ジャーナリング | あり | あり | なし |
| POSIX権限 | 強い | Linuxでは扱いに工夫あり | 弱い |
| 大容量バックアップ用途 | 向く | Windows混用なら有力 | 単純交換用途向け |
21. ext4の予約領域を5%のままにしない
ext4はデフォルトで、一般にファイルシステム容量の5%をroot用予約ブロックとして確保する。
8TB級ディスクでは5%は非常に大きい。
単純計算では、
8TB × 5% ≒ 400GB
となる。
バックアップ用HDDでは大きすぎるため、0.1% 程度まで下げる案を検討した。
8TB × 0.1% ≒ 8GB
予約領域の目的
- 一般ユーザーが容量を使い切ってもrootが最低限の作業をできるようにする。
- ファイルシステムが極端に満杯になることによる断片化悪化を抑える。
利点
- 5%より大幅に無駄容量を減らせる。
- 数GB〜十数GBを残すことで、完全な0%より保守余地を残せる。
欠点
- 予約量を減らしすぎると、完全に埋まったときの保守余地が小さくなる。
- ルートファイルシステムでは5%を大きく下げる判断は慎重にするべき。
関連コマンド
新規作成時。
mkfs.ext4 -m 0.1 /dev/<TARGET_PARTITION>
作成後に変更する場合。
tune2fs -m 0.1 /dev/<TARGET_PARTITION>
最終的には、バックアップ用HDDとして予約領域を0.1%に設定した。8TB級ディスクでは単純計算で約8GBを予約領域として残す構成になる。
22. 最終的なフォーマット・マウント構成
初期不良チェック完了後、新8TB HDDはバックアップ用途として次の構成で運用することにした。
最終構成
- パーティション構成:GPT + 1パーティション
- ファイルシステム:ext4
- ext4予約領域:0.1%
- ラベル:
HDD-8TB - マウントポイント:
/mnt/HDD-8TB - fstab:
nofailを採用 - デバイス待機時間:10秒
なぜ nofail を付けたのか
今回の8TB HDDはUSB接続のバックアップ用ディスクであり、OSの起動に必須のシステムディスクではない。
そのため、次のような場合でも、HDDが見つからないことを理由にProxmoxホストの起動を止めたくなかった。
- HDDを物理的に外している
- USBケースの電源が入っていない
- HDDやUSB接続に異常がある
そこで、fstabには nofail を採用した。
これにより、対象HDDが存在しない場合でも、そのディスクのマウント失敗だけを理由にOS全体の起動を失敗扱いにしない構成にした。
デバイス待機時間を10秒にした理由
外付けUSB HDDでは、接続されていないデバイスを長時間待ち続ける必要はない。
そのため、デバイスの出現を待つ時間を10秒に設定した。
今回の運用では、次の動作を狙った。
HDDが正常に接続されている
↓
/mnt/HDD-8TB へマウント
HDDが未接続・故障・認識失敗
↓
一定時間で待機を打ち切る
↓
OS自体は起動を継続
23. SMB共有へ新8TB HDDを追加
SMB用LXCの smb.conf に新しい共有を追加した。
公開用にユーザー名・グループ名を一般化すると次の形。
[HDD-8TB]
comment = 8TB Backup Shared Folder
path = /mnt/HDD-8TB
valid users = <WRITE_USER> <READ_USER>
write list = <WRITE_USER>
force group = <SMB_GROUP>
create mask = 0664
directory mask = 0775
各設定の意味
| 設定 | 意味 |
|---|---|
path | 実際に共有するLinux側パス |
valid users | 接続を許可するユーザー |
write list | 書込可能ユーザー |
force group | 作成ファイルのグループを統一 |
create mask | 新規ファイルの最大権限 |
directory mask | 新規ディレクトリの最大権限 |
構文確認
pct exec <SMB_LXC_ID> -- testparm -s
結果。
Loaded services file OK.
さらに、出力上で [HDD-8TB] が確認できた。
testparm の利点
- Samba設定の構文ミスを検出できる。
- 実際に有効な設定を正規化して表示できる。
testparm の限界
- 実際のファイルシステム権限までは保証しない。
- bind mountが存在するかまでは保証しない。
- Windowsクライアントから接続できるかは別途確認が必要。
特に重要
Samba設定に path = /mnt/HDD-8TB と書くだけでは、LXCからそのパスが見えていなければ共有できない。
つまり、
Proxmoxホスト上のマウント
↓
LXCへのbind mount
↓
Sambaのpath設定
の3層を分けて考える必要がある。
さらに、WindowsとAndroidの実クライアントから接続し、書き込み用アカウントで実際に読み書きできることを確認した。読み取り専用アカウントについても、用途に応じたアクセス制御を設定した。
24. 旧4TB HDDの再確認で学んだこと
旧4TB HDDは、一時 DEGRADED だったZFSプールが zpool clear HDD 後に ONLINE へ戻った。
しかし、これはHDDが修理されたわけではない。
zpool clear HDD
zpool clear HDD
ZFSのエラー表示・カウンタをクリアする。
利点
- 過去のエラー状態をいったんクリアして、再発するか観察できる。
欠点
- 物理セクタ不良を修理しない。
- SMART履歴を消さない。
- 過去のセルフテスト失敗を無効化しない。
「ONLINEに戻った = HDDが正常化した」ではない。
25. zpool scrub HDD
zpool scrub HDD
ZFSプール内の全データを読み直し、チェックサムと照合する。
利点
- 保存データの整合性確認ができる。
- 冗長構成なら、条件により訂正・修復できる。
欠点
- 単一ディスクでは、読めないデータを別コピーから復旧する冗長性がない。
- HDDへ長時間I/O負荷がかかる。
scrubはバックグラウンドで動くため、シェルを閉じても継続する。
進捗確認。
zpool status -v HDD
30秒ごとに表示。
watch -n 30 zpool status -v HDD
I/O確認。
zpool iostat -v HDD 5
停止する場合。
zpool scrub -s HDD
26. 旧HDD調査で使った主要コマンド一覧
ZFS状態
zpool status HDD
zpool status -P HDD
zpool status -v HDD
zpool events -v | tail -n 100
| コマンド | 目的 |
|---|---|
zpool status HDD | プール全体の状態確認 |
zpool status -P HDD | デバイスパスを絶対パスで表示 |
zpool status -v HDD | 影響ファイルを含む詳細表示 |
zpool events -v | ZFSイベント履歴確認 |
データセット
zfs list -r -o name,used,avail,mountpoint HDD
ZFSデータセット名、使用量、空き、マウントポイントを一覧表示する。
Proxmoxストレージ定義
pvesm status
HDDがProxmoxのストレージとして登録されているか、VM/LXC用ストレージがどこにあるかを確認する。
LXC/VMからの参照確認
grep -R "HDD" /etc/pve/qemu-server /etc/pve/lxc 2>/dev/null
物理ディスクを外す前に、どのVM/LXC設定がHDDを参照しているか調べる。
27. 重要な失敗・つまずき
1. SMART PASSED を過信しそうになった
旧HDDは SMART PASSED だったが、Extended self-testに read failure が残っていた。
対策: 全体判定だけでなく、セルフテストログと主要属性を見る。
2. badblocks の % を全体進捗と誤認しやすい
表示されるパーセントは現在の工程内の進捗。
対策: Testing with pattern と Reading and comparing を一緒に見る。
3. nohup が途中停止した
Webシェル環境では期待どおり残らないケースがあった。
対策: systemd-run へ切り替え、ユニットとして管理。
4. USB-SATA HDDをSMART自動検出できなかった
smartctl --scan ではNVMeしか見えなかった。
対策: -d sat を明示し、Netdataにも type: sat を設定。
5. zpool clear を修復と誤解しやすい
ONLINE に戻っても物理的な劣化は直らない。
対策: SMART履歴とscrub結果を別々に評価する。
6. LXC設定の「説明欄」と「実際の有効設定」を混同しやすい
後の確認では、旧 mp0 の文字列が説明欄に残っているだけで、実際の有効設定ではなかった時点もあった。
対策: pct config <ID> や設定ファイル実体を確認し、description文字列と有効パラメータを区別する。
7. 監視設定と実際のデバイス名の安定性は別問題
Beszelの最終設定は /dev/sda:sat,/dev/sdb:sat で動作したが、/dev/sdX は変わり得る。
対策: 再起動後に lsblk、systemctl show、ログ、監視画面を再確認する。
28. コマンド別の利点・欠点まとめ
| コマンド / 方法 | 目的 | 利点 | 欠点・危険 |
|---|---|---|---|
lsblk | ディスク識別 | 一覧性が高い | /dev/sdX は変わる |
readlink -f /dev/disk/by-id/... | 実体確認 | 取り違え防止 | パスが長い |
wipefs -n | シグネチャ確認 | 非破壊 | -n を外すと消去操作になる |
smartctl -x -d sat | 詳細SMART | 情報量が多い | USBブリッジ依存 |
smartctl -t short | 短時間自己診断 | 早い | 全面検査ではない |
smartctl -t conveyance | 輸送ダメージ確認 | 新規導入時に有効 | 非対応ドライブあり |
smartctl -t long | 長時間自己診断 | 非破壊 | 時間がかかる |
badblocks -w | 全面書込・読戻し | 強い検査 | 既存データが消去され、一般的なデータ復旧は極めて困難になる |
nohup | セッション切断対策 | 簡単 | 環境依存で停止する場合あり |
systemd-run | 長時間処理管理 | 状態・ログ・終了コード確認 | コマンドが長い |
zpool clear | ZFSエラー履歴クリア | 再発確認しやすい | 修理ではない |
zpool scrub | ZFS整合性検査 | データ読取・チェックサム確認 | I/O負荷 |
testparm -s | Samba設定検証 | 構文確認に強い | 実アクセス成功までは保証しない |
| Netdata smartctl job | SMART履歴監視 | 詳細グラフ | USB-SATAは手動設定が必要な場合あり |
| Beszel Agent | 軽量監視 | UIが簡潔 | SMART権限・デバイス指定が必要 |
29. 今回のHDD初期不良チェックを再現する最小フロー
警告: 下記の
badblocks -wは対象ディスクのデータを完全に破壊する。対象確認が100%できない場合は実行しない。
1. 対象確認
lsblk -o NAME,SIZE,MODEL,SERIAL,TRAN,FSTYPE,TYPE,MOUNTPOINTS
readlink -f /dev/disk/by-id/<TARGET_DISK_ID>
lsblk -o NAME,SIZE,MODEL,SERIAL,FSTYPE,TYPE,MOUNTPOINTS \
/dev/disk/by-id/<TARGET_DISK_ID>
2. SMART保存
smartctl -x -d sat /dev/disk/by-id/<TARGET_DISK_ID> \
| tee /root/smart-before.txt
3. Short test
smartctl -t short -d sat /dev/disk/by-id/<TARGET_DISK_ID>
4. Conveyance test
smartctl -t conveyance -d sat /dev/disk/by-id/<TARGET_DISK_ID>
5. destructive badblocks
systemd-run --unit=badblocks-test --collect \
/bin/bash -lc \
'badblocks -wsv -b 4096 \
-o /root/badblocks.txt \
/dev/disk/by-id/<TARGET_DISK_ID> \
> /root/badblocks.log 2>&1'
6. 進捗確認
tr '\r' '\n' < /root/badblocks.log \
| grep -E 'Testing with pattern|Reading and comparing|done|Interrupted|errors' \
| tail -50
7. 完了確認
systemctl show badblocks-test.service \
-p ActiveState -p SubState -p Result -p ExecMainStatus
wc -l /root/badblocks.txt
8. SMART Long
smartctl -t long -d sat /dev/disk/by-id/<TARGET_DISK_ID>
完了後。
smartctl -l selftest -d sat /dev/disk/by-id/<TARGET_DISK_ID>
9. 最終SMART
smartctl -x -d sat /dev/disk/by-id/<TARGET_DISK_ID> \
| tee /root/smart-after.txt
30. 最終評価
今回の新8TB HDDは、確認できた範囲で次をすべて通過した。
SMART overall-health: PASSED
SMART Short: Completed without error
SMART Conveyance: Completed without error
badblocks 4-pattern destructive write/read compare: 0 bad blocks
badblocks errors: 0/0/0
SMART Extended/Long: Completed without error
LBA_of_first_error: -
Reallocated_Sector_Ct: 0
Current_Pending_Sector: 0
Offline_Uncorrectable: 0
Reported_Uncorrect: 0
UDMA_CRC_Error_Count: 0
Command_Timeout: 0
したがって、家庭で実施できる初期不良チェックとしてはかなり強い検査を通したと言える。
ただし、これは将来故障しない保証ではない。
HDDは消耗品であり、初期検査を通過しても後日故障する可能性は残る。
今回の検査の価値は、
- 導入直後の明らかな不良
- 弱いセクタ
- 書込・読戻し不一致
- SMARTセルフテスト失敗
- USB接続の不安定性
- 温度上昇
を、実運用前にできるだけ発見することにあった。
31. まとめ
今回の作業で最も重要だったのは、単に「HDDを交換した」ことではない。
実際には、
旧HDDの異常履歴確認
↓
ZFS状態確認
↓
依存しているLXC確認
↓
安全にzpool export
↓
新HDDをby-idで厳密に特定
↓
SMART事前保存
↓
Short / Conveyance
↓
badblocks 4パターン
↓
SMART Long
↓
Netdata / Beszelで継続監視
↓
SMB共有設定確認
という一連の流れになった。
特に重要な教訓は次の5点。
SMART PASSEDだけで正常判定しない。- 破壊的コマンドでは
/dev/sdXよりby-idを優先する。 badblocks -wは非常に強いが、完全破壊的で時間もかかる。- 長時間処理は、Webシェル環境では
systemd-runの方が管理しやすかった。 - USB-SATA SMARTは
-d satが必要になる場合があり、監視ツールにも同じ情報を明示する必要がある。
この一連の記録は、同じ作業を数か月後・数年後にやり直すときの再現手順として使える。