冒頭まとめ

FailedCreatePodSandbox は、kubelet が Pod の sandbox(ネットワーク名前空間や pause コンテナといった、コンテナ起動前の土台)を作成できなかったときに記録される警告イベントです。Pod は ContainerCreating のまま止まり、kubelet はリトライを繰り返します。

原因はほぼ次の3方向に分かれます。

  1. CNI プラグインまたは CNI 設定の不整合で、Pod のネットワーク設定(IP 割り当てを含む)に失敗している
  2. container runtime が sandbox image(pause image)を取得・起動できず、sandbox コンテナを作れない
  3. ノード側の状態(ディスク、iptables/sysctl、カーネルモジュール、runtime プロセス)が壊れている

調査の出発点は「イベント本文の desc = 以降に書かれた、container runtime から返った実メッセージ」です。ここに cni / network / image / no space left on device のどの語が出ているかで、上の1〜3のどれを追うべきかがほぼ決まります。次に「1ノードだけの問題か、クラスタ全体か」を確認すると、ノード修復かクラスタ設定修正かの判断が付きます。

エラーの概要

これは HTTP ステータスではなく kubelet のイベント理由です

FailedCreatePodSandboxエラーコードではなく、kubelet が Pod に対して発行する Event の reason です。kubectl describe pod の Events 欄や kubectl get events に現れます。

実際にクラスタ上で出力される文字列は FailedCreatePodSandBoxBox の B が大文字) です。ログイベント検索するときは大文字小文字を区別しない検索grep -i)を使うと取りこぼしが減ります。

sandbox とは何か

Kubernetes の Pod は、内部のコンテナネットワーク名前空間などを共有する単位です。CRI(Container Runtime Interface)では、この共有される土台を「Pod sandbox」と呼びます。kubelet が Pod を起動する流れは、おおむね次の順序です。

  1. kubelet が CRI の RunPodSandbox を container runtime に要求する
  2. container runtime が sandbox image をもとに sandbox コンテナ(一般に pause コンテナ)を作り、名前空間を用意する
  3. container runtime が CNI プラグインを呼び出し、Pod にネットワークIP アドレスやルート)を設定する
  4. 成功後、init コンテナとアプリコンテナのイメージ取得・作成に進む

FailedCreatePodSandBox は、この1〜3のどこかで失敗した場合に出ます。アプリコンテナのイメージコマンドはまだ関係しません。 ここを押さえると、Deployment のマニフェストばかり見直して時間を失う事故を避けられます。

近い事象との違い

事象失敗している段階主な調査先
FailedCreatePodSandBoxsandbox 作成(名前空間・CNI・pause)ノードの kubelet / runtime / CNI
ErrImagePull / ImagePullBackOffアプリコンテナのイメージ取得レジストリ疎通、imagePullSecrets
CreateContainerConfigErrorsandbox 後のコンテナ設定参照している ConfigMap / Secret
CreateContainerErrorsandbox 後のコンテナ作成runtime、マウント、リソース設定
FailedScheduling(Pending)ノードへの割り当て前スケジューラ、リソース、taint
FailedMountボリュームのマウントCSI ドライバ、PV/PVC
CrashLoopBackOffコンテナ起動後アプリケーションログ

この記事が扱うのは1行目、つまり「sandbox が作れない」段階に限定します。sandbox 作成後に発生する CreateContainerError 系や、アプリイメージの pull 失敗は範囲外です。イベントreason を先に確定させてから読み進めてください。

エラーメッセージの読み方

イベントは典型的に次の構造で出力されます(<...>環境ごとに変わる部分です)。

Warning  FailedCreatePodSandBox  <経過時間>  kubelet  Failed to create pod sandbox: rpc error: code = <gRPC コード> desc = <container runtime が返した実メッセージ>

読み方は3層に分けて考えます。

  1. Failed to create pod sandbox:失敗した段階。sandbox 作成であることの確認。
  2. rpc error: code = ... desc = ...:kubelet から container runtime への CRI(gRPC)呼び出しが失敗したという枠。codegRPC のステータスで、原因の特定にはあまり使えません。
  3. desc = 以降:container runtime が返した実メッセージ。ここが唯一の手がかりです。

desc 以降に含まれる語から、追うべき方向を判断します。

メッセージに含まれる語の傾向疑う対象この記事の該当箇所
cnipluginnetwork for sandbox、IPAM やアドレス枯渇を示す表現CNI プラグイン・CNI 設定・IP 管理原因1
cni config uninitializedNetworkPluginNotReadyCNI 設定がランタイムに読み込まれていない原因1
sandbox image や pull、認証、名前解決に関する表現pause image の取得原因2
runtime のソケット、cgroup、runtime 起動に関する表現container runtime 本体原因2
no space left on device、inode やファイル作成の失敗ノードのディスク・資源原因3

なお、同じ Pod で同種のイベントが大量に出ると、kubelet は「類似イベントをまとめた」形(発生回数付き)で1行に集約して出力します。回数と経過時間が大きい場合は、恒久的な設定不備である可能性が高くなります。

イベント自体は API サーバー設定に従って一定時間で削除されるため、古い障害を後追いする場合はイベントではなくノードのログ(後述)を確認してください。

原因と解決策

解決策の早見表

原因主な確認主な対処
CNI 設定・プラグインの不整合CNI アドオンの Pod 状態、CNI 設定ディレクトリとバイナリ、ノードの NetworkUnavailableアドオンの公式手順どおりに再適用、ノード上の CNI 設定・バイナリの整合を回復
IP アドレスの枯渇・IPAM の不整合アドオン側の IPAM 状態、Pod CIDR 設定の一致不要な Pod や滞留 sandbox の整理、CIDR 設計の見直し
pause image を取得できないランタイム設定上の sandbox image 名、レジストリ疎通、認証ランタイム設定修正プライベートレジストリへのミラー設定
container runtime の異常systemctl status、runtime のログcrictl inforuntime の復旧、設定不整合(cgroup ドライバ等)の修正
ノードのディスク・inode 枯渇df -h / df -i、ノードの DiskPressure不要イメージログ削除、容量拡張
ネットワーク前提条件の欠落カーネルモジュールと sysctl、iptables のバックエンド公式ドキュメントの前提条件どおりに設定

原因1:CNI プラグインまたは CNI 設定の不整合

sandbox のネットワーク設定は container runtime が CNI プラグインを呼び出して行います。ここが成立しないと、pause コンテナまで作れていても sandbox 作成全体が失敗として扱われます。よくあるパターンは次のとおりです。

  • クラスタ構築直後にネットワークアドオンを適用していない:kubeadm などで構築した直後は CNI 設定が存在せず、kubelet は「ネットワークプラグインが未初期化」であることを示すメッセージとともに Pod を起動できません。ノードの Ready 条件のメッセージにも NetworkPluginNotReady 相当の記述が出ます。この症状は公式リポジトリの Issue でも繰り返し報告されています(kubernetes/kubernetes#48798kubernetes/kubeadm#1031)。
  • アドオンの DaemonSet が該当ノードで動いていない:ノード追加直後、taint、イメージ取得失敗などでアドオンの Pod が起動せず、そのノードだけ CNI 設定が配置されないケースです。
  • CNI 設定ファイルが壊れている・複数あって意図しないものが選ばれている設定ディレクトリ内のファイルは名前順で評価されるため、旧アドオンの設定が残っていると意図しないプラグインが使われます。アドオンを入れ替えた際に起きやすい失敗です。
  • CNI プラグインのバイナリが無い、実行できない:ノードの初期化方法を変えた、イメージを作り直した、ディスクを入れ替えたといった変更の直後に起きます。
  • IP アドレスの枯渇や IPAM 情報の不整合:ノードに割り当てられた Pod 用アドレス範囲を使い切ると、新しい sandbox に IP を割り当てられません。削除しきれなかった sandbox が IP を保持し続けている場合もあります。

対処の流れ

# 1. ネットワークアドオンが該当ノードで動いているか
kubectl get pods -A -o wide | grep -i -E 'cni|calico|cilium|flannel|weave|antrea'

# 2. ノード側の条件を確認(NetworkUnavailable / Ready の message)
kubectl describe node <your-node-name> | sed -n '/Conditions:/,/Addresses:/p'

# 3. ノードにログインし、ランタイムが認識している CNI 設定を確認
sudo crictl info | grep -i -A20 cni

CNI 設定ディレクトリやバイナリディレクトリの場所は container runtime の設定で決まります。既定値を推測せず、crictl info の出力やランタイムの設定ファイルで実際のパスを確認してください。

修復手順(設定ファイルの内容、Pod CIDR の指定方法、必要な RBAC など)はアドオンごとに大きく異なります。使用しているアドオンの公式ドキュメントに従ってください。Pod CIDR は kubeadm 側の指定とアドオン側の設定が一致している必要があるため、両方を照合します。

原因2:pause image または container runtime が sandbox コンテナを作れない

container runtime は sandbox コンテナを起動するために sandbox image(pause image)を必要とします。この取得や起動に失敗すると、CNI が正常でも sandbox は作れません。

  • エアギャップ環境・制限されたネットワークで pause image を取得できない:ノードから公開レジストリへ到達できない、プロキシ設定が runtime に反映されていない、DNS が引けない、といった状況です。
  • ランタイム設定の sandbox image 指定が誤っている:存在しないタグ、到達できないミラー、アーキテクチャの異なるイメージを指定している場合です。
  • プライベートレジストリ認証:sandbox image の取得は container runtime 自身の設定と認証情報で行われるため、Pod の imagePullSecrets を追加しても解決しない場合があります。ランタイム側のレジストリ認証設定を公式ドキュメントで確認してください。
  • container runtime 本体の異常プロセスが停止している、CRI ソケットが応答しない、設定変更後に再起動していない、cgroup ドライバ設定が kubelet と食い違っている、といった状態です。

確認方法

# ランタイムの稼働状況とログ
sudo systemctl status containerd   # CRI-O の場合は crio
sudo journalctl -u containerd --since "15 min ago" --no-pager | grep -i -E 'sandbox|image|cni'

# ランタイムが保持しているイメージ一覧(pause を確認)
sudo crictl images | grep -i pause

設定されている sandbox image 名は、推測せずランタイムの実効設定から読み取ります。containerd と CRI-O では設定キー名が異なり、containerd はメジャーバージョンによっても書き方が変わるため、実効設定のダンプ出力を確認するのが確実です。

# containerd:実効設定から sandbox / pause 関連の項目を探す
sudo containerd config dump | grep -i -E 'sandbox|pause|pinned'

# 取得可否そのものを試す(<your-sandbox-image> は上で確認した値)
sudo crictl pull <your-sandbox-image>

crictl pull が失敗するなら、原因はレジストリ疎通か認証設定値です。成功するのに sandbox が作れないなら、CNI(原因1)かノード状態(原因3)を疑います。cgroup ドライバやランタイムの前提設定については、Kubernetes 公式ドキュメントの「Container Runtimes」に記載された手順を基準にしてください。

原因3:ノード側の状態(ディスク・iptables・sysctl・カーネル)

kubelet と container runtime はノードの OS 機能に強く依存します。ノード側が壊れていると、マニフェストが正しくても sandbox は作れません。

  • ディスクや inode の枯渇no space left on device を含むメッセージで sandbox 作成が失敗する事例は、クラウド提供元のトラブルシューティング文書でも紹介されています(例:Tencent Cloud TKE のドキュメント)。ランタイムのデータディレクトリ、/var/log/var/lib/kubelet を個別に確認します。
  • ネットワーク前提条件の欠落:ノードで必要なカーネルモジュールや sysctl(IP 転送やブリッジ関連の設定)が有効でないと、Pod ネットワーク設定に失敗します。必要な項目は Kubernetes 公式ドキュメントの「Container Runtimes」に前提条件として明記されているので、その一覧と実機の状態を照合してください。
  • iptables/nftables の不整合:ホストの iptables がどのバックエンド(legacy / nft)で動いているかが、CNI やサービスプロキシの想定と食い違うと、ルール適用が失敗したり無効化されたりします。ノード再作成やディストリビューション更新の後に起きやすい問題です。
  • プロセス・ファイルディスクリプタ・PID の上限:ノードが高負荷のときに sandbox 作成だけが失敗することがあります。カーネルログ(dmesg)に該当メッセージが出ていないか確認します。
  • RuntimeClass の指定:Pod が指定した runtimeClassName に対応する handler がノードの runtime 側に設定されていないと、Pod は起動できません。特定の Pod だけが失敗する場合は、この可能性を確認してください(設定名や必要な runtime 側の定義は公式の RuntimeClass ドキュメントを参照)。

確認コマンド

# 容量と inode
df -h /var/lib/kubelet /var/log
df -h $(sudo crictl info | grep -i -m1 root | awk -F'"' '{print $4}') 2>/dev/null
df -i /var

# ネットワーク前提の状態(公式ドキュメントの前提条件と照合する)
lsmod | grep -E 'br_netfilter|overlay'
sysctl net.ipv4.ip_forward net.bridge.bridge-nf-call-iptables

# iptables のバックエンド
iptables -V

# カーネル側のエラー
sudo dmesg -T | tail -50

不要イメージの整理など、削除を伴う対処を行うときは、先に対象ノードを kubectl cordon(必要に応じて kubectl drain)して影響範囲を限定してください。iptables -F の実行やランタイムのデータディレクトリの削除は、クラスタ全体の通信断や復旧困難な状態を招く可能性があるため、主たる解決策としては採りません。

確認・切り分け手順

上から順に実施すると、原因が3方向のどれかに収束します。

手順1:イベント全文を取得する

kubectl describe pod <your-pod-name> -n <your-namespace>

# 名前空間内のイベントを時系列で見る
kubectl get events -n <your-namespace> --sort-by=.lastTimestamp

# 該当イベントだけを全名前空間から抽出する
kubectl get events -A --field-selector type=Warning,reason=FailedCreatePodSandBox

desc = 以降を必ず全文で記録します。ここが後続すべての判断材料になります。

手順2:影響範囲を切り分ける

# 止まっている Pod がどのノードに偏っているか
kubectl get pods -A -o wide | grep -E 'ContainerCreating|Init:'

# ノードの状態
kubectl get nodes -o wide
kubectl describe node <your-node-name>
  • 特定ノードに集中:そのノードの runtime・CNI・資源(原因2、原因3)を追います。
  • クラスタ全体:ネットワークアドオン、クラスタ共通設定、レジストリ疎通(原因1、原因2)を追います。
  • 特定 Pod だけhostNetworkhostPort の競合、runtimeClassName、Pod 単位の設定を確認します。

手順3:ノードの kubelet ログを読む

sudo journalctl -u kubelet --since "30 min ago" --no-pager | grep -i -E 'sandbox|cni|network'

イベントは要約されているため、失敗の直前後に出ているログ行を見ると、どのコンポーネントが返したエラーかが明確になります。

手順4:container runtime 側を確認する

sudo journalctl -u containerd --since "30 min ago" --no-pager | grep -i -E 'sandbox|cni|image'
sudo crictl info
sudo crictl pods

crictl info の出力にはランタイムの状態(RuntimeReady / NetworkReady に相当する条件)と CNI 設定の読み込み状況が含まれます。NetworkReady が false なら原因1、ランタイム自体が応答しないなら原因2に進みます。crictl の使い方は Kubernetes 公式ドキュメントの「Debugging Kubernetes nodes with crictl」に説明があります。

手順5:仮説を1つずつ検証する

  • CNI を疑うなら:アドオン Pod の状態とログ、ノード上の CNI 設定・バイナリの存在を確認
  • pause image を疑うなら:crictl pull <your-sandbox-image> を実行
  • ノード状態を疑うなら:df -h / df -i / sysctl / lsmod / dmesg

手順6:解決を確認する

対処後、対象 Pod を作り直して観測します。

kubectl delete pod <your-pod-name> -n <your-namespace>
kubectl get pod -n <your-namespace> -w

期待される状態は、ContainerCreating を経て Running に到達し、kubectl describe pod の Events に新しい FailedCreatePodSandBox が出ないことです。Pod に IP が割り当てられていることも合わせて確認します。

kubectl get pod <your-pod-name> -n <your-namespace> -o wide

ノードを cordon していた場合は、復旧確認後に kubectl uncordon <your-node-name> で戻します。

それでも解決しない場合

次の情報をまとめると、原因の再検討や外部への問い合わせが進みます。

# 1. イベント(desc 全文を含む)
kubectl describe pod <your-pod-name> -n <your-namespace> > pod-describe.txt

# 2. ノードの状態
kubectl get nodes -o wide > nodes.txt
kubectl describe node <your-node-name> > node-describe.txt

# 3. kubelet と runtime のログ
sudo journalctl -u kubelet --since "1 hour ago" --no-pager > kubelet.log
sudo journalctl -u containerd --since "1 hour ago" --no-pager > runtime.log

# 4. ランタイムと CNI の状態
sudo crictl info > crictl-info.txt
sudo crictl pods > crictl-pods.txt

# 5. ノード資源
df -h > df.txt; df -i > df-inode.txt

問い合わせ先の選び方は次のとおりです。

  • CNI 由来のメッセージが出ている:使用しているネットワークアドオンの公式リポジトリ・ドキュメント
  • container runtime 由来のメッセージが出ている:containerd や CRI-O の公式リポジトリ・ドキュメント
  • kubelet や CRI の挙動そのものに疑問がある:kubernetes/kubernetes の Issue を検索し、同種の報告があるか確認する
  • マネージドサービス(クラウド提供の Kubernetes)を利用している:ノードイメージやネットワーク実装が提供元固有のため、提供元のサポート窓口が最短

報告時は、クラスタの構築方法(kubeadm、マネージドサービス、ディストリビューション)、使用しているネットワークアドオン、container runtime の種類、直前に行った変更(ノード追加、アップグレード、設定変更)を添えると切り分けが早くなります。ログを共有する際は、トークンや認証情報が含まれていないかを確認し、必要に応じて <your-token> のような形に置き換えてください。

Editor’s Note

このエラーはアプリコンテナの失敗ではなく、kubelet が sandbox を作る前段で止まる点が重要です。Kubernetes の Pod デバッグ手順はイベント確認を起点にしており(公式ドキュメント)、ネットワーク実装は CNI プラグインが担うため(Network Plugins)、現場では desc = 以降の文言から CNI か runtime かを先に分けるのが有効です。


免責事項:本記事の内容は、執筆時点の公開情報をもとに作成したものです。ソフトウェアの仕様は予告なく変更されることがあります。最新の情報は各ツールの公式サポートページをご確認ください。本記事の情報を利用した結果生じたいかなる損害についても、著者および運営者は責任を負いかねます。