Kubernetesを学ぶ:6段階ロードマップ
この記事にはアフィリエイト広告が含まれています。 冒頭まとめ Kubernetesのエラーを検索して1件ずつ直しているのに、翌日は別のエラーで止まる。この繰り返しから抜けるには、覚える順序を変える必要があります。 Kubernetesのエラーの多くは、4つの境界のどこかで起きています。宣言した状態と実際の状態の境界、コントロールプレーンとノードの境界、Podの内と外の境界、そしてPodの寿命とデータの寿命の境界です。エラー文やイベントはこの境界のどれで止まったかを示していますが、境界の存在を知らないと文言が読めません。 Dockerとの最大の違いはここにあります。Dockerでは実行した命令がそのまま結果になりますが、Kubernetesでは「こうあってほしい」という宣言を出し、それを実現しようとする過程が延々と続きます。したがってエラーは、失敗した瞬間ではなく、実現できないまま繰り返している状態として現れます。 学ぶ順序は、Podとコンテナ、Deploymentと宣言、Serviceとネットワーク、設定とデータ、スケジューリングとリソース、ログとトラブルシューティングの6段階です。各段階には「次へ進む目安」を置きました。飛ばした段階は、後の段階のエラーとして別の顔で現れます。 個別に直すだけでは理解しにくい理由 検索で見つかる対処は、多くの場合その環境で有効だった手順です。なぜ有効だったかは書かれていないことがあります。 たとえば、Podが起動しないときに kubectl delete pod を実行したら直った、という手順があります。Deploymentの管理下にあるPodは削除すると作り直されるので、一時的な不具合であれば確かに解消します。しかし原因がマニフェストの側にあれば、作り直されたPodも同じ理由で止まります。Podが誰に管理されているかを知らないと、この区別ができません。 同じことがネットワークでも起きます。Serviceの port と targetPort を同じ値に揃えたら繋がった、という手順は、どちらがService側でどちらがコンテナ側かを知らなければ再現できません。 エラー文とイベントも同じです。Kubernetesの表示は、どの部品が判断したのかを示しています。スケジューラが置き場所を決められないのか、kubeletがイメージを取得できないのか、コンテナの中のプロセスが落ちているのかで、直す場所が変わります。この区別は、次に説明する全体像を知っていれば読み取れます。 最初に理解するべきKubernetesの全体像 先に部品の関係を押さえます。ここを飛ばすと、後のすべての段階で判断がぶれます。 公式ドキュメントによれば、Kubernetesクラスターはコントロールプレーンと1つ以上のワーカーノードで構成されます。コントロールプレーン側には、KubernetesのHTTP APIを公開する中核サーバーである kube-apiserver、APIサーバーの全データを保持するキーバリューストアの etcd、まだノードに割り当てられていないPodを探して適切なノードへ割り当てる kube-scheduler、APIの振る舞いを実装するコントローラーを動かす kube-controller-manager があります。ノード側には、Podとそのコンテナが動いていることを保証する kubelet、Serviceを実装するネットワーク規則を維持する kube-proxy、コンテナの実行を担うコンテナランタイムがあります(Cluster Architecture)。 この構造から、エラーの読み分けが決まります。kubectl はAPIサーバーへ要求を送るだけの道具です。マニフェストを適用した時点で成功と表示されても、それは「宣言が受け付けられた」という意味であり、動き出したという意味ではありません。実際に動くかどうかは、その後にスケジューラとkubeletが決めます。 したがってKubernetesの調査は、常に2段構えになります。宣言は正しく登録されたか。そしてその宣言を実現しようとした過程のどこで止まったか。前者は kubectl get で、後者は kubectl describe のイベント欄で確認します。 まずは手元の環境が動いているかを確認してください。 kubectl cluster-info kubectl get nodes ノードが Ready でなければ、この先のPodはどれも起動しません。この時点で次へ進んでも、以降のコマンドはすべて同じ理由で止まります。 学習ステップ1:Podとコンテナ 何を理解する段階か:Podが何の単位なのか、そしてコンテナとどう違うのかです。 なぜエラー解決に必要か:Kubernetesのエラーの大半はPod単位で現れます。Podの状態欄とコンテナの状態欄が別々にあることを知らないと、どちらの情報を読んでいるのか分からなくなります。 最低限覚える概念:公式ドキュメントによれば、PodはKubernetesで作成・管理できる最小のデプロイ単位で、1つ以上のコンテナのグループです。ストレージとネットワークの資源を共有し、コンテナをどう動かすかの仕様を持ちます。Podの中身は常に同じ場所に配置され、同時にスケジュールされ、共有された文脈で動きます(Pods)。 つまりPodは、複数のコンテナをまとめて1台の論理的なホストのように扱う入れ物です。同じPodの中のコンテナは同じネットワーク名前空間を共有するため、互いに localhost で通信できます。別のPodには届きません。 実際に試すコマンド: # Pod を一覧する kubectl get pods # 状態とノードと再起動回数まで表示する kubectl get pods -o wide # Pod の詳細とイベントを確認する(最も重要) kubectl describe pod <Pod名> # Pod 内のコンテナでコマンドを実行する kubectl exec -it <Pod名> -- sh # 複数コンテナがある場合はコンテナを指定する kubectl exec -it <Pod名> -c <コンテナ名> -- sh kubectl describe の出力は上半分が宣言された内容、下半分の Events が実現しようとした過程です。エラーの理由はほぼ常に下半分にあります。 ...