1. 概述
在搭建 Kubernetes 集群过程中,我们有时会遇到一个常见的错误提示:“It seems like the kubelet isn’t running or healthy”。这个错误通常出现在执行 kubeadm init
初始化集群时,导致集群初始化流程中断。
根本原因在于 kubelet
这个关键组件无法通过健康检查。kubelet
是每个节点上的核心组件,负责管理 Pod 和容器的生命周期、监控资源使用情况并与 API Server 通信。如果它无法正常运行,集群初始化就无法完成。
本文将分析这个错误的常见原因,并提供一套系统化的排查和解决流程。
2. 理解 kubelet 与错误信息
kubelet 的作用
kubelet 是 Kubernetes 节点上的“现场管理员”,其职责包括:
- 管理 Pod 和容器的创建、销毁
- 监控节点资源使用情况
- 与 API Server 通信,上报节点状态并接收指令
✅ 没有 kubelet,节点就无法加入集群,也无法运行任何工作负载。
错误信息的含义
当我们执行 kubeadm init
时,系统会进行一系列预检(pre-flight checks),其中之一就是检查 kubelet 是否运行并健康。
kubelet 提供了一个健康检查接口(health endpoint),地址通常是 http://localhost:10248/healthz
。如果 kubelet 没有运行,或者虽然运行但返回错误,就会触发这个提示。
3. 常见错误原因分析
3.1. kubelet 未运行
最常见的原因之一是 kubelet 没有启动成功。这可能由以下情况导致:
- 依赖包未安装或版本不兼容
- systemd 配置文件有误
可以通过以下命令检查 kubelet 状态:
$ sudo systemctl status kubelet
如果状态为 inactive (dead)
,说明 kubelet 没有运行。
3.2. cgroup 驱动配置不一致
Docker 和 kubelet 使用的 cgroup 驱动不一致也会导致 kubelet 无法启动。例如 Docker 使用 systemd
,而 kubelet 配置为 cgroupfs
。
可以通过以下命令查看 Docker 的 cgroup 驱动:
$ docker info | grep -i cgroup
确保 kubelet 的配置文件中(通常是 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
)设置的 --cgroup-driver
与 Docker 一致。
3.3. 网络或 API Server 通信问题
kubelet 需要与 API Server 通信。如果网络配置错误,如防火墙阻止了端口(如 6443、10248),就会导致健康检查失败。
可以使用以下命令测试 kubelet 的健康接口:
$ curl -sSL http://localhost:10248/healthz
如果返回错误,说明本地 kubelet 无法响应,需检查防火墙或端口配置。
3.4. 认证或配置错误
kubelet 使用的 kubeconfig
文件如果配置错误,如 API Server 地址不对、token 失效,也会导致认证失败,进而无法与控制平面通信。
检查 /etc/kubernetes/kubelet.conf
中的 server
字段是否指向正确的 API Server 地址(通常是 https://<control-plane-ip>:6443
)。
4. 故障排查流程
4.1. 检查 kubelet 状态与日志
首先确认 kubelet 是否运行:
$ sudo systemctl status kubelet
查看详细日志:
$ sudo journalctl -xeu kubelet
日志中常见的错误包括:
- connection refused
- cgroup driver mismatch
- unable to connect to API Server
4.2. 检查容器运行时状态
查看 kubelet 管理的容器是否正常运行:
$ docker ps -a | grep kube
如果发现 kube-apiserver
、etcd
或 kube-proxy
容器状态异常,可以用以下命令查看日志:
$ docker logs <container-id>
这些日志可能揭示容器启动失败的原因,如镜像拉取失败、端口冲突等。
4.3. 解决 cgroup 配置问题
确保 Docker 与 kubelet 的 cgroup 驱动一致:
$ docker info | grep -i cgroup
修改 kubelet 的配置文件:
Environment="KUBELET_EXTRA_ARGS=--cgroup-driver=cgroupfs"
然后重载 systemd 并重启 kubelet:
$ sudo systemctl daemon-reload
$ sudo systemctl restart kubelet
4.4. 禁用 Swap 与调整系统设置
Kubernetes 要求禁用 Swap,否则 kubelet 会拒绝启动。
临时禁用 Swap:
$ sudo swapoff -a
永久禁用 Swap:
$ sudo vim /etc/fstab
注释掉所有 Swap 相关行:
# UUID=xxxx-xxxx none swap sw 0 0
然后重启系统生效。
此外,检查防火墙是否允许 kubelet 的健康检查端口(10248)和 API Server 端口(6443):
$ sudo ufw status
4.5. 重置并重新初始化集群
如果以上步骤都已完成,可以尝试重置集群:
$ sudo kubeadm reset
然后重新初始化:
$ sudo kubeadm init
如果需要加入工作节点,使用 kubeadm init
输出的 join
命令即可。
5. 总结
“kubelet isn’t running or healthy” 是 Kubernetes 集群初始化过程中常见的问题,可能由多种原因导致,包括:
- kubelet 未运行或配置错误
- cgroup 驱动不一致
- 网络或防火墙配置问题
- kubeconfig 认证失败
通过系统化的排查流程,包括检查状态、日志、配置文件、容器状态和网络设置,我们可以快速定位问题并解决。
掌握这些排查技巧,有助于我们在搭建或维护 Kubernetes 集群时更加得心应手。