TT Lab
开始
学习 学习路径 课程

Kubernetes 发行版 — 自己搭

改了 k0s.yaml 还重启了,结果什么都没发生

在 TT Lab 中继续学习

本实验在真正的 k0s 中运行

VM 中有一台以静态配置运行的 k0s v1.36.4+k0s.0(兼任控制器和工作节点)。配置文件为 /etc/k0s/k0s.yaml,工作目录为 /root/k0scfg。首次启动大约需要 3 分钟。实验过程中会重启 k0s 三次。

目标

按模式确认 k0s 的配置来自哪里。通过 worker profile ConfigMap 展示:在静态配置下,文件的修改要重启才生效;在动态配置下,生效的是 ClusterConfig 对象而不是文件。声明并删除 Helm 扩展,记录 Chart 对象和 release 会如何随之变化。

为什么重要

人们都知道 k0s 用一个文件进行配置,所以即使在打开了动态配置的集群中,也仍然有人去修改文件。这样一来,即使重启也什么都不会改变,也不会报错。反过来,在静态配置下,被修改了文件的那个节点重启的那天,配置会突然发生变化。无论哪种情况,都不能只看“命令执行成功”,而必须看到实际产生了什么,才能知道结果。

步骤

  1. 比较默认值与这台 VM 的配置,保存到 /root/k0scfg/defaults.yaml 和 /root/k0scfg/defaults.json。
  2. 把 k0s sysinfo 的结果保存到 /root/k0scfg/sysinfo.json 和 /root/k0scfg/sysinfo-summary.txt。
  3. 在静态配置下把 worker profile edge-small 写进文件,并把不重启就不会生效的情况记录到 /root/k0scfg/static-edit.json。
  4. 重启 k0s,把 profile ConfigMap 出现的情况记录到 /root/k0scfg/static-restart.json。
  5. 切换为动态配置,把 ClusterConfig 对象记录到 /root/k0scfg/dynamic.json。
  6. 在动态配置下把 profile from-file 写进文件并重启,把结果记录到 /root/k0scfg/file-ignored.json。
  7. 向 ClusterConfig 中添加 profile from-api,把不重启就生效的情况记录到 /root/k0scfg/api-patch.json。
  8. 在 ClusterConfig 中声明 podinfo Chart,并写入 /root/k0scfg/helm.json。
  9. 把删除 Chart 声明的结果写入 /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(修改网段的原因,30 个字符以上)这些键。

默认值由已安装的二进制文件告诉你。文件中的值在 /etc/k0s/k0s.yaml 里,实际 API 服务器所用的 Service 网段在 kube-apiserver 进程参数的 service-cluster-ip-range 中。想一想这台 VM 运行在哪里,就能得出修改网段的原因。

读取安装前检查

把 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 中加入 worker profile edge-small(maxPods: 40),用 k0s config validate 确认之后,不要重启,等待 30 秒以上,然后在 /root/k0scfg/static-edit.json 中写入 profile、configmap(应该出现的 ConfigMap 名称)、configmap_present、k0s_pid(k0scontroller 服务的 MainPID)这些键。

worker profile 是 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 再 k0s start。API 恢复之后,请稍等片刻,直到 ConfigMap 出现。kubeletConfiguration 是 ConfigMap 数据中的 JSON 字符串。重启前的 PID 在第 3 步的记录中。

把事实来源迁移到 API

加上 --enable-dynamic-config 重新安装并启动 k0scontroller 服务,然后在 /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 网段和实际值并进行比较。

这次即使重启也会被忽略

在动态配置下,向 /etc/k0s/k0s.yaml 的 worker profile 列表中加入 from-file(maxPods: 30)并重启 k0s,等待 20 秒以上,然后在 /root/k0scfg/file-ignored.json 中写入 profile、generation_before、generation_after(ClusterConfig 的 metadata.generation)、object_has_profile、configmap_present 这些键。

如果是静态配置,这项修改在重启后就会生效。动态配置下文件有什么用途,请看理论部分的“集群配置与节点配置”一节。spec 每变化一次,generation 就会增加。

修改对象后立即生效

不要重启,向 ClusterConfig 的 worker profile 列表中在不删除原有 profile 的前提下加入 from-api(maxPods: 60),待 ConfigMap 出现后,在 /root/k0scfg/api-patch.json 中写入 profile、configmap_uid、max_pods、controller_started_at(k0scontroller 服务最近一次启动的时刻,Unix 秒)这些键。

merge patch 会整体替换列表字段。向列表末尾追加一项的方法在 JSON patch 中。服务启动时刻可以把 systemctl 的 ActiveEnterTimestamp 用 date 转换得到。评分器会检查 ConfigMap 是否是在那个时刻之后创建的。

声明的 Chart 会变成 Chart 对象

在 ClusterConfig 的 spec.extensions.helm 中声明仓库 podinfo(https://stefanprodan.github.io/podinfo)和 Chart 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 安装完成后,Chart 的 status 中会填入版本。命名空间的 UID 是下一步用来核对“还剩下什么”的值。

删除声明后还剩下什么

只从 ClusterConfig 中删除 podinfo Chart 声明,并在 /root/k0scfg/removal.json 中写入 removed_chart_uid、chart_object_present、release_secrets(podinfo 命名空间中 Helm release Secret 的数量)、namespace_kept 这些键。然后在 /root/k0scfg/report.md 中写入 static_restart_needed=、dynamic_file_applied=、dynamic_object_applied=(三项都填 yes 或 no)、object_service_cidr=、apiserver_service_cidr= 这五行,以及 150 个字符以上的说明。

只删除 Chart 列表,保留仓库声明也可以。Chart 对象要过几秒才会消失。Helm release Secret 可以通过 owner=helm 标签找到。说明中请写明在哪种模式下什么是事实来源,以及对象中的 Service 网段是否可信。