news 2026/10/30 18:57:57

手把手教你排查K8S节点NotReady:从日志分析到Calico网络插件修复

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手教你排查K8S节点NotReady:从日志分析到Calico网络插件修复

从NotReady到Ready:一次完整的Kubernetes节点故障深度排查与Calico网络修复实战

最近在帮一个朋友调试他的K8S集群时,遇到了一个经典的节点NotReady问题。他刚搭建好的Master节点,kubectl get nodes一直显示NotReady状态,CoreDNS也卡在Pending,整个集群基本处于瘫痪状态。这种问题对于刚接触K8S的运维来说确实头疼,但如果你掌握了系统化的排查思路,其实就像解谜一样,每一步都有迹可循。今天我就把这次完整的排查过程整理出来,不仅告诉你如何解决这个具体问题,更重要的是分享一套通用的故障排查方法论,让你下次遇到类似问题时能快速定位。

节点NotReady的原因多种多样,可能是网络插件配置问题、系统资源不足、证书过期,或者是组件版本不兼容。这次我们遇到的是Calico网络插件与K8S版本匹配问题,但排查过程涉及了日志分析、污点处理、CNI配置检查等多个层面,非常具有代表性。无论你是负责生产环境稳定的SRE,还是正在学习K8S的开发者,这套排查思路都能帮你节省大量时间。

1. 建立系统化的故障排查思维框架

遇到节点NotReady,很多人的第一反应是重启kubelet或者整个节点。这有时能解决问题,但更多时候只是暂时掩盖了问题,甚至可能让情况变得更复杂。我建议采用分层排查的方法,从最外层现象逐步深入到内核原因。

1.1 理解节点状态机制

Kubernetes节点状态不是简单的是否在线,而是一个综合健康检查的结果。当kubelet启动后,它会定期向API Server报告节点状态,包括:

  • NodeReady:节点是否准备好接收Pod
  • MemoryPressure:内存是否不足
  • DiskPressure:磁盘空间是否不足
  • PIDPressure:进程ID是否耗尽
  • NetworkUnavailable:节点网络配置是否正确

这些条件状态会直接影响调度器的决策。NotReady状态通常意味着一个或多个条件不满足,我们的任务就是找出具体是哪个条件出了问题。

1.2 分层排查策略

我习惯将排查分为四个层次:

  1. 表象层:通过kubectl命令查看节点、Pod状态
  2. 组件层:检查kubelet、容器运行时、网络插件等核心组件
  3. 配置层:验证配置文件、证书、网络配置
  4. 系统层:检查内核参数、系统资源、防火墙规则

每一层都有对应的检查工具和方法,下面我们逐层深入。

2. 从表象到本质:初步诊断与信息收集

当接到节点NotReady的告警时,不要急于修改配置,先收集足够的信息。信息越全面,判断就越准确。

2.1 基础状态检查

首先获取节点的详细状态信息:

# 查看所有节点状态 kubectl get nodes -o wide # 获取特定节点的详细描述 kubectl describe node <node-name> # 查看节点上的事件 kubectl get events --field-selector involvedObject.kind=Node,involvedObject.name=<node-name>

kubectl describe node的输出特别重要,它会显示:

  • Conditions:节点的各种条件状态
  • Addresses:节点的IP地址和主机名
  • System Info:操作系统、内核版本、容器运行时信息
  • Allocatable/Allocated Resources:资源分配情况
  • Taints:节点污点设置

在我朋友的案例中,describe命令显示节点有一个node.kubernetes.io/not-ready:NoSchedule的污点。这是K8S自动添加的,当节点长时间处于NotReady状态时,调度器会避免将新Pod调度到该节点。

注意:污点是K8S的调度机制,不是问题的原因而是结果。直接移除污点可能让Pod调度到不健康的节点上,应该先解决根本问题。

2.2 核心组件Pod状态分析

接下来检查kube-system命名空间下的核心组件:

# 查看所有系统Pod kubectl get pods -n kube-system -o wide # 检查特定Pod的日志 kubectl logs -n kube-system <pod-name> # 获取Pod的详细描述和事件 kubectl describe pod -n kube-system <pod-name>

这里我们发现CoreDNS Pod处于Pending状态,描述信息显示"0/1 nodes are available: 1 node(s) had taint {node.kubernetes.io/not-ready: }"。这证实了节点污点影响了Pod调度,但我们需要知道为什么节点会被标记为NotReady。

2.3 节点资源与系统检查

有时候NotReady是资源不足导致的,检查节点资源使用情况:

# 查看节点资源使用 kubectl top node # 或者使用原生命令 ssh <node-ip> "free -h && df -h && uptime"

同时检查一些关键的系统参数:

# 检查swap是否开启(K8S要求关闭swap) cat /proc/swaps # 检查关键内核参数 sysctl net.bridge.bridge-nf-call-iptables sysctl net.ipv4.ip_forward

资源检查通常能快速排除内存、磁盘等问题,如果这些都没问题,我们就需要深入组件层了。

3. 深入组件层:kubelet与容器运行时诊断

kubelet是节点上的核心代理,负责与API Server通信并管理容器。当节点NotReady时,kubelet通常是第一个需要检查的组件。

3.1 kubelet日志分析

kubelet的日志包含了丰富的诊断信息。在大多数Linux发行版上,你可以通过systemd的journalctl查看:

# 实时查看kubelet日志 journalctl -f -u kubelet # 查看特定时间段的日志 journalctl -u kubelet --since "2 hours ago" # 查看包含错误级别的日志 journalctl -u kubelet -p err

在我遇到的案例中,日志里反复出现这样的错误:

W0430 21:11:05.628506 962 cni.go:239] Unable to update cni config: no networks found in /etc/cni/net.d E0430 21:11:06.818698 962 kubelet.go:2103] Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

这两条信息非常关键:

  1. CNI配置未找到:kubelet在/etc/cni/net.d目录下找不到网络配置
  2. 网络插件未就绪:容器运行时报告网络插件未初始化

这直接指向了CNI(Container Network Interface)网络插件的问题。

3.2 kubelet服务状态检查

除了查看日志,还要检查kubelet服务的运行状态:

# 检查kubelet服务状态 systemctl status kubelet -l # 查看kubelet的启动参数 ps aux | grep kubelet

重点关注kubelet的启动参数,特别是--network-plugin参数。在K8S 1.24+版本中,默认使用cni作为网络插件,但需要确保CNI配置文件存在且正确。

3.3 容器运行时检查

K8S支持多种容器运行时(Docker、containerd、CRI-O等),需要确保运行时正常工作:

# 检查Docker服务状态(如果使用Docker) systemctl status docker # 测试Docker是否能运行容器 docker run --rm hello-world # 检查containerd状态 systemctl status containerd

如果容器运行时有问题,kubelet就无法创建或管理容器,节点自然无法变为Ready状态。

4. CNI网络插件深度排查:以Calico为例

CNI网络插件是K8S网络的核心,也是节点NotReady的常见原因。Calico作为最流行的网络插件之一,其配置相对复杂,容易出问题。

4.1 CNI基础目录结构检查

首先验证CNI的基本目录结构是否存在:

# 检查CNI二进制文件目录 ls -la /opt/cni/bin/ # 检查CNI配置文件目录 ls -la /etc/cni/net.d/

正常的Calico安装应该包含:

/opt/cni/bin/目录下的关键二进制文件:

文件作用是否必需
calicoCalico CNI插件主程序是
calico-ipamCalico IP地址管理插件是
bridge标准bridge插件可选
flannelFlannel插件(如果同时使用)可选
portmap端口映射插件推荐
tuning网络调优插件推荐

/etc/cni/net.d/目录下的配置文件:

# 查看CNI配置文件 cat /etc/cni/net.d/10-calico.conflist

一个基本的Calico CNI配置应该类似这样:

{ "name": "k8s-pod-network", "cniVersion": "0.3.1", "plugins": [ { "type": "calico", "log_level": "info", "datastore_type": "kubernetes", "nodename": "__KUBERNETES_NODE_NAME__", "mtu": __CNI_MTU__, "ipam": { "type": "calico-ipam" }, "policy": { "type": "k8s" }, "kubernetes": { "kubeconfig": "__KUBECONFIG_FILEPATH__" } }, { "type": "portmap", "snat": true, "capabilities": {"portMappings": true} }, { "type": "bandwidth", "capabilities": {"bandwidth": true} } ] }

如果这些文件不存在或格式错误,CNI插件就无法正常工作。

4.2 Calico组件状态检查

Calico由多个组件构成,需要确保所有组件都正常运行:

# 查看所有Calico相关的Pod kubectl get pods -n calico-system kubectl get pods -n calico-apiserver kubectl get pods -n tigera-operator

关键组件及其作用:

组件命名空间作用预期状态
calico-nodecalico-system节点上的网络代理Running
calico-kube-controllerscalico-system策略控制器Running
calico-typhacalico-system数据平面扩展(大规模集群)Running(可选)
tigera-operatortigera-operatorCalico OperatorRunning
calico-apiservercalico-apiserverAPI服务器(企业版)Running(可选)

如果任何关键组件不是Running状态,需要查看其日志:

# 查看calico-node日志 kubectl logs -n calico-system daemonset/calico-node # 查看calico-kube-controllers日志 kubectl logs -n calico-system deployment/calico-kube-controllers

4.3 常见Calico问题与解决方案

根据我的经验,Calico相关的问题主要集中在以下几个方面:

1. 镜像拉取失败

Calico组件需要从特定镜像仓库拉取镜像,如果网络不通或镜像版本不对,Pod会处于ImagePullBackOff状态:

# 查看Pod的事件 kubectl describe pod -n calico-system <pod-name> # 手动测试镜像拉取 docker pull calico/node:v3.27.3

2. IP池配置问题

Calico需要正确的IP池配置,否则Pod无法获取IP地址:

# 查看IP池配置 kubectl get ippools -o yaml # 检查IP池是否启用 kubectl get ippools -o jsonpath='{.items[*].spec.disabled}'

3. 网络策略冲突

过于严格的网络策略可能阻止Calico组件间的通信:

# 临时禁用所有网络策略进行测试 kubectl delete networkpolicies --all-namespaces --all

4. 内核模块缺失

Calico需要一些内核模块支持,特别是IP转发和网桥过滤:

# 检查必需的内核模块 lsmod | grep -E 'ip_tables|iptable_filter|iptable_nat|iptable_mangle' lsmod | grep -E 'br_netfilter|bridge|nf_conntrack'

如果缺少这些模块,需要加载它们:

# 临时加载模块 modprobe ip_tables modprobe iptable_filter modprobe iptable_nat modprobe br_netfilter # 永久生效(添加到/etc/modules-load.d/k8s.conf) echo -e "ip_tables\niptable_filter\niptable_nat\nbr_netfilter" >> /etc/modules-load.d/k8s.conf

5. 版本兼容性:被忽视的关键问题

在我朋友的案例中,最根本的问题是版本兼容性。他使用的是K8S 1.29.4,但安装的Calico版本与这个K8S版本不兼容。这是很多人在升级K8S后容易忽略的问题。

5.1 K8S与Calico版本兼容性矩阵

Calico官方维护着详细的版本兼容性表格,以下是一些常见版本的兼容情况:

Calico版本支持的K8S版本关键特性备注
v3.27.x1.25-1.29支持eBPF数据平面生产推荐
v3.26.x1.24-1.28稳定性优化长期支持
v3.25.x1.23-1.27性能改进逐步淘汰
v3.24.x1.22-1.26基础功能仅维护

重要提示:始终参考Calico官方文档获取最新的兼容性信息。不要凭记忆或过时的博客文章选择版本。

5.2 版本不兼容的典型症状

当Calico与K8S版本不匹配时,可能会出现:

  1. CRD(Custom Resource Definition)创建失败

    # 查看CRD安装状态 kubectl get crd | grep calico
  2. API版本错误

    error: unable to recognize "calico.yaml": no matches for kind "Installation" in version "operator.tigera.io/v1"
  3. 组件启动失败但无明确错误Pod处于CrashLoopBackOff状态,但日志没有明显错误。

5.3 安全升级与降级策略

如果发现版本不兼容,需要重新安装合适版本的Calico。以下是安全操作步骤:

步骤1:备份当前配置

# 备份Calico自定义资源 kubectl get installation.operator.tigera.io default -o yaml > calico-installation-backup.yaml kubectl get ippools -o yaml > calico-ippools-backup.yaml # 备份网络策略 kubectl get networkpolicies --all-namespaces -o yaml > all-networkpolicies-backup.yaml

步骤2:卸载当前Calico

# 如果使用Operator方式安装 kubectl delete -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/tigera-operator.yaml # 如果使用manifest方式安装 kubectl delete -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/calico.yaml # 清理残留资源 kubectl delete crd $(kubectl get crd | grep calico | awk '{print $1}') kubectl delete crd $(kubectl get crd | grep tigera | awk '{print $1}')

步骤3:安装兼容版本

# 对于K8S 1.28.2,我推荐Calico 3.27.3 kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/tigera-operator.yaml kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/custom-resources.yaml

步骤4:验证安装

# 等待所有Pod就绪 watch kubectl get pods -n calico-system # 检查节点网络状态 kubectl get nodes -o wide # 测试网络连通性 kubectl run test-pod --image=busybox --rm -it --restart=Never -- ping -c 4 8.8.8.8

5.4 预防版本问题的实践建议

  1. 在测试环境先验证:任何版本升级都先在测试集群验证
  2. 阅读发布说明:关注版本间的破坏性变更
  3. 使用版本管理工具:如Helm,可以方便地回滚
  4. 监控组件健康:设置对Calico组件的监控告警

6. 高级排查技巧与工具

当基础排查无法解决问题时,需要一些更高级的工具和技巧。

6.1 使用kubectl-debug进行节点诊断

kubectl-debug是一个强大的诊断工具,可以在不登录节点的情况下运行诊断命令:

# 安装kubectl-debug curl -Lo kubectl-debug.tar.gz https://github.com/aylei/kubectl-debug/releases/download/v0.1.1/kubectl-debug_0.1.1_linux_amd64.tar.gz tar -zxvf kubectl-debug.tar.gz sudo mv kubectl-debug /usr/local/bin/ # 在问题节点上运行诊断容器 kubectl debug node/<node-name> --image=nicolaka/netshoot -- bash

进入诊断容器后,你可以:

# 检查CNI配置 cat /host/etc/cni/net.d/* # 检查网络接口 ip addr show ip route show # 测试网络连通性 ping <其他节点IP> nc -zv <API-Server-IP> 6443

6.2 使用calicoctl进行Calico特定诊断

calicoctl是Calico的专用管理工具,提供了丰富的诊断功能:

# 安装calicoctl curl -L https://github.com/projectcalico/calico/releases/download/v3.27.3/calicoctl-linux-amd64 -o calicoctl chmod +x calicoctl sudo mv calicoctl /usr/local/bin/ # 检查Calico节点状态 calicoctl node status # 查看BGP对等状态 calicoctl get bgppeer # 检查IP池使用情况 calicoctl ipam show --show-blocks

6.3 网络策略与连通性测试

有时候问题不是Calico本身,而是网络策略阻止了必要的通信:

# 创建测试Pod进行网络诊断 kubectl run network-test --image=nicolaka/netshoot --restart=Never -- sleep 3600 # 进入测试Pod kubectl exec -it network-test -- bash # 在Pod内测试各种连通性 # 测试到API Server的连通性 curl -k https://kubernetes.default.svc.cluster.local:443 # 测试到其他Pod的连通性 ping <其他PodIP> # 测试到服务的连通性 nslookup kubernetes.default.svc.cluster.local

6.4 性能问题诊断

如果节点在重负载下变为NotReady,可能是性能问题:

# 检查系统资源使用 kubectl top node kubectl top pod -n calico-system # 检查Calico的CPU/内存限制 kubectl describe daemonset calico-node -n calico-system | grep -A5 Resources # 调整Calico资源限制(如果需要) kubectl patch daemonset calico-node -n calico-system --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/resources", "value": {"limits": {"cpu": "500m", "memory": "512Mi"}, "requests": {"cpu": "250m", "memory": "256Mi"}}}]'

7. 预防措施与最佳实践

解决问题很重要,但预防问题更重要。以下是我总结的一些最佳实践:

7.1 监控与告警配置

建立完善的监控体系,在问题发生前发现迹象:

# Prometheus监控Calico的示例规则 groups: - name: calico.rules rules: - alert: CalicoNodeDown expr: absent(up{job="calico-node"} == 1) for: 5m labels: severity: critical annotations: summary: "Calico node {{ $labels.instance }} is down" - alert: BGPSessionDown expr: calico_bgp_session_state != 1 for: 2m labels: severity: warning annotations: summary: "BGP session {{ $labels.peer_ip }} is down on {{ $labels.instance }}"

7.2 定期健康检查

建立定期检查脚本,自动化常见问题检测:

#!/bin/bash # k8s-node-health-check.sh # 检查节点状态 echo "=== 节点状态检查 ===" kubectl get nodes -o wide # 检查核心Pod echo -e "\n=== 核心Pod状态检查 ===" kubectl get pods -n kube-system -o wide | grep -v Running # 检查Calico组件 echo -e "\n=== Calico组件状态检查 ===" kubectl get pods -n calico-system -o wide | grep -v Running # 检查CNI配置 echo -e "\n=== CNI配置检查 ===" for node in $(kubectl get nodes -o name | cut -d/ -f2); do echo "检查节点 $node 的CNI配置..." kubectl debug node/$node --image=busybox -- cat /host/etc/cni/net.d/10-calico.conflist 2>/dev/null || echo "CNI配置不存在" done # 检查网络连通性 echo -e "\n=== 网络连通性测试 ===" kubectl run net-test --image=busybox --rm -it --restart=Never -- ping -c 3 8.8.8.8

7.3 文档与知识库

建立内部知识库,记录常见问题和解决方案:

问题现象可能原因排查步骤解决方案
节点NotReady,CNI配置缺失Calico未正确安装1. 检查/etc/cni/net.d目录
2. 检查Calico Pod状态
3. 查看kubelet日志
重新安装兼容版本的Calico
Calico-node Pod不断重启资源不足或镜像拉取失败1. 查看Pod日志
2. 检查节点资源
3. 检查镜像仓库可达性
调整资源限制或配置镜像仓库
Pod无法跨节点通信网络策略或路由问题1. 检查网络策略
2. 检查Calico BGP状态
3. 验证防火墙规则
调整网络策略或修复BGP配置

7.4 灾难恢复计划

为最坏情况做好准备:

  1. 备份关键配置

    # 备份Calico配置 kubectl get installation.operator.tigera.io -o yaml > calico-backup.yaml kubectl get ippools -o yaml > ippools-backup.yaml # 备份网络策略 kubectl get networkpolicies --all-namespaces -o yaml > networkpolicies-backup.yaml
  2. 准备快速恢复脚本

    # restore-calico.sh kubectl apply -f calico-backup.yaml kubectl apply -f ippools-backup.yaml kubectl apply -f networkpolicies-backup.yaml
  3. 建立回滚流程

    • 记录每次变更
    • 测试回滚步骤
    • 定期演练恢复过程

节点NotReady问题虽然令人头疼,但通过系统化的排查方法,大多数问题都能快速定位和解决。关键是要保持冷静,按照从外到内、从简单到复杂的顺序逐步排查。记住,日志是你的好朋友,kubectl describe和kubectl logs能提供80%的线索。版本兼容性这种看似简单的问题,往往是最容易被忽视的陷阱,特别是在快速发展的K8S生态中。定期更新你的知识库,测试环境先行,生产环境谨慎,这样才能在享受容器化便利的同时,保持系统的稳定可靠。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/30 18:57:42

3个步骤掌握ROFL-Player:英雄联盟回放文件全流程管理指南

3个步骤掌握ROFL-Player&#xff1a;英雄联盟回放文件全流程管理指南 【免费下载链接】ROFL-Player (No longer supported) One stop shop utility for viewing League of Legends replays! 项目地址: https://gitcode.com/gh_mirrors/ro/ROFL-Player 一、功能价值&…

作者头像 李华
网站建设 2026/10/30 18:57:42

HDBSCAN实战:用Python搞定高维数据聚类(附完整代码与调参技巧)

HDBSCAN实战&#xff1a;用Python搞定高维数据聚类&#xff08;附完整代码与调参技巧&#xff09; 最近在分析一批电商用户行为数据时&#xff0c;我遇到了一个典型难题&#xff1a;用户群体特征复杂&#xff0c;行为模式差异巨大&#xff0c;传统的K-Means或DBSCAN聚类方法要…

作者头像 李华
网站建设 2026/10/29 14:22:09

2026全国力推数据要素年,你的城市靠数据赚钱的机会来了!

曾几何时&#xff0c;数据还只是数字世界的“副产品”&#xff0c;被存储在服务器中&#xff0c;鲜少被人提及价值。而今天&#xff0c;数据已被视为与土地、劳动力、资本、技术并列的第五大生产要素&#xff0c;成为像水电一样的基础资源。2026年&#xff0c;我国明确将其定为…

作者头像 李华
网站建设 2026/10/23 7:38:36

Dynamic Vision Sensor-事件相机/仿生视觉-在“低照 + 快速运动触发”的周界/安防场景中非常有价值

Dynamic Vision Sensor-事件相机/仿生视觉-在“低照 快速运动触发”的周界/安防场景中非常有价值动态视觉传感器 (DVS) 市场专注于能够实时捕捉基于像素级变化的视觉数据的传感器。该技术具有低延迟、高时间分辨率和低功耗等优势&#xff0c;是汽车、医疗保健、能源与公用事业…

作者头像 李华
网站建设 2026/10/23 8:26:20

Gemma-3-270m企业应用:保险行业保单条款解读与客户疑问自动应答系统

Gemma-3-270m企业应用&#xff1a;保险行业保单条款解读与客户疑问自动应答系统 保险行业每天都要处理海量的保单咨询。客户看不懂复杂的条款&#xff0c;客服人员需要反复解释&#xff0c;效率低下还容易出错。有没有一种方法&#xff0c;能让机器自动读懂保单&#xff0c;并…

作者头像 李华