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

Kubernetesディストリビューション — 自分で立てる

k0s.yaml を直して再起動までしたのに何も起きなかった

TT Labで続きを見る

このラボは本物のk0sで動きます

VMの中にk0s v1.36.4+k0s.0が1台(コントローラー兼ワーカー)、静的構成で起動しています。設定ファイルは/etc/k0s/k0s.yaml、作業ディレクトリは/root/k0scfgです。最初の起動には3分前後かかります。ラボの途中で、k0sを3回再起動します。

目標

k0sの設定がどこから来るかを、モードごとに確認します。静的構成ではファイルの変更が再起動して初めて反映され、動的構成ではファイルの代わりにClusterConfigオブジェクトが反映されることを、ワーカープロファイルのConfigMapで示します。Helm拡張を宣言して削除し、Chartオブジェクトとリリースがどう追従するかを記録します。

なぜ重要なのか

k0sはファイル1つで設定すると知られているため、動的構成を有効にしたクラスターでも、人はファイルを直します。すると、再起動までしても何も変わらず、エラーも出ません。逆に静的構成では、ファイルを直したノードが再起動される日に、突然設定が変わります。どちらの場合も、「コマンドが成功した」ではなく、実際に何ができたかを見て初めてわかります。

ステップ

  1. デフォルト値とこのVMの設定を比較して保存してください(保存先: /root/k0scfg/defaults.yaml、/root/k0scfg/defaults.json)。
  2. k0s sysinfoの結果を残してください(保存先: /root/k0scfg/sysinfo.json、/root/k0scfg/sysinfo-summary.txt)。
  3. 静的構成でファイルにワーカープロファイルedge-smallを入れ、再起動なしでは反映されないことを記録してください(記録先: /root/k0scfg/static-edit.json)。
  4. k0sを再起動してプロファイルのConfigMapができることを記録してください(記録先: /root/k0scfg/static-restart.json)。
  5. 動的構成に切り替えて、ClusterConfigオブジェクトを記録してください(記録先: /root/k0scfg/dynamic.json)。
  6. 動的構成でファイルにプロファイルfrom-fileを入れて再起動した結果を記録してください(記録先: /root/k0scfg/file-ignored.json)。
  7. ClusterConfigにプロファイルfrom-apiを追加して、再起動なしで反映されることを記録してください(記録先: /root/k0scfg/api-patch.json)。
  8. ClusterConfigにpodinfoチャートを宣言して、ファイルを書いてください(書き込み先: /root/k0scfg/helm.json)。
  9. チャートの宣言を削除した結果と(書き込み先: /root/k0scfg/removal.json)、まとめを書いてください(書き込み先: /root/k0scfg/report.md)。

参考

書かなかった値は何になるのか

k0s config createの出力を保存し(保存先: /root/k0scfg/defaults.yaml)、次のキーを書いてください(書き込み先: /root/k0scfg/defaults.json)。default_pod_cidr、default_service_cidr、default_storage_type、default_telemetry、file_pod_cidr、file_service_cidr、file_telemetry、apiserver_service_cidr、reason(CIDR範囲を変更した理由、30字以上)です。

デフォルト値は、インストールされたバイナリが教えてくれます。ファイルの値は/etc/k0s/k0s.yamlに、実際のAPIサーバーが使っているServiceのCIDR範囲は、kube-apiserverプロセスの引数のservice-cluster-ip-rangeにあります。このVMがどこで動いているかを考えると、CIDR範囲を変更した理由がわかります。

インストール前の点検を読み取る

k0s sysinfo -o jsonの結果を保存し(保存先: /root/k0scfg/sysinfo.json)、次の行を書いてください(書き込み先: /root/k0scfg/sysinfo-summary.txt)。total=<항목 수>(プレースホルダーは項目数です)、結果の分類ごとに<분류>=<수>(プレースホルダーは分類と数です。例: pass=)、cgroups=<Control Groups 항목의 값>(プレースホルダーはControl Groups項目の値です)の行と、passではない項目ごとにnot_pass=<displayName>の行です。

JSONは項目の配列で、各項目にcategory・displayName・propがあります。分類ごとに数えて、passではないものの名前を書き写してください。採点ツールは、sysinfoをもう一度実行して、同じ数になるかを確認します。

ファイルを直したのに何も起きない

/etc/k0s/k0s.yamlのspecにワーカープロファイルedge-small(maxPods: 40)を入れてk0s config validateで確認してから、再起動せずに30秒以上待ち、次のキーを書いてください(書き込み先: /root/k0scfg/static-edit.json)。profile、configmap(できるはずのConfigMapの名前)、configmap_present、k0s_pid(k0scontrollerサービスのMainPID)です。

ワーカープロファイルは、spec.workerProfilesリストのnameとvaluesです。k0sがファイルを監視しているなら、待っている間にkube-systemにConfigMapができるはずです。PIDは、後で「その後に再起動があったか」を照合する値なので、systemctlから読み取ってください。

再起動したらできた

k0sを再起動し、edge-smallのConfigMapができたら、次のキーを書いてください(書き込み先: /root/k0scfg/static-restart.json)。configmap、configmap_uid、max_pods(ConfigMapのkubeletConfigurationから読み取った値)、k0s_pid_before、k0s_pid_afterです。

再起動は、k0s stopとstartです。APIが戻った後、ConfigMapができるまで少し待ってください。kubeletConfigurationは、ConfigMapのデータの中のJSON文字列です。再起動前のPIDは、ステップ3の記録にあります。

信頼できる情報源をAPIに移す

k0scontrollerサービスに--enable-dynamic-configを加えてインストールし直して起動してから、次のキーを書いてください(書き込み先: /root/k0scfg/dynamic.json)。clusterconfig_uid、object_has_edge_small、object_service_cidr(オブジェクトのspec.network.serviceCIDR)、apiserver_service_cidr(実際のAPIサーバーの引数)です。

すでにインストールされているサービスに、k0s install controllerをそのままもう一度実行すると、拒否されます。元の引数をすべて維持しないと、ワーカーがなくなります。動的構成が有効になると、kube-systemにclusterconfigリソースができます。オブジェクトのServiceのCIDR範囲と実際の値を、別々に読み取って比べてください。

今回は再起動しても無視される

動的構成で、/etc/k0s/k0s.yamlのワーカープロファイルのリストにfrom-file(maxPods: 30)を追加してk0sを再起動し、20秒以上待ってから、次のキーを書いてください(書き込み先: /root/k0scfg/file-ignored.json)。profile、generation_before、generation_after(ClusterConfigのmetadata.generation)、object_has_profile、configmap_presentです。

静的構成だったなら、再起動で反映されたはずの変更です。動的構成でファイルが何に使われるかは、理論の記事の「クラスター設定とノード設定は異なる」の節を見てください。generationは、オブジェクトのspecが変わるたびに上がります。

オブジェクトを直すとすぐに反映される

再起動せずに、ClusterConfigのワーカープロファイルのリストにfrom-api(maxPods: 60)を、既存のプロファイルを消さずに追加し、ConfigMapができたら、次のキーを書いてください(書き込み先: /root/k0scfg/api-patch.json)。profile、configmap_uid、max_pods、controller_started_at(k0scontrollerサービスが最後に起動した時刻、Unix秒)です。

merge patchは、リストのフィールドを丸ごと置き換えます。リストの末尾に1つ追加する方法は、JSON patchにあります。サービスの起動時刻は、systemctlのActiveEnterTimestampをdateで変換すればわかります。採点ツールは、ConfigMapがその時刻より後にできたかどうかを確認します。

宣言したチャートがChartオブジェクトになる

ClusterConfigのspec.extensions.helmに、リポジトリpodinfo(https://stefanprodan.github.io/podinfo)とチャートpodinfo(chartnameはpodinfo/podinfo、versionは6.14.1、namespaceはpodinfo)を宣言し、デプロイの準備ができたら、次のキーを書いてください(書き込み先: /root/k0scfg/helm.json)。chart_object(できたChartの名前)、chart_uid、chart_version(Chartのstatusのversion)、namespace_uid(podinfoネームスペースのUID)です。

k0sは、宣言をkube-systemのChartオブジェクトに変換します。その命名規則は、kubectl get chartsで確認してください。チャートのインストールが終わると、Chartのstatusにバージョンが入ります。ネームスペースのUIDは、次のステップで「何が残るか」を照合する値です。

宣言を削除すると何が残るのか

ClusterConfigから、podinfoのチャート宣言だけを削除し、次のキーを書いてください(書き込み先: /root/k0scfg/removal.json)。removed_chart_uid、chart_object_present、release_secrets(podinfoネームスペースのHelmリリースSecretの数)、namespace_keptです。そして、static_restart_needed=、dynamic_file_applied=、dynamic_object_applied=(3つともyes/no)、object_service_cidr=、apiserver_service_cidr=の5行と、150字以上の説明を書いてください(書き込み先: /root/k0scfg/report.md)。

チャートの一覧だけを削除して、リポジトリの宣言は残してもかまいません。Chartオブジェクトが消えるまでに数秒かかります。HelmのリリースSecretは、owner=helmラベルで探せます。説明には、どのモードで何が信頼できる情報源だったか、オブジェクトのServiceのCIDR範囲を信じてよいかを入れてください。