1. 问题现象:当Kubernetes节点突然失联

最近在维护一个Kubernetes集群时,突然发现某个工作节点状态变为NotReady,kubectl命令执行时出现异常。通过systemctl检查kubelet服务状态,发现日志中不断刷出类似这样的错误:

May 05 10:32:32 master1 kubelet[15016]: E0505 10:32:32.353984 15016 kubelet.go:2263] node "master1" not found

这种报错看起来非常诡异——节点明明就在眼前运行着,kubelet却声称找不到这个节点。更奇怪的是,重启kubelet服务后问题依旧存在。这时候我们需要像侦探一样,从各种蛛丝马迹中寻找线索。

2. 排查第一步:检查基础服务状态

2.1 验证kubelet基础功能

首先确认kubelet本身是否正常运行:

systemctl status kubelet -l

如果服务处于active状态但持续报错,说明kubelet进程还在,但可能遇到了某些资源限制。这时候可以尝试查看完整的journal日志:

journalctl -xu kubelet --no-pager | tail -n 50

2.2 检查API Server连通性

kubelet需要与API Server保持通信,测试集群控制平面的连通性:

curl -k https://<API-SERVER-IP>:6443/healthz

如果返回"ok"说明网络连接正常。也可以检查kubelet使用的kubeconfig配置:

cat /etc/kubernetes/kubelet.conf

3. 关键线索:磁盘空间告急

3.1 发现磁盘异常

在尝试用tab补全命令时,终端突然报错:

bash: cannot create temp file for here-document: No space left on device

这个提示直接指向了问题的核心——磁盘空间不足。立即使用df命令验证:

df -h

输出显示根分区使用率100%:

Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        50G   50G   0   100% /

3.2 定位大文件

使用ncdu工具快速分析磁盘使用情况(如果没有安装可以用du替代):

ncdu / --exclude /proc --exclude /sys

或者使用find命令查找大文件:

find / -type f -size +1G -exec ls -lh {} + 2>/dev/null

4. 深度分析:容器日志占满磁盘

4.1 检查Docker存储

在/var/lib/docker/containers目录下发现某个容器的日志文件异常庞大:

ls -lh /var/lib/docker/containers/*/*-json.log

输出显示某个日志文件达到11GB:

-rw-r----- 1 root root 11G May 3 06:51 0d7b20...-json.log

4.2 理解日志轮转机制

默认情况下Docker不会自动轮转日志,需要检查daemon.json配置:

cat /etc/docker/daemon.json

如果没有配置日志限制,可以考虑添加:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

5. 解决方案:清理与恢复操作

5.1 安全清理日志文件

直接删除大文件可能导致程序异常,推荐使用清空方式:

truncate -s 0 /var/lib/docker/containers/*/*-json.log

或者针对特定大文件:

cat /dev/null > 0d7b20...-json.log

5.2 临时增加磁盘空间

如果立即清理有困难,可以临时扩展磁盘空间:

dd if=/dev/zero of=/tmp/tempfile bs=1M count=1024

注意这只是一个临时方案,使用后记得删除:

rm /tmp/tempfile

5.3 服务重启与验证

清理后重启相关服务:

systemctl restart docker
systemctl restart kubelet

检查节点状态是否恢复:

kubectl get nodes

6. 预防措施:长期解决方案

6.1 配置日志轮转策略

对于Kubernetes集群,推荐以下两种方案:

  1. 全局配置Docker日志驱动(前文已提及)
  2. 使用Kubernetes的日志轮转:
kubectl edit cm kubelet-config -n kube-system

添加:

containerLogMaxSize: 100Mi
containerLogMaxFiles: 3

6.2 监控磁盘空间

部署Prometheus监控,添加以下告警规则:

- alert: NodeDiskRunningFull
  expr: (node_filesystem_avail_bytes{mountpoint="/"} * 100) / node_filesystem_size_bytes{mountpoint="/"} < 10
  for: 30m
  labels:
    severity: critical
  annotations:
    summary: "Node disk is running full (instance {{ $labels.instance }})"

6.3 设置Pod驱逐阈值

调整kubelet配置防止磁盘耗尽:

vim /var/lib/kubelet/config.yaml

添加:

evictionHard:
  memory.available: "500Mi"
  nodefs.available: "10%"
  imagefs.available: "15%"

7. 其他可能原因排查指南

虽然磁盘空间不足是最常见的原因,但node not found错误还可能有其他诱因:

7.1 节点名称不一致

检查节点名称是否发生变化:

hostname
cat /etc/hostname
kubectl get nodes

如果不一致,需要修正后重新加入集群。

7.2 证书过期问题

检查kubelet证书有效期:

openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -text | grep -A 2 Validity

如果过期需要轮换证书。

7.3 网络插件故障

检查CNI插件状态:

ls /etc/cni/net.d/
ip route show

在实际运维中,这类问题的排查往往需要结合具体环境分析。建议每次操作前做好备份,关键操作通过自动化脚本实现,这样可以大大提高故障处理效率。

更多推荐