Article
Kubernetesのinode枯渇を防ぐ:イメージGCと退避の間を監視で埋める
kubeletはinode不足を検知しますが、容量ベースのイメージGCはバイト数を基準に動きます。CNCFの運用事例を起点に、inodeの診断、早期警告、実行用イメージの見直しをつなげます。
Share
こはるの読みどころ
空き容量を見るときは、ファイルを増やせる余裕も一緒に見たいね。警告が出る条件と、kubeletが回収を始める条件を分けて読むと、次の手が決めやすいよ。

ディスクに空きがあるのに、ファイルを作れなくなる方向へ進んでいる。Kubernetesノードでは、容量のグラフだけを見ていると、この兆候を見落とすことがあります。
きっかけは、2026年10月5日にCNCF Blogへ掲載された運用事例です。記録上のディスク使用率は83%、inode使用率は67%でしたが、inodeの枯渇を予測する警告が発生しました。数値の大きい方が、先に問題になるとは限らないわけですね。
Linuxノードを運用するなら、知りたいのは「kubeletが片付けてくれるまで待ってよいか」です。その判断に必要な、容量とinode、イメージGCとPod退避の違いを押さえ、診断から予防へつなげます。
空きバイト数だけでは、ファイルを増やせるか分からない
inodeは、所有者や権限、時刻、データの所在などを保持するファイルシステムの管理情報です。ext4でも、ファイルの大きさとは別にinodeの構造を持ちます。Linuxカーネルのext4仕様を見ると、バイト容量とファイル管理のための資源を分けて考える理由が分かります。
小さなファイルを大量に作る処理では、データ量の増加が小さくても、多数のinodeを消費し得ます。イメージの圧縮サイズだけでは、ノード上へ展開した後の負担を判断できません。
CNCFの事例では、containerdのsnapshot領域に展開された依存関係が調査対象になり、イメージ全体には4万を超えるファイルが含まれていました。これはその事例の記録であり、すべてのNode.jsイメージに当てはまる数ではありません。
イメージGCの85%とinode退避の5%は、別の資源を測っている
容量ベースのイメージGCは、イメージ用ファイルシステムの使用率をバイト数から計算します。設定の既定値は、回収開始の目安となる imageGCHighThresholdPercent が85、回収目標の imageGCLowThresholdPercent が80です。inode使用率が85%になったら回収する、という意味ではありません。GCの実装と設定リファレンスで、この区別を確認できます。
一方、Linux向けのhard evictionにはinodeの空き率が含まれます。Kubernetes v1.37.0の既定値を、ディスク関連の項目だけ並べると次のとおりです。
| 対象のシグナル | 既定の閾値 | 測っているもの |
|---|---|---|
nodefs.available |
空き10%未満 | nodefsのバイト容量 |
imagefs.available |
空き15%未満 | imagefsのバイト容量 |
nodefs.inodesFree |
空き5%未満 | nodefsのinode |
imagefs.inodesFree |
空き5%未満 | imagefsのinode |
閾値に達すると、kubeletはまず不要な資源の回収を試み、足りなければPodを退避します。hard evictionによる終了の猶予は0秒です。空きinodeが5%を下回ることは、普段の掃除を待つ段階とは意味が違います。ノード圧迫による退避の仕様に沿って、回収と退避を区別しておきたいところです。
表は上流の既定値なので、実環境の evictionHard と照合します。一部だけ上書きすると、mergeDefaultEvictionSettings がfalseの場合、未指定のシグナルは既定値を継承せず0になります。設定のマージ規則も含めて見ると、「既定では守られているはず」という思い込みを避けられます。
dfとduで、inodeを消費する保存先までたどる
最初に、同じ保存先についてバイト使用率とinode使用率を並べます。次はcontainerdの保存先が /var/lib/containerd にある場合の読み取り用コマンドです。パスを変更している環境では、実際の保存先へ置き換えます。
# ルートとcontainerd保存先のバイト容量を確認する
df -h / /var/lib/containerd
# 同じ保存先のinode使用量を確認する
df -i / /var/lib/containerd
df -i はブロック容量の代わりにinode情報を表示します。GNU dfの説明にあるとおり、引数のパスが属するファイルシステムを調べられます。containerdを別ディスクへ置いているなら、/ だけの確認では不十分です。
ファイルが集中するディレクトリは、GNU coreutilsの du で絞れます。読み取り権限が必要で、ファイル数が多いほど走査にも時間がかかるため、まず対象の保存先に範囲を限定します。
# inode数の多いディレクトリを、別ファイルシステムへ跨がずに探す
sudo du --inodes -xS /var/lib/containerd | sort -nr | head -n 20
--inodes はinode数、-x は別ファイルシステムを走査しない指定、-S は子ディレクトリ分を親の集計に含めない指定です。GNU duの仕様に沿って読むと、大きな親ディレクトリの下にあるファイルの集中箇所を探せます。結果は消費元を追う手掛かりとして使い、snapshotのディレクトリをそのまま削除する手順にはしません。
inodeの増加傾向と残量を、別々の警告条件で見る
NodeFilesystemFilesFillingUp は将来の枯渇予測を含む警告です。現行のnode_exporter mixinの定義では、predict_linear に加えて空き率や読み取り専用状態なども条件に入っています。67%という使用率だけで発報した、と読むのは正確ではありません。
同じ定義には固定閾値の NodeFilesystemAlmostOutOfFiles もあり、空き5%未満と3%未満のルールが含まれます。したがって、最初にすることは稼働中のルールの確認です。固定閾値の警告が存在しても、kubeletの退避より十分早く行動できる設定かは別に判断します。
残量を見る基本式は、次のように書けます。これはnode_exporterがルートを mountpoint="/" として公開し、inode総数が正のファイルシステムを対象にする例です。
1 - (
node_filesystem_files_free{mountpoint="/"}
/ node_filesystem_files{mountpoint="/"}
)
結果の0.80は使用率80%です。予測警告と組み合わせ、対応に必要な時間を確保できる使用率と継続時間を選びます。80%を共通の正解にはせず、別ディスクのimagefsならそのmountpointも対象にします。増加が止まって予測が変わっても、残量が少ない状態は別の条件で追えるようにする設計です。
実行用イメージのファイル数と、未使用イメージの保持を見直す
消費元がビルド用の依存関係なら、次はイメージの作り方です。Dockerのマルチステージビルドでは、ビルド段階と実行段階を分け、必要な成果物だけを COPY --from で渡せます。静的ファイルとして配信できるアプリなら、実行用イメージへビルドツールや依存ツリーを丸ごと持ち込まずに済みます。
サーバ側でNode.jsを動かすアプリでは、実行に必要な依存関係まで消さないようにします。また、.dockerignore でローカルの node_modules などをビルドコンテキストから除外すると、COPY . . による意図しない持ち込みを防げます。改善は圧縮サイズだけでなく、展開後のファイル数と、同じ条件でデプロイしたノードのinode増分で評価したいですね。
既に保持しているイメージには、別の時間軸があります。補足すると、kubeletにはディスク使用率と独立して未使用期間で回収する imageMaximumGCAge もあります。既定値は 0s で無効です。有効化を検討するなら、GCの公式説明にある、kubelet再起動で使用履歴に基づく経過時間の追跡がリセットされる点も踏まえます。これはinode残量を見て動く機能ではなく、保持期間を調整する選択肢です。
「空き容量があるから、kubeletの掃除を待てばよい」とは判断できません。実際の保存先でinodeを測り、退避より前に行動できる警告を設け、次のデプロイで持ち込むファイルを減らす。このつながりを作ると、ノードが最後に守ってくれることへ頼る運用から、原因に手を入れる運用へ進めます。
出典
- Title: Kubelet watches inodes. Just not until it’s an emergency.
- URL: https://www.cncf.io/blog/2026/10/05/kubelet-watches-inodes-just-not-until-its-an-emergency/
Share
Related Articles
カテゴリやタグが近い記事を続けて読めるように並べています。




