Linux k0s 的零依赖安装与 air-gapped 离线部署流程

1次阅读

k0s无需systemd因单二进制静态链接核心组件,但离线部署需手动补全iptables、ip、modprobe等系统工具及so依赖,并正确配置service路径、worker join Token和containerd镜像导入。

Linux k0s 的零依赖安装与 air-gapped 离线部署流程

为什么 k0s 不需要 systemd 也能跑,但离线部署必须手动处理二进制依赖

k0s 本身是单二进制,k0s 文件里已静态链接了大部分运行时(比如容器运行时、etcd),但实际启动时仍会调用系统级工具:比如 iptablesmodprobesysctl。这些不是 k0s 自带的,离线环境若没预装,节点会卡在 “waiting for node to be ready” 或报 failed to setup iptables rules

实操建议:

  • 离线前,在同构系统(相同 OS 版本 + 架构)上运行 k0s install controller 并观察日志,用 strace -e trace=execve k0s start 捕获所有外部命令调用
  • 把缺失的二进制(如 iptablesipmodprobesysctl)连同它们的 so 依赖(用 ldd 检查)一并打包进离线介质
  • 别指望用 --disable-components 关掉网络策略就能绕过 iptables——kube-proxy 默认启用,且 k0s v1.28+ 强制校验 iptables 可用性

k0s air-gapped 部署时,如何让 worker 节点跳过 controller 的 TLS 证书校验

离线环境下,controller 的证书通常是自签名的,worker 启动时默认会校验 CA,失败就停在 failed to join cluster: x509: certificate signed by unknown authority。这不是 bug,是设计行为。

实操建议:

  • 不要改 worker 的 k0s.yaml 去删 CA 字段——k0s 会拒绝加载不完整配置
  • 正确做法是在 controller 初始化时,用 --config 指定含 spec.api.tlsSanspec.network.podCIDR 的配置,并提前生成好 CA;或更简单:用 k0s token create --role=worker --expiry=24h 生成带嵌入式 CA 的 join token
  • token 本质是 base64 编码的 json,里面包含 ca.crt 内容,worker 用它 join 就自动信任,无需额外传证书文件
  • 注意 token 有效期:离线环境无法自动续期,务必用 --expiry 设长一点,比如 8760h(1年)

离线集群里,k0s 如何加载本地 containerd 镜像而不依赖 registry

k0s 默认用 containerd,但它不支持直接从本地 tar 文件加载镜像(像 docker load 那样)。如果离线环境没搭 registry,又想预置 corednskube-proxy 等镜像,容易卡在 ImagePullBackOff

实操建议:

  • 先在有网机器上用 ctr --Namespace=k8s.io images pull 拉取所需镜像,再用 ctr --namespace=k8s.io images export coredns.tar ghcr.io/coredns/coredns:1.11.3 导出为 tar
  • 离线节点上,用 ctr --namespace=k8s.io images import coredns.tar 导入——注意 namespace 必须是 k8s.io,否则 k0s 容器运行时不认
  • 别用 nerdctldocker save/load 替代:containerd 的镜像存储格式和 layer 解析逻辑与 docker 不完全兼容,导入后可能显示 missing blob
  • 验证是否成功:ctr --namespace=k8s.io images list | grep coredns,看到 status 是 ready 才算真正可用

k0s v1.27+ 离线安装时,systemd 服务文件为什么不能直接用 k0s install 生成

k0s install 默认生成的 systemd unit 会写死 ExecStart=/usr/bin/k0s,并依赖 /usr/bin/k0s 存在。但在 air-gapped 场景下,你很可能把 k0s 放在 /opt/k0s/k0s 这类自定义路径,直接运行 install 会导致服务启动失败,报 Failed at step EXEC spawning /usr/bin/k0s: No such file or Directory

实操建议:

  • 不要运行 k0s install,改用手动创建 service 文件:sudo cp k0s /opt/k0s/k0s && sudo chmod +x /opt/k0s/k0s
  • k0s default-config > k0s.yaml 生成基础配置,修改其中 spec.dataDir 指向离线路径(如 /opt/k0s/data
  • service 文件里明确写 ExecStart=/opt/k0s/k0s server --config /opt/k0s/k0s.yaml,并加 Environment="K0S_DATA_DIR=/opt/k0s/data"
  • 特别注意:k0s v1.28 开始,k0s install 加了 --bin-dir 参数,但仅限 controller;worker 仍不支持,必须手写 service

离线部署最麻烦的从来不是 k0s 本身,而是它默许依赖的那些“系统常识”——比如哪个路径该有 iptables,哪个 namespace containerd 认,甚至 systemd 服务里一个硬编码路径。这些细节不记日志、不报明确错误,只让你等在 “node not ready” 里干瞪眼。

text=ZqhQzanResources