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-apiserveretcdkube-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 集群时更加得心应手。


原始标题:Fixing Error “It seems like the kubelet isn’t running or healthy”