Google Cloudとコンテナの継続的なセキュリティ
本文の内容は、2023年3月23にJAVIER MARTÍNEZ が投稿したブログ(https://sysdig.com/blog/kubernetes-createcontainerconfigerror-createcontainererror)を元に日本語に翻訳・再構成した内容となっております。
CreateContainerConfigErrorとCreateContainerErrorは、クラウドネイティブアプリケーションで見られる最も一般的なKubernetesエラーの2つです。
CreateContainerConfigErrorは、Pod内のコンテナに指定された構成が正しくないか、重要な部分が欠けている場合に発生するエラーです。
CreateContainerErrorは、コンテナ作成フローの後段で発生する問題です。Kubernetesは、Pod内のコンテナを作成しようとすると、このエラーを表示します。
この記事では、次のことを学びます:
新しいコンテナを開始するプロセスでは、Kubernetesはまずそのコンテナの設定を生成しようとします。実際、これはgenerateContainerConfigというメソッドを呼び出すことで内部的に処理され、取得を試みます:
上記の要素に問題があると、CreateContainerConfigErrorが発生します。
Kubernetesは、参照するボリュームにアクセスできない、コンテナ名がすでに使用されているなど、設定とは関係なく、コンテナの作成に問題がある場合にCreateContainerErrorを投げます。
CrashLoopBackOffのような他の問題と同様に、この記事では最も一般的な原因のみを取り上げていますが、現在のアプリケーションによって他にも多くの原因があります。
kubectl get podsを実行することで、両方のエラーを検出することができます:
NAME READY STATUS RESTARTS AGE
mypod 0/1 CreateContainerConfigError 0 11m
この出力からわかるように:
CreateContainerErrorとCreateContainerConfligErrorを理解するためには、まずコンテナ作成の正確なフローを知る必要があります。
Kubernetesは、新しいコンテナを開始する必要があるたびに、次のステップを踏んでいます:
ご覧のように、ステップ2とステップ4では、それぞれCreateContainerConfigとCreateContainerErorrが表示される可能性があるところです。
コンテナの作成とコンテナの起動の流れ
Kubernetes ConfigMapは、Podが使用する非機密情報をkey-valueペアとして保存するための重要な要素です。
PodでConfigMapの参照を追加すると、そこから特定のデータを取得するよう効果的に指示することになります。しかし、Podが存在しないConfigMapを参照した場合、KubernetesはCreateContainerConfigErrorを返します。
シークレットは、Kubernetesで機密情報を保存するための、より安全な方法です。しかし、これはbase64でエンコードされた生のデータであるため、実際には暗号化されておらず、難読化されているだけであることに注意してください。
Podに存在しないシークレットへの参照が含まれている場合、KubeletはCreateContainerConfigErrorを投げ、コンテナ設定を形成するために必要なデータを取得できなかったことを示します。
珍しいことですが、特定のコンテナ名がすでに使用されているため、競合が発生する場合があります。すべてのdockerコンテナには固有の名前が必要なので、元のコンテナを削除するか、新しく作成されるコンテナの名前を変更する必要があります。
コンテナ作成時のエラーの原因は様々かもしれませんが、コンテナの起動を妨げている問題のトラブルシューティングは、常に以下の方法に頼ることができます。
kubectl describe pod
を使用すると、影響を受けるPodとそのコンテナの詳細情報を取得することができます:
Containers:
mycontainer:
Container ID:
Image: nginx
Image ID:
Port: <none>
Host Port: <none>
State: Waiting
Reason: CreateContainerConfigError
Ready: False
Restart Count: 0
Limits:
cpu: 3
---
Volumes:
config:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: myconfigmap
Optional: false
Pod内のコンテナからログ情報を取得するには、 kubectl logs
を使用します。複数のコンテナを持つPodの場合は、 -all-containers
パラメーターを使用する必要があることに注意してください:
Error from server (BadRequest): container "mycontainer" in pod "mypod" is waiting to
start: CreateContainerConfigError
また、 kubectl get events
を実行すると、Pod で最近発生したすべてのイベントを取得することができます。describe podsコマンドは、最後に特定のイベントも表示することを忘れないでください。
CreateContainerConfigErrorのトラブルシューティングに使用するkubectlコマンドのターミナルウィンドウです。
Prometheus + kube-state-metricsを利用する場合、作成時や設定ステップでエラーが発生したコンテナを持つPodを素早く取得することができます:
kube_pod_container_status_waiting_reason{reason="CreateContainerConfigError"} > 0
kube_pod_container_status_waiting_reason{reason="CreateContainerError"} > 0
Pendingは、Podが起動すらできなかったときに表示されるPodステータスです。これはスケジュール時に発生するため、Kube-schedulerがリソースの不足や適切な taints/tolerations 設定でないためにノードを見つけることができなかったことに注意してください。
ContainerCreating は、実行中の問題 (例: コマンドが指定されていない) のためにコンテナを開始できなかった場合に発生する可能性がある、もう 1 つの待機状態の理由です。
Error from server (BadRequest): container "mycontainer" in pod "mypod" is waiting to
start: ContainerCreating
これは、CreateContainerErrorと同様の状況かもしれませんが、コンテナ作成ステップではなく、実行ステップで発生することに注意してください。
RunContainerErrorは、読み取り専用のボリュームに書き込もうとするなど、実行時に発生する問題を示している可能性が高いです。
CrashLoopBackOffは厳密にはエラーではなく、再試行の間に追加される待機時間の猶予期間であることを忘れないでください。
CrashLoopBackOffイベントとは異なり、CreateContainerErrorとCreateContainerConfigErrorは自動的に再試行されることはありません。
この記事では、CreateContainerConfigErrorとCreateContainerErrorの両方が、Kubernetesコンテナ作成プロセスにおける重要なメッセージであることを確認しました。これらを検出し、どの段階で発生しているのかを理解できることは、クラウドネイティブサービスの日々のデバッグに欠かせません。
また、Kubernetesコンテナ作成フローの内部動作や、各ステップで表示される可能性のあるエラーについて知っておくことも重要です。
最後に、CreateContainerConfigErrorとCreateContainerErrorは、他の異なるKubernetesのエラーと間違われるかもしれませんが、この2つはコンテナ作成段階で発生し、自動的に再試行されるわけではありません。
Sysdig MonitorのAdvisorを使用すると、KubernetesクラスターでCreateContainerConfigErrorまたはCreateContainerErrorの問題が発生しているコンテナを簡単に検出することができます。
Advisorは、ライブログ、パフォーマンスデータ、推奨される修復ステップにより、解決までの平均時間(MTTR)を短縮します。Kubernetesのトラブルシューティングのための簡単なボタンです!
30日間、無料でお試しいただけます!