問題と範囲
通常のバイト使用率は、ファイルシステムが別のファイルを作成できることを証明するものではありません。ext4などのファイルシステムはデータブロックとinodeを管理しており、大量の小さなファイル、キャッシュの断片、メールキュー、またはコンテナ層によってinodeが先に枯渇することがあります。ここでの課題は、不明なディレクトリを削除したり再起動によって証拠を消し去ったりすることなく、サービスを実行したまま原因を突き止めることです。
一般的なLinuxやDevOpsの面接資料では、診断シナリオとして「ディスクフル」がよく使用されます。dfのマニュアルとLinuxカーネルのext4ドキュメントには、ブロック、inode、ディレクトリエントリの境界が定義されているため、優れた回答では単にクリーンアップコマンドを列挙するのではなく、証拠に基づいてアクションを導き出します。
面接官がテストしていること
- バイトブロック、inode、ユーザー/プロジェクトクォータ、コンテナの書き込み可能層を区別できること。
- アクションを実行する前に、影響を受けているマウント、時間枠、書き込みパスを確認できること。
- 小さなファイルのホットスポット、隠れたマウント、ローテーションの不備、およびオープンされたまま削除されたファイルを特定できること。
rm -rfや無作為な再起動を行う代わりに、可逆的で監査可能な復旧手順を選択できること。- 容量の兆候として、inode使用率、ファイル数の増加、ディレクトリのホットスポットを監視できること。
最初に明確にすべき質問
- 失敗しているプロセスはどのパスとマウントに書き込んでいますか?それはホスト、コンテナ、または一時ファイルシステムのどれですか?
df -hとdf -iは何を報告していますか?ユーザーまたはプロジェクトのクォータは関係していますか?- 障害はファイルの新規作成、拡張、あるいはoverlay、tmpfs、ネットワークファイルシステムへの書き込みのいずれで発生していますか?
- デプロイ、ログローテーション、バックアップ、またはバッチジョブが実行中ですか?保持ルールによって削除が制限されていますか?
- サービスを一時的にスロットリングできますか?また、ロールバックやヘルスチェックのウィンドウはありますか?
30秒での回答
「失敗しているプロセス、マウント、および時間枠を特定し、df -hとdf -iを比較します。inode使用率が100%に近い場合は、ファイル数のホットスポットを特定し、コンテナの書き込み可能層、ログローテーション、およびクォータを調査します。inodeが正常な場合は、ブロック、予約領域、クォータ、および削除済みでオープン状態のファイルを確認します。復旧にあたっては、証拠を保全しながら、制御されたローテーション、圧縮、確認済みの一時データのクリーンアップ、または拡張から開始します。最終的には、単一のディスク使用率パーセンテージではなく、バイト数、inode、ファイル数、増加率、および修復までの時間に対してアラートを設定します。」
詳細な回答
ステップ 1: 障害の境界を確立する
アプリケーションおよびカーネルのログ、失敗しているパス、マウント情報を保全します。単一のサービス、単一のコンテナ、またはホスト全体のいずれがファイルを作成できないのかを判断します。同じエラーテキストでも、inodeの枯渇、ブロック不足、クォータ、または読み取り専用ファイルシステムを示している可能性があります。
ステップ 2: ブロックとinodeを併せて確認する
df -hT /
df -iT /
findmnt -T /var/lib/appdf -hはデータブロックを報告し、df -iはinodeを報告します。失敗しているパスを保持するマウントについて両方を確認します。バイト数が残っているにもかかわらずinode使用率が100%に近い場合は、小さなファイルの分析を優先します。そうでない場合は、ブロック、クォータ、読み取り専用状態、およびコンテナの制限を調査します。
ステップ 3: カウントによってディレクトリのホットスポットを特定する
不要なI/Oを避けるため、ファイルの内容を読み取る前にディレクトリエントリ数をカウントします。ディレクトリごとに検索範囲を絞り込み、最も急速に増加しているブランチを掘り下げます。findを既知のパスに限定し、他のマウントを除外して、トラフィックのピーク時には探索処理にリソース予算(制限)を設定します。小さなファイルでいっぱいのディレクトリは、バイト容量をほとんど消費せずにinodeを使い果たす可能性があります。
ステップ 4: ファイルをマウント境界から切り分ける
Overlayファイルシステム、バインドマウント、tmpfs、およびログボリュームにより、ホストのパスがプロセスの書き込み先レイヤーと異なる場合があります。プロセスの作業ディレクトリ、コンテナ設定、およびfindmnt -Tを照合します。コンテナ層のファイルをホストから直接削除しないでください。ランタイム、ボリュームポリシー、またはアプリケーションのクリーンアップパスを使用してください。
ステップ 5: ローテーション、キャッシュ、および削除済みでオープン状態のファイルを調査する
ローテーションによってプロセスがファイルを再度開くことなくログの名前が変更される場合や、キャッシュによって無制限に小さなファイルが作成される場合があります。lsof +L1を使用すると、ディレクトリリンクがゼロであるにもかかわらずプロセスが保持し続けているファイルを検出できます。これらを解放するには、通常、所有者がファイルを安全にクローズまたは再オープンする必要があります。再起動は証拠を破壊し、書き込みの急増を再現させる可能性があるため、デフォルトの手段ではありません。
ステップ 6: 復旧アクションを選択する
リスク順にアクションを整理します。重要でないプロデューサーをスロットリングし、確認済みのログをローテーションまたは圧縮し、保持ポリシーの対象となるキャッシュをクリーンアップしてから、拡張または移行を行います。各パス、サイズ、ファイル数、所有者、およびロールバック手順を記録します。削除する前に、そのデータが現在の設定、キューの状態、データベースのデータ、または監査の証拠ではないことを確認してください。
ステップ 7: 復旧と副作用を検証する
df -hTとdf -iTを再度実行し、実際の一時ファイル作成、ログ書き込み、および重要なリクエストを実行します。inode使用率、エラー率、およびレイテンシが回復したことを確認します。コンテナの場合は、再構築や再起動によってファイル数の急増がすぐに再発しないことを確認します。
ステップ 8: 恒久的な防御策を構築する
ブロックとinodeの使用率、マウントあたりのファイル数、ディレクトリの増加、ローテーションの遅延、削除済みでオープン状態のファイル、およびコンテナ層のサイズを監視します。一律の「90%」という単一の数値ではなく、増加率と応答時間に基づいてしきい値を設定します。クリーンアップ、拡張、ローテーションの復旧、および検証を実行可能なランブックにまとめ、リハーサルを実施します。
トレードオフと境界
クリーンアップ vs 拡張
クリーンアップはサービスを迅速に復旧させますが再発する可能性があります。拡張は原因を根本解決することなく空き容量を追加します。まずは復旧を優先し、その後、増加の証拠を利用してアプリケーションの変更、ローテーション、ファイルの粒度、または拡張のいずれかを選択します。
測定の精度 vs オンラインコスト
ディスク全体のfindは正確ですが高負荷です。ディレクトリ数のカウントやサンプリングは継続的な監視に適しています。インシデント発生時は、I/O負荷がかかっているファイルシステム全体を再帰的に読み取るのではなく、段階的にスコープを狭めていきます。
ホスト vs コンテナ
ホストのメトリクスは、ボリュームやoverlayのメトリクスの代わりにはなりません。すべての書き込み可能層には、クォータ、所有者、およびクリーンアップの境界が必要です。レイヤーをまたいだ削除は、予測不可能なイメージやボリュームの動作を引き起こす可能性があります。
障害訓練と改善
失敗例: df -h のみを確認する
inodeがゼロであってもバイト容量が残っている場合があります。初動診断にdf -iを含め、マウントごとにアラート履歴を管理してください。
失敗例: 最大のディレクトリに対して rm -rf を実行する
その中にはキュー、証拠、または現在書き込み中のファイルが含まれている可能性があります。所有権、保持期間、開いているハンドル、およびロールバックを確認した上で、制限されたバッチ単位でクリーンアップを行ってください。
失敗例: 復旧ではなく再起動を行う
再起動すると、削除済みでオープン状態のファイルが一時的に解放されるかもしれませんが、証拠が破壊され、発生源が隠蔽されてしまいます。所有者に安全にファイルをクローズさせ、次の書き込みを検証してください。
よくある間違いとフォローアップ
間違い: inodeの使用量はファイルサイズのみに関係する
inodeは主にファイル数とファイルシステムのフォーマットによって消費されます。0バイトのファイルやごく小さなファイルであっても消費されます。
フォローアップ: ファイルを削除しても空き容量が増えなかったのはなぜですか?
プロセスがまだそのファイル記述子を保持しているためです。ディレクトリエントリは削除されましたが、記述子が閉じられるまでブロックとinodeは割り当てられたままになります。
フォローアップ: クォータをどのように区別しますか?
ファイルシステム全体のメトリクスと、ユーザー、プロジェクト、およびコンテナのクォータを比較し、同じパス上で同じアイデンティティを使用して制御された作成テストを実行します。
フォローアップ: ログローテーションをどのように検証しますか?
プロセスが新しいファイルを開き、古いハンドルを閉じ、ファイル数とinode使用率が予算内に収まっていることを確認します。新しいファイル名が存在することだけでは証明になりません。
フォローアップ: 小さなファイルの大量発生をどのように防ぎますか?
レコードをバッチ処理し、時間でパーティション分割し、キャッシュエントリに上限を設け、ローテーション制限を設定し、ファイル作成率とディレクトリエントリの増加を監視します。
フォローアップ: 拡張が役に立たないのはどのような場合ですか?
inode密度が固定されており、新しいファイルシステムでも同じinode設計が提供される場合、バイト数を追加してもinode枯渇は解決しません。移行、再構築、またはファイルの粒度の変更を行ってください。