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

Kubernetes 发行版 — 自己搭

删除了 traefik,重启后它又回来了

在 TT Lab 中继续学习

目标

在真实的 k3s 上确认 k3s 服务器把 manifests 目录中的文件作为 AddOn 应用,并把 traefik 作为 HelmChart 安装的结构。 记录用 kubectl 删除、重启、.skip、--disable、HelmChartConfig,以及配置文件与 CLI 标志的优先级,各自会改变什么、又会保留什么。

为什么重要

k3s 用一行安装命令,就提供包含 Ingress、DNS、指标在内的集群。这种便利来自“k3s 每次启动时都会重写并应用默认组件的清单”这一设计。 因此,像在托管集群中那样用 kubectl 删除组件,下次重启时它会悄无声息地复活;反过来,即使删除清单文件,集群中的对象也会保留。 关闭靠 --disable,只忽略文件靠 .skip,只改值靠 HelmChartConfig。如果分不清这三者的区别,在升级或重启之后就得去追查“是谁把它又装上了”。 配置文件也一样:如果不知道安装脚本写入服务单元的标志优先于 config.yaml,就找不到修改后的值没有生效的原因。

步骤

  1. 在 /root/k3s-pkg/inventory.json 中写入 version(节点的 kubeletVersion)、addons(kube-system 中 AddOn 名称排序后的数组)、helmcharts(kube-system 中 HelmChart 名称排序后的数组)、manifest_files(manifests 目录下文件的相对路径排序后的数组)。
  2. 在 /var/lib/rancher/k3s/server/manifests/lab-banner.yaml 中写入 Namespace k3s-pkg 和 ConfigMap banner(命名空间 k3s-pkg,msg: v1),作为 AddOn 部署。用 kubectl 删除生成的 ConfigMap,等待 20 秒,确认它没有回来,然后把文件中的值改为 msg: v2,让它重新生成。在 /root/k3s-pkg/banner.json 中写入 deleted_uid(被删除那个的 UID)、restored_uid(重新生成那个的 UID)、returned_before_edit(在修改文件之前它是否回来了,布尔值)。
  3. 用 kubectl 删除 kube-system 中的 HelmChart traefik,并等待 traefik Deployment 消失(此时先不要重启)。在 /root/k3s-pkg/gone.json 中写入 deleted_at(删除的时刻,UTC RFC3339,例如:2026-01-01T00:00:00Z)、manifest_still_there(traefik.yaml 文件是否仍然存在,布尔值)、release_left(剩余的 traefik release Secret 数量,整数)。
  4. 用 systemctl restart k3s 重启 k3s,并等待 traefik Deployment 再次变为 Available。在 /root/k3s-pkg/revive.json 中写入 helmchart_uid(重新生成的 HelmChart traefik 的 UID)、helmchart_created(它的 creationTimestamp)、revived(Deployment 是否恢复了,布尔值)。
  5. 用 /var/lib/rancher/k3s/server/manifests/lab-pinned.yaml 部署 ConfigMap pinned(命名空间 k3s-pkg,v: "1")。确认它生成之后,在同一目录中创建 lab-pinned.yaml.skip,把文件中的值改为 v: "2",并等待 20 秒。在 /root/k3s-pkg/skip.json 中写入 file_value(文件中写的值)、live_value(集群 ConfigMap 中的值)、addon_still_exists(AddOn lab-pinned 是否仍然存在,布尔值)。
  6. 保持 /etc/rancher/k3s/config.yaml 不变,创建 /etc/rancher/k3s/config.yaml.d/50-disable.yaml 来关闭 metrics-server。local-storage 必须保持关闭。写完文件后,先确认 metrics-server 在 20 秒内保持原样,然后重启 k3s。在 /root/k3s-pkg/disable.json 中写入 changed_before_restart(重启之前它是否消失了,布尔值)、removed_addons(因重启而消失的 AddOn 名称排序后的数组)、files_left(manifests/metrics-server 下剩余的文件数,整数)。
  7. 在 /etc/rancher/k3s/config.yaml 中保留原有的 disable 列表,并加入 write-kubeconfig-mode: "0600",然后重启 k3s。查看 /etc/rancher/k3s/k3s.yaml 的权限变成了什么,并在 /root/k3s-pkg/precedence.json 中写入 config_value(config.yaml 中写的值,字符串)、effective_mode(重启后 k3s.yaml 的八进制权限,字符串,例如:"640")、winner(cli 或 config)、flag_file(写有胜出值的文件的绝对路径)。
  8. 不重启,在 /var/lib/rancher/k3s/server/manifests/traefik-config.yaml 中放置 HelmChartConfig traefik(kube-system),把 traefik 的日志级别改为 DEBUG(logs.general.level)。在 /root/k3s-pkg/hcc.json 中写入 revision_before(应用前 traefik release 的最大 revision,整数)、revision_after(应用后,整数)、log_arg(traefik 容器参数中完整的日志级别参数)。
  9. 在 /root/k3s-pkg/report.json 中写入 needs_restart(对象:manifest_file、skip_file、helmchartconfig、config_dropin 各自是否需要重启才生效,布尔值)、revived_by_restart(第 3、4 步中因重启而复活的 HelmChart 名称)、disable_deletes_files(布尔值)、skip_removes_resources(布尔值)、current_addons(当前 kube-system 中 AddOn 名称排序后的数组)、traefik_revision(当前 traefik release 的最大 revision,整数)。

参考

哪些东西是作为 AddOn 安装的

在 /root/k3s-pkg/inventory.json 中写入 version(节点的 kubeletVersion)、addons(kube-system 中 AddOn 名称排序后的数组)、helmcharts(kube-system 中 HelmChart 名称排序后的数组)、manifest_files(manifests 目录下文件的相对路径排序后的数组)。

AddOn 是 k3s.cattle.io 组的 CRD,一个文件对应一个 AddOn。子目录中的文件也各自成为一个 AddOn。local-storage 已经在配方的 config.yaml 中关闭了,所以它不在列表中才是正常的。

用 kubectl 删除的 ConfigMap 何时会回来

在 /var/lib/rancher/k3s/server/manifests/lab-banner.yaml 中写入 Namespace k3s-pkg 和 ConfigMap banner(命名空间 k3s-pkg,msg: v1),作为 AddOn 部署。用 kubectl 删除生成的 ConfigMap,等待 20 秒,确认它没有回来,然后把文件中的值改为 msg: v2,让它重新生成。在 /root/k3s-pkg/banner.json 中写入 deleted_uid(被删除那个的 UID)、restored_uid(重新生成那个的 UID)、returned_before_edit(在修改文件之前它是否回来了,布尔值)。

部署控制器在文件发生变化时以及 k3s 启动时进行应用。集群中的对象被删除这一事实,并不是触发应用的时机。AddOn 会记住文件的校验和,所以像 touch 这样内容相同的变更也不会成为触发时机。

用 kubectl 删除了 traefik

用 kubectl 删除 kube-system 中的 HelmChart traefik,并等待 traefik Deployment 消失(此时先不要重启)。在 /root/k3s-pkg/gone.json 中写入 deleted_at(删除的时刻,UTC RFC3339,例如:2026-01-01T00:00:00Z)、manifest_still_there(traefik.yaml 文件是否仍然存在,布尔值)、release_left(剩余的 traefik release Secret 数量,整数)。

HelmChart 上带有 helm-controller 的终结器(finalizer),删除时 helm-delete Job 会先删除 release。Helm release 会以带有 owner=helm,name=traefik 标签的 Secret 形式保留在 kube-system 中。即使删除集群对象,manifests 目录也不会被触动。

重启之后 traefik 又复活了

用 systemctl restart k3s 重启 k3s,并等待 traefik Deployment 再次变为 Available。在 /root/k3s-pkg/revive.json 中写入 helmchart_uid(重新生成的 HelmChart traefik 的 UID)、helmchart_created(它的 creationTimestamp)、revived(Deployment 是否恢复了,布尔值)。

k3s 每次启动时都会把默认组件的清单重新写入磁盘并应用。如果没有由文件创建的 HelmChart,就会重新创建,随后 helm-install Job 再次运行。从 API 就绪到 traefik 启动之间,大约相差 20 秒。

.skip 不会删除,只是装作没看见

用 /var/lib/rancher/k3s/server/manifests/lab-pinned.yaml 部署 ConfigMap pinned(命名空间 k3s-pkg,v: "1")。确认它生成之后,在同一目录中创建 lab-pinned.yaml.skip,把文件中的值改为 v: "2",并等待 20 秒。在 /root/k3s-pkg/skip.json 中写入 file_value(文件中写的值)、live_value(集群 ConfigMap 中的值)、addon_still_exists(AddOn lab-pinned 是否仍然存在,布尔值)。

.skip 文件只看是否存在,不看内容。已经应用的 AddOn 以及它所创建的对象保持原样,此后对该文件的变更会被忽略。

用一个 drop-in 关闭 metrics-server

保持 /etc/rancher/k3s/config.yaml 不变,创建 /etc/rancher/k3s/config.yaml.d/50-disable.yaml 来关闭 metrics-server。local-storage 必须保持关闭。写完文件后,先确认 metrics-server 在 20 秒内保持原样,然后重启 k3s。在 /root/k3s-pkg/disable.json 中写入 changed_before_restart(重启之前它是否消失了,布尔值)、removed_addons(因重启而消失的 AddOn 名称排序后的数组)、files_left(manifests/metrics-server 下剩余的文件数,整数)。

drop-in 按名称顺序读取,如果多个文件中有相同的键,则以最后一个值为准。要追加到列表中,就在键名末尾加上 +。--disable 不仅会移除 AddOn,还会删除原文件。配置文件在 k3s 启动时读取。

修改了 config.yaml,权限却没变

在 /etc/rancher/k3s/config.yaml 中保留原有的 disable 列表,并加入 write-kubeconfig-mode: "0600",然后重启 k3s。查看 /etc/rancher/k3s/k3s.yaml 的权限变成了什么,并在 /root/k3s-pkg/precedence.json 中写入 config_value(config.yaml 中写的值,字符串)、effective_mode(重启后 k3s.yaml 的八进制权限,字符串,例如:"640")、winner(cli 或 config)、flag_file(写有胜出值的文件的绝对路径)。

如果配置文件和 CLI 参数中有相同的键,CLI 优先。传给安装脚本的 INSTALL_K3S_EXEC 会作为参数保存在 systemd 单元的 ExecStart 中。请用 systemctl cat k3s 查看。

不重启,只修改 traefik 的值

不重启,在 /var/lib/rancher/k3s/server/manifests/traefik-config.yaml 中放置 HelmChartConfig traefik(kube-system),把 traefik 的日志级别改为 DEBUG(logs.general.level)。在 /root/k3s-pkg/hcc.json 中写入 revision_before(应用前 traefik release 的最大 revision,整数)、revision_after(应用后,整数)、log_arg(traefik 容器参数中完整的日志级别参数)。

HelmChartConfig 的名称和命名空间必须与目标 HelmChart 相同。valuesContent 优先于 HelmChart 的 valuesContent,但弱于 spec.set。由于 helm-controller 会运行 helm upgrade,release Secret 会增加一个(sh.helm.release.v1.traefik.vN)。

把删除、忽略、覆盖整理成一张表

在 /root/k3s-pkg/report.json 中写入 needs_restart(对象:manifest_file、skip_file、helmchartconfig、config_dropin 各自是否需要重启才生效,布尔值)、revived_by_restart(第 3、4 步中因重启而复活的 HelmChart 名称)、disable_deletes_files(布尔值)、skip_removes_resources(布尔值)、current_addons(当前 kube-system 中 AddOn 名称排序后的数组)、traefik_revision(当前 traefik release 的最大 revision,整数)。

依据前面步骤留下的 json 和当前集群来填写。评分器会从集群和记录文件中重新计算同样的值。