TT Lab
はじめる
学ぶ 学習パス コース

CKA — Kubernetes管理者

ノードが複数になると変わること

TT Labで続きを見る

一言でいうと

ノードが複数になると、Kubernetesの問題は「Podが起動しない」から「どのノードの何が間違っているか」に変わります。その答えは、たいていkubectlではなく、そのノードの中にあります。

なぜ必要なのか

1台のクラスターで練習すると、ノードは背景のように見えます。ノード名が1つだけなので、スケジューリングも、ネットワークも、メンテナンスも、悩むことがありません。ところが、実際のクラスターは複数のノードで、CKAの実技も、複数のノードにsshで入って作業させます。ワーカーを参加させ、1つのノードを空にし、NotReadyのノードを復活させることは、すべてノードの中で起こることです。

どう動くのか

ノードのアドレス: kubeletは、自分のアドレスをノードオブジェクトのInternalIPとして登録し、APIサーバー・ほかのノード・CNIが、そのアドレスでこのノードを探しに来ます。アドレスを別に指定しないと、kubeletはデフォルトのルートが出ていくNICのアドレスを選びます。NICが1つのサーバーではそれで合っていますが、管理ネットワークとクラスターネットワークが分かれたサーバーでは、誤ったアドレスが登録されます。そのため、--node-ip(kubelet)、--apiserver-advertise-address(kubeadm)、--iface(Flannel)のように、同じ質問に、コンポーネントごとに別々に答える必要があります。このラボのVMは、最初のNICがすべて10.0.2.2なので、1か所でも抜けると、症状がすぐに現れます。

参加(join): kubeadm joinは、ブートストラップトークンでAPIサーバーに自分を紹介し、--discovery-token-ca-cert-hashで、そのAPIサーバーが本物かを確認したあと、kubeletが使う証明書を受け取って、/etc/kubernetes/kubelet.confを書きます。参加が終わると、kubeletがノードオブジェクトを作成し、CNI DaemonSetがそのノードでPodを起動してはじめて、Readyになります。

メンテナンス: kubectl cordonは、ノードにスケジュール禁止のマークを付けるだけです。kubectl drainは、それに加えて、Podをエビクトします。エビクションは、削除と違って、PodDisruptionBudgetを守ります。DaemonSetのPodは、エビクトしても同じノードに再び作られるので、--ignore-daemonsetsでスキップします。メンテナンスが終わると、uncordonで元に戻しますが、すでに移ったPodは戻ってきません。スケジューラーは、新しいPodを配置するときにだけ判断するからです。

kubeletはサービスです: コントロールプレーンのコンポーネントは、静的Podとして動きますが、その静的Podを起動するkubelet自身は、systemdが管理します。そのため、kubeletが死ぬと、そのノードの状態を報告する主体がなく、ノードがNotReadyになり、原因はsystemctl status kubeletとjournalctl -u kubeletにだけ残ります。ここで、active(今起動している)とenabled(起動時に有効になる)は、別の質問です。kubeadmは、参加するときにkubeletを直接起動しますが、enableはしてくれず、警告だけを残します。

このラボの環境が、実際と同じ点と異なる点

同じ点から見ます。3つのVMは、それぞれカーネル・systemd・containerdを持つ本物のサーバーで、ノード間のトラフィックは、本物のネットワークを通ります。FlannelのVXLANがUDP 8472で出ていき、APIサーバーは6443で、kubeletは10250で、互いを呼び出します。そのため、設定を1か所間違えると、症状が実際のクラスターとまったく同じように現れます。

異なる点は2つです。1つ目、eth1は実際のNICではなく、このセッションのVM同士だけがつながった、仮想のL2ネットワークです。外から見ると、VM間にUDP 4789だけが行き来し、ほかの受講生のVMには届きません。2つ目、3つのVMの最初のNICは、すべて10.0.2.2という同じアドレスを受け取ります。実際のサーバーでは珍しいことですが、おかげで、「アドレスを明示しないと何が選ばれるのか」が、曖昧にならず、はっきりと現れます。デフォルト値に頼る設定は、この環境では必ず失敗します。

現場での姿

オンプレミスのサーバーは、管理ネットワーク・ストレージネットワーク・サービスネットワークのNICを、別々に持つ場合がよくあります。ここにkubeadmをデフォルト値で導入すると、ノードが管理ネットワークのアドレスで登録され、Pod間の通信が、ストレージネットワークのスイッチを通ったり、そもそも届かなかったりします。ノードはすべてReadyに見えるので、ずいぶんあとになって気づきます。カーネルのパッチ適用後に再起動したノードが、戻ってこないこともよくあります。誰かが手でサービスを起動しただけでenableしておらず、その事実は、再起動まで何の症状も出ません。そのため、メンテナンス手順書には、「再起動後にReadyに戻るか確認」が、いつも最後の行に入ります。メンテナンスは、ノードを停止する瞬間ではなく、戻ってきたことを確認する瞬間に終わり、確認しない再起動は、次の障害を予約しておくのと同じです。

次のラボですること

3つのノードにsshで入ってNICを確認し、eth1のアドレスでコントロールプレーンを立ち上げたあと、Flannelにトンネル用のNICを教えます。ワーカー2台を参加させて、別のノードのPodに実際に届くかを確認したあと、node01を空にしてメンテナンスし、再起動後に戻ってこないnode02を、そのノードの中で復活させます。