Kubernetesディストリビューション — 自分で立てる
k0s.yaml を直して再起動までしたのに何も起きなかった
このラボは本物の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つで設定すると知られているため、動的構成を有効にしたクラスターでも、人はファイルを直します。すると、再起動までしても何も変わらず、エラーも出ません。逆に静的構成では、ファイルを直したノードが再起動される日に、突然設定が変わります。どちらの場合も、「コマンドが成功した」ではなく、実際に何ができたかを見て初めてわかります。
ステップ
- デフォルト値とこのVMの設定を比較して保存してください(保存先:
/root/k0scfg/defaults.yaml、/root/k0scfg/defaults.json)。 k0s sysinfoの結果を残してください(保存先:/root/k0scfg/sysinfo.json、/root/k0scfg/sysinfo-summary.txt)。- 静的構成でファイルにワーカープロファイル
edge-smallを入れ、再起動なしでは反映されないことを記録してください(記録先:/root/k0scfg/static-edit.json)。 - k0sを再起動してプロファイルのConfigMapができることを記録してください(記録先:
/root/k0scfg/static-restart.json)。 - 動的構成に切り替えて、ClusterConfigオブジェクトを記録してください(記録先:
/root/k0scfg/dynamic.json)。 - 動的構成でファイルにプロファイル
from-fileを入れて再起動した結果を記録してください(記録先:/root/k0scfg/file-ignored.json)。 - ClusterConfigにプロファイル
from-apiを追加して、再起動なしで反映されることを記録してください(記録先:/root/k0scfg/api-patch.json)。 - ClusterConfigにpodinfoチャートを宣言して、ファイルを書いてください(書き込み先:
/root/k0scfg/helm.json)。 - チャートの宣言を削除した結果と(書き込み先:
/root/k0scfg/removal.json)、まとめを書いてください(書き込み先:/root/k0scfg/report.md)。
参考
- ワーカープロファイルのConfigMapの名前は
worker-config-<프로필>-1.<마이너>です(プレースホルダーはプロファイル名とマイナーバージョンです。このVMは1.36)。プロファイルの値は、kubeletConfigurationのデータの中にJSONとして入ります。 - 再起動は、
k0s stopのあとk0s startです。その後、APIが応答するまで待ってください。サービス名はk0scontrollerです。 - すでにインストールされているサービスの実行引数を変更するには、
k0s install controllerを、同じ引数に新しいフラグを加えて--forceでもう一度実行します。--enable-worker --no-taints -c /etc/k0s/k0s.yamlを抜かすと、ワーカーがなくなります。 - チャートは、
https://stefanprodan.github.io/podinfoリポジトリのpodinfo6.14.1です。イメージはghcr.ioにあるので、取得制限にかかりません。 - よくあるミス1: ステップ3で再起動から行うこと。採点ツールは、記録がConfigMapができる前に書かれたかどうかを確認します。
- よくあるミス2: ステップ7でmerge patchを使って
workerProfilesを丸ごと上書きし、edge-smallを消すこと。リストのフィールドは、merge patchが置き換えます。ステップ4の再採点が不合格になります。
書かなかった値は何になるのか
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範囲を信じてよいかを入れてください。