BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Kubernetesのデプロイに失敗する10の一般的理由

Kubernetesのデプロイに失敗する10の一般的理由

原文(投稿日:2017/02/27)へのリンク

先日公開された一連記事に、Kubernetesのデプロイが失敗する、一般的な10の理由が取り上げられていた。内容としてはミスや入力の誤りからリソース制限の超過にまで及んでいるが、そのほとんどの場合において、根本原因の特定には‘kubectrl describe’コマンドが有効だ。

Kubernetesデプロイメント時の入力誤りとして、存在しない、あるいは権限的な問題でアクセスできないコンテナイメージの指定がある。既定のレジストリはDockerhubなので、Amazon ECRやQuay.ioなど他のレジストリを使用する場合には、レジストリのURLを指定しなければならない。プライベートレジストリの場合は、イメージアクセス時の資格情報が必要だ。プルするタグ名が正しくない場合も、イメージのプルに失敗する。イメージにlatestタグ(何も指定しない場合、‘latest’がデフォルトのタグとなる)が存在しない場合、こういった状況が発生する可能性がある。ネットワークの障害も問題の原因となり得る。これらのケースでは同じようなエラーメッセージが出力されるため、正確な原因の特定には、より詳細な調査が必要になる。

Kubernetesにおけるデプロイの失敗は通常、 特定のPodが立ち上がらないという状態で現れる。その時には ‘kubectl describe pod <pod名>’ を実行すれば、エラーの原因を記述したイベントログが表示される。kubectlコマンドの引数には、‘pod’, ‘eplicaset’, ‘deployment’ が指定可能だ。これらコマンドと ‘kubectl logs <Pod名>’ の組み合わせは、デプロイ時のエラーをデバッグする上で重要な役割を持つ。

Kubernetesのデフォルトポリシが常にレジストリからプルしないように設定されていると、更新された変更がコミットされ、イメージがプッシュされた後でも、その内容を参照できない場合がある。運用上のアプローチとして推奨されるのは、各イメージにユニークなタグを使用して、プルリクエスト時にそれを指定する方法だ。デプロイメント設定で指定した永続ボリュームが存在しない場合にも、デプロイメントが失敗する可能性がある。

その他の不正な入力のケースとしては、“アプリケーション実行時のConfigMapあるいはSecretが存在しない”、“Specオブジェクトが無効” の2つがある。ConfigMapはアプリケーションに必要な設定データを指定したキーと値のペアのマップで、CLIの引数、環境変数、あるいはマウントされたボリューム内のファイルとして参照される。これが存在しない場合、Podの生成が停止して‘RunContainerError’状態がセットされる。一方のSecretは資格情報などの機密データを格納するメカニズムである。Secrentが存在しない場合も同じようなエラーとなる。ConfigMapとSecretは、いずれもボリュームとしてマウント可能だが、これに失敗すると、イベントログに‘ContainerCreating’が記録された状態でコンテナ生成が停止する。

YAML内でのインデントの間違いやタイプミスに起因する、無効なKubernetres Specオブジェクトの指定も障害の原因となる。このような問題はCLIベースのYAML検証や、あるいは次のように --dry-run フラグを指定することで容易に防止可能だ。

kubectl create -f test-application.deploy.yaml --dry-run --validate=true

この実行にはKubernetesクラスタが起動中であることが必要だが、そのような依存性を回避して、クライアント側でも検証を可能にする作業進行中である。このYAML検証は、ソース管理システムのコミット前フックの一部として追加することもできる。

Kubernetesのデプロイ失敗のもうひとつの部類は、リソース制限超過によるものだ。Podとコンテナにはそれぞれ、CPUおよびメモリ使用量の制限が設定されていて、これらの制限を超過するとPodの生成が行われない。この問題のデバッグにはかなりの調査時間が必要だが、‘kubectl describe deployment <デプロイメント名>’ を指定すれば、Kubernetesが作成を試みたレプリカセットの名称が確認できる。さらに‘kubectrl describe replicaset <replicaset name>’を実行すれば、以前のステップで適用されたレプリカセットの名称がプリントアウトされた上で、他のケースと同じようなイベントログがエラーメッセージを伴ってプリントアウトされる。

デプロイメントの失敗はリソースクオータ超過によっても発生する。リソースクオータは、ノード数の固定されたクラスタを複数チームが共有する場合に、名前空間毎のリソース消費を制限するためのメカニズムである。管理対象のリソースにはPodやサービス、デプロイメントの他、計算リソースの総量も含まれている。このケースにおいても‘kubectl describe’ コマンドは、実際のエラーメッセージの掘り下げに有効だ。

クラスタオートスケーラ(cluster autoscaler)では、ノードがリソースを十分に活用していない場合、あるいはリソース不足のためにPodが実行不可能な場合の両方において、Kubernetesクラスタサイズの自動調整を実行する。これが無効になっていると、割り当てられた以上のリソースを要求するデプロイメントは失敗し、Podのステータスは‘Pending’のままになる。実際に不足したリソースが何であるかはイベントログに表示される。

アプリケーション動作の予期しない変更は、さまざまな障害を引き起こす可能性がある。‘CrashLoopBackOff’メッセージを伴うローンチエラーは、一般的にアプリのクラッシュによって発生する。この問題の特定にはアプリケーションログが有効だ。Kubernetesがサービスの状態および起動状況の検出に使用しているLiveness/Readinessプローブについても、設定ミスやタイムアウトなどで失敗する可能性がある。アプリケーションのヘルスチェックURLが変更されたり、あるいはデータベースの変更によってアプリケーションが期待した動作を行なわない場合がそれに当たる。起動状態チェックに対するURLからの応答に時間がかかると、タイムアウトが発生してデプロイに失敗する場合もある。

本記事の筆者は、ビルド失敗時にKubernetesに関する有用な情報をビルトログに表示するスクリプトを、オープンソースとして公開している。

 
 

この記事を評価

関連性
スタイル
 
 

この記事に星をつける

おすすめ度
スタイル

BT