k8s网络故障排查思路

K8s网络问题解决方案

  • 网络故障介绍
  • 故障解决方案

1 网络故障类型介绍

 在 Kubernetes 中,网络故障的类型软件层面可以分为以下几种:

  1. 容器网络故障
  2. 网络插件故障
  3. 网络策略故障
  4. DNS 故障

2 横向解决思路(横向思路过于宽泛,简单参考即可,不推荐作为排错思路)

1.1 容器网络故障

在 Kubernetes 中,容器网络故障可能会导致应用程序无法正常工作或通信。容器网络故障可以是由各种原因引起的,例如网络配置错误、网络拓扑不正确、网络插件故障、网络设备故障等。

常见原因

以下是一些可能导致容器网络故障的常见原因:

  • Pod IP 地址冲突:如果两个 Pod 具有相同的 IP 地址,则将发生 IP 地址冲突,这可能导致容器网络故障。
  • 网络插件故障:Kubernetes 使用不同的网络插件来实现容器网络,例如 Flannel、Calico 等。如果网络插件出现故障,可能会导致容器网络故障。
  • 网络设备故障:如果网络设备出现故障,例如交换机、路由器、防火墙等,可能会导致容器网络故障。
  • 网络配置错误:如果网络配置不正确,例如子网掩码、网关、DNS 等配置错误,可能会导致容器网络故障。
  • 网络拓扑不正确:如果网络拓扑不正确,例如存在网络分区或防火墙规则阻止了容器之间的通信,可能会导致容器网络故障。

解决方案

1. 确认容器是否已正确启动并运行,并且是否已被正确配置为使用正确的网络。

  • 执行命令,确认 Pod 是否已正确启动并运行。 kubectl get pods
  • 执行命令,确认容器的网络配置是否正确。 kubectl describe pod <pod-name>
k8s网络故障排查思路

2. 检查 Pod 和容器的网络配置,例如 IP 地址、子网掩码、网关、DNS 等是否正确配置。

  • 执行命令查看容器的网络配置信息。kubectl describe pod <pod-name>
  • 执行命令 ,查看容器的网络接口信息。kubectl exec <pod-name> -- ifconfig

3. 检查网络插件是否正常工作,并尝试重启网络插件。

  • 如果使用 Flannel 网络插件,执行命令 查看 Flannel 的日志信息。kubectl logs -n kube-system -l k8s-app=flannel
  • 如果使用 Calico 网络插件,执行命令,查看 Calico 的日志信息。 kubectl logs -n kube-system -l k8s-app=calico-node
k8s网络故障排查思路
  • 重启网络插件:如果使用 Flannel 网络插件,执行命令 kubectl delete pod -n kube-system -l k8s-app=flannel
  • 如果使用 Calico 网络插件,执行命令 kubectl delete pod -n kube-system -l k8s-app=calico-node

4 检查网络设备是否正常工作,例如交换机、路由器、防火墙等是否出现故障。

  • 检查网络设备的日志或配置信息,确认网络设备是否正常工作。

5. 尝试使用 Kubernetes 工具进行诊断,例如 kubectl,以查看 Pod 和容器的状态和日志。

  • 执行命令,查看容器的日志信息。kubectl logs <pod-name>
k8s网络故障排查思路
  • 执行命令 ,查看容器的状态信息。kubectl describe pod
k8s网络故障排查思路

6. 如果以上方法无法解决问题,可以考虑重新部署容器网络或更换网络插件。

  • 如果使用 Flannel 网络插件,执行命令 重新部署 Flannel 网络插件。
kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml && kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml,
  • 如果使用 Calico 网络插件,执行命令重新部署 Calico 网络插件。
 kubectl delete -f https://docs.projectcalico.org/manifests/calico.yaml && kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

1.2 网络插件故障

Kubernetes中的网络插件是负责容器网络连接与管理的重要组件之一。网络插件的故障可能会导致容器之间无法通信、网络延迟等问题。

常见原因 

下面是几种可能导致网络插件故障的情况:

  • 网络插件配置错误:网络插件的配置文件可能存在错误,例如配置了错误的IP地址、子网掩码、网关、DNS等信息,这可能导致容器无法正确连接到网络。
  • 网络插件版本不兼容:Kubernetes的版本更新可能会导致网络插件版本不兼容,从而导致网络插件故障。
  • 网络插件容器故障:网络插件通常运行在Kubernetes集群中的容器中,如果容器出现故障,可能会导致网络插件无法正常工作。
  • 网络设备故障:网络插件需要依赖底层的网络设备,例如交换机、路由器、防火墙等,如果这些网络设备出现故障,可能会导致网络插件无法正常工作。

当网络插件故障时,可能会出现以下一些常见问题:

  • 容器之间无法通信:当网络插件故障时,可能导致容器之间无法互相通信,这可能会影响应用程序的正常运行。
  • 网络延迟增加:当网络插件故障时,容器之间的网络延迟可能会增加,这可能会影响应用程序的性能。
  • 网络连接不稳定:当网络插件故障时,网络连接可能会不稳定,这可能会导致容器之间的连接断开或丢失数据包。

解决方案

  • 解决网络插件故障的方法取决于具体的故障原因,以下是一些常见的解决方法:
  • 检查网络插件的配置文件:如果网络插件的配置文件存在错误,可以通过检查和修改配置文件来解决问题。例如,可以检查IP地址、子网掩码、网关、DNS等信息是否正确配置。
  • 升级或降级网络插件版本:如果网络插件版本不兼容,可以尝试升级或降级网络插件版本来解决问题。建议在升级或降级前备份网络插件的配置文件,以避免数据丢失。
  • 重启网络插件容器:如果网络插件容器出现故障,可以尝试重启容器来解决问题。例如,可以使用kubectl命令重启网络插件的Pod。
  • 检查网络设备是否正常工作:如果网络插件依赖的底层网络设备出现故障,可以通过检查网络设备的日志或配置信息来解决问题。例如,可以检查交换机、路由器、防火墙等网络设备的日志或配置信息,确认网络设备是否正常工作。
  • 重新部署网络插件:如果以上方法无法解决问题,可以考虑重新部署网络插件。例如,可以使用kubectl命令删除网络插件的Pod和Service,然后重新部署网络插件。在重新部署前建议备份网络插件的配置文件,以避免数据丢失。

 解决网络插件故障常用命令

检查网络插件的Pod是否正常运行:kubectl get pods -n <namespace>

k8s网络故障排查思路

查看网络插件的Pod的详细信息:kubectl describe pod <pod-name> -n <namespace>

k8s网络故障排查思路

查看网络插件的日志信息:kubectl logs <pod-name> -n <namespace>

k8s网络故障排查思路

重启网络插件的Pod:kubectl delete <pod-name> pod -n <namespace>

检查集群的网络配置:kubectl cluster-info dump

检查节点的网络配置:kubectl describe node <node-name>

k8s网络故障排查思路

检查Flannel的日志信息:kubectl logs -n kube-system -l k8s-app=flannel

重启Flannel的Pod:kubectl delete pod -n kube-system -l k8s-app=flannel

检查Calico的日志信息:kubectl logs -n kube-system -l k8s-app=calico-node

重启Calico的Pod:kubectl delete pod -n kube-system -l k8s-app=calico-node

1.3 网络策略故障

Kubernetes中的网络策略(Network Policy)是用于控制容器间网络流量的重要组件之一。网络策略可以定义允许或禁止容器间的网络连接,从而增强了容器间网络的安全性。如果网络策略出现故障,可能会导致容器无法正常通信,网络安全性受到威胁等问题。

查看所有网络策略:kubectl get networkpolicies --all-namespaces
查看网络策略的详细信息:kubectl describe networkpolicy <network-policy-name> -n <namespace>
检查网络策略的规则是否正确:kubectl get networkpolicy <network-policy-name> -n -o yaml
检查容器是否正确标记:kubectl get pods --selector=<label-selector> -n <namespace> -o wide
检查容器的端口是否正确配置:kubectl get pods <pod-name> -n -o yaml
检查节点是否正确配置:kubectl get nodes -o wide
检查网络设备是否正常工作:kubectl logs <network-device-pod-name> -n <namespace>
如果你的Kubernetes集群使用的是Calico网络策略,你可以使用以下命令:
查看所有Calico网络策略:kubectl get networkpolicies.projectcalico.org --all-namespaces
查看Calico网络策略的详细信息:kubectl describe networkpolicy <network-policy-name> -n <namespace>
检查Calico网络策略的规则是否正确:kubectl get networkpolicy <network-policy-name> -n <namespace> -o yaml
检查Calico网络设备是否正常工作:kubectl logs -n kube-system -l k8s-app=calico-node

1.4 DNS 故障

常见原因

以下是几种可能导致DNS故障的情况:

  • DNS配置错误:Kubernetes中的DNS服务需要正确配置才能正常工作,例如需要配置正确的域名服务器、搜索域等信息。如果DNS配置存在错误,可能会导致DNS服务无法正常工作。
  • DNS版本不兼容:Kubernetes的版本更新可能会导致DNS版本不兼容,从而导致DNS故障。
  • 网络连接不稳定:网络连接不稳定可能会导致DNS服务无法正常解析域名。
  • 容器网络配置错误:如果容器的网络配置存在错误,可能会导致容器无法正确连接到DNS服务,从而导致DNS故障。

常见问题

当DNS服务出现故障时,可能会出现以下一些常见问题:

  • 容器无法正确解析域名:当DNS服务故障时,容器无法正确解析域名,这可能会影响应用程序的正常运行。
  • DNS解析延迟:当DNS服务故障时,DNS解析可能会变得缓慢,这可能会导致容器之间的通信延迟。
  • 容器网络连接不稳定:当DNS服务故障时,网络连接可能会不稳定,这可能会导致容器之间的连接断开或丢失数据包。
  • 为了避免DNS故障导致的问题,需要定期对DNS服务进行检查和维护,确保其正常工作。同时,还需要备份DNS的配置文件,并了解网络设备的故障排除方法,以便快速解决问题。

解决方案

检查网络设备是否连通:可以使用ping命令检查网络设备是否连通,例如:ping <network-device-ip> 如果网络设备无法连通,可能是网络设备的IP地址或网络配置存在问题。

检查网络设备的日志信息:可以通过查看网络设备的日志信息来了解网络设备的工作情况,例如:kubectl logs <network-device-pod-name> -n <namespace>

检查网络设备的配置信息:可以通过查看网络设备的配置信息来了解网络设备是否正确配置,例如:kubectl exec -it <network-device-pod-name> -n <namespace> -- <command> <arguments>

检查网络设备的版本信息:可以通过查看网络设备的版本信息来了解网络设备是否需要升级,例如:kubectl exec -it <network-device-pod-name> -n <namespace> -- <command> <arguments>

检查网络设备的连接状态:可以通过查看网络设备的连接状态来了解网络设备的工作情况,例如:kubectl exec -it <network-device-pod-name> -n <namespace> -- <command> <arguments>

3 纵向解决思路(推荐)

Pod 网络异常

网络异常大概分为如下几类:

  • 网络不可达,主要现象为 ping 不通,其可能原因为:
    • 源端和目的端防火墙(iptables, selinux)限制
    • 网络路由配置不正确
    • 源端和目的端的系统负载过高,网络连接数满,网卡队列满
    • 网络链路故障
  • 端口不可达:主要现象为可以 ping 通,但 telnet 端口不通,其可能原因为:
    • 源端和目的端防火墙限制
    • 源端和目的端的系统负载过高,网络连接数满,网卡队列满,端口耗尽
    • 目的端应用未正常监听导致(应用未启动,或监听为 127.0.0.1 等)
  • DNS 解析异常:主要现象为基础网络可以连通,访问域名报错无法解析,访问 IP 可以正常连通。其可能原因为
    • Pod 的 DNS 配置不正确
    • DNS 服务异常
    • pod 与 DNS 服务通讯异常
  • 大数据包丢包:主要现象为基础网络和端口均可以连通,小数据包收发无异常,大数据包丢包。可能原因为:
    • 可使用 ping -s 指定数据包大小进行测试
    • 数据包的大小超过了 docker、CNI 插件、或者宿主机网卡的 MTU 值。
  • CNI 异常:主要现象为 Node 可以通,但 Pod 无法访问集群地址,可能原因有:
    • kube-proxy 服务异常,没有生成 iptables 策略或者 ipvs 规则导致无法访问
    • CIDR 耗尽,无法为 Node 注入 PodCIDR 导致 CNI 插件异常
    • 其他 CNI 插件问题

那么整个 Pod 网络异常分类可以如下图所示:

k8s网络故障排查思路

总结:Pod 最常见的网络故障有,网络不可达(ping 不通);端口不可达(telnet 不通);DNS 解析异常(域名不通)与大数据包丢失(大包不通)

二、常用网络排查工具

关于抓包节点和抓包设备的抓包方式

  • 抓包节点:通常情况下会在源端和目的端两端同时抓包,观察数据包是否从源端正常发出,目的端是否接收到数据包并给源端回包,以及源端是否正常接收到回包。如果有丢包现象,则沿网络链路上各节点抓包排查。例如,A 节点经过 C 节点到 B 节点,先在 AB 两端同时抓包,如果 B 节点未收到 A 节点的包,则在 C 节点同时抓包。
  • 抓包设备:对于 Kubernetes 集群中的 Pod,由于容器内不便于抓包,通常视情况在 Pod 数据包经过的 veth 设备,docker0 网桥,CNI 插件设备(如 cni0,flannel.1 etc..)及 Pod 所在节点的网卡设备上指定 Pod IP 进行抓包。选取的设备根据怀疑导致网络问题的原因而定,比如范围由大缩小,从源端逐渐靠近目的端,比如怀疑是 CNI 插件导致,则在 CNI 插件设备上抓包。从 pod 发出的包逐一经过 veth 设备,cni0 设备,flannel0,宿主机网卡,到达对端,抓包时可按顺序逐一抓包,定位问题节点。

1、tcpdump

详见 tcpdump使用

捕获流量输出为文件
-w 可以将数据包捕获保存到一个文件中以便将来进行分析。这些文件称为 PCAP(PEE-cap)文件,它们可以由不同的工具处理,包括 Wireshark
tcpdump port 80 -w capture_file

2.nsenter

详见 Kubernetes常见的网络抓包思路

3.paping

paping 命令可对目标地址指定端口以 TCP 协议进行连续 ping,通过这种特性可以弥补 ping ICMP 协议,以及 nmap、telnet 只能进行一次操作的的不足;通常情况下会用于测试端口连通性和丢包率。

RedHat/CentOS:yum install -y libstdc++.i686 glibc.i686

4.mtr

mtr 是一个跨平台的网络诊断工具,将 traceroute 和 ping 的功能结合到一个工具中。与 traceroute 不同的是 mtr 显示的信息比起 traceroute 更加丰富:通过 mtr 可以确定网络的条数,并且可以同时打印响应百分比以及网络中各跳跃点的响应时间。

下面是一些常见的mtr命令参数:

-c <count>:设置要发送的数据包数。
mtr -c 10 google.com
-r:显示IP地址而不是主机名。
mtr -r google.com
-n:禁用DNS解析,只显示IP地址。
mtr -n 8.8.8.8
-b:以批处理模式运行,输出结果以可编辑格式打印。
mtr -b google.com > output.txt
-s <packet size>:设置要发送的ICMP数据包大小。
mtr -s 1500 google.com
-t <ttl>:设置初始TTL值。
mtr -t 5 google.com
-u:使用UDP协议而不是默认的ICMP协议。
mtr -u google.com
-T, --tcp:使用TCP SYN数据包而不是ICMP ECHO。使用该选项的话会忽略修改数据包大小的-s、--psize或者PACKETSIZE,因为SYN数据包不包含数据。

最简单的示例,就是后接域名或 IP,这将跟踪整个路由。

mtr www.baidu.com

k8s网络故障排查思路

如果需要指定次数,并且在退出后保存这些数据,使用 -r

mtr -r -c 5 www.baidu.com >  mtr.log
k8s网络故障排查思路

输出结果

Loss%:丢包率。
Snt:已发送的数据包。 
Last:最近一次探测到达此地址的时间延迟值(时间单位均是毫秒)
Avg:探测到达此地址时间延迟平均值,计将所有数据相加并除以数据集中的观测次数。
Best:探测到达此地址时间延迟最佳值,通常指数据集中的最小值或最大值,具体取决于分析的问题和目的。
Wrst:探测到达此地址时间延迟最差值,通常指数据集中的最大值或最小值,具体取决于分析的问题和目的。
StDev:标准偏差,是测量数据集中数据离其平均值的距离的一种方式,它告诉我们数据分布的紧密程度。如果标准差较大,则表示数据点不集中于平均值周围;如果标准差较小,表示数据点比较集中,这个值越小延时越稳定。

丢包判断:

任一节点的 Loss%(丢包率)如果不为零,则说明这一跳网络可能存在问题。导致相应节点丢包的原因通常有两种。

  • 运营商基于安全或性能需求,人为限制了节点的 ICMP 发送速率,导致丢包。
  • 节点确实存在异常,导致丢包。可以结合异常节点及其后续节点的丢包情况,来判定丢包原因。

Notes:

  • 如果随后节点均没有丢包,则通常说明异常节点丢包是由于运营商策略限制所致。可以忽略相关丢包。
  • 如果随后节点也都出现丢包,则通常说明节点确实存在网络异常,导致丢包。对于这种情况,如果异常节点及其后续节点连续出现丢包,而且各节点的丢包率不同,则通常以最后几跳的丢包率为准。如链路测试在第 5、6、7 跳均出现了丢包。最终丢包情况以第 7 跳作为参考。

某个跃点(hop)的位置出现三个问号“???”

这通常表示该节点(路由器)没有响应ICMP(Internet Control Message Protocol)请求。ICMP是用于在IP网络上发送控制消息的协议,而MTR使用ICMP来执行跟踪路由的功能。

有几种可能的原因导致节点不响应ICMP请求:

  1. 防火墙设置: 节点可能配置了防火墙规则,阻止了ICMP请求的传输。这是一种常见的安全配置,尤其是在公共网络中。
  2. 网络故障: 有可能存在网络故障,导致节点无法正确处理或响应ICMP请求。这可能是由于网络设备故障、网络拥塞或其他问题引起的。
  3. 路由策略: 节点可能配置了路由策略,不允许通过MTR的路径进行通信。这是一种安全和隐私保护的做法。

具体案例:首先mtr www.baidu.com

k8s网络故障排查思路

这里我们国内访问:mtr www.onlinesim.io

k8s网络故障排查思路

然后mtr测试

k8s网络故障排查思路

国外最后一跳可能会有少许丢包,这是正常的

延迟判断:

由于链路抖动或其它因素的影响,节点的 Best 和 Worst 值可能相差很大。而 Avg(平均值)统计了自链路测试以来所有探测的平均值,所以能更好的反应出相应节点的网络质量。

而 StDev(标准偏差值)越高,则说明数据包在相应节点的延时值越不相同(越离散)。所以标准偏差值可用于协助判断 Avg 是否真实反应了相应节点的网络质量。

例如,如果标准偏差很大,说明数据包的延迟是不确定的。可能某些数据包延迟很小(例如:25ms),而另一些延迟却很大(例如:350ms),但最终得到的平均延迟反而可能是正常的。所以此时 Avg 并不能很好的反应出实际的网络质量情况。

这就需要结合如下情况进行判断:

  • 如果 StDev 很高,则同步观察相应节点的 Best 和 wrst,来判断相应节点是否存在异常。
  • 如果 StDev 不高,则通过 Avg 来判断相应节点是否存在异常。

三、Pod 网络排查流程

k8s集群中的网络通信主要有以下几种:

1、同一个pod内的多个容器之间的网络通信

pod自身网络出现问题,会导致pod中的多个容器通信出现异常,具体排查网络组件

2、pod与pod之间的网络通信。

pod与pod之间通信故障是经常会出现的现象,可以排查网络组件Calico和kube-proxy这两个组件

3、pod与Node节点之间的通信故障

当出现此故障时,一般都是Calico网络组件产生了问题,需要排查具体日志

4、Service资源与集群外部的通信

检查网络插件、kube-proxy和服务发现配置等问题

k8s网络故障排查思路

四、案例学习

192.168.1.10k8s-masterk8s-master 节点
192.168.1.11k8s-node1k8s-node1 节点
192.168.1.12k8s-node2k8s-node2 节点(本次 nginx 服务 pod 所在 节点)
  • CNI 插件:flannel vxlan
  • kube-proxy 工作模式为 iptables
  • nginx 服务

1.外部网络访问nginx service地址不通

问题:使用deployment部署了一个nginx,然后通过service通过NodePort 方式暴露 80端口,名称为nginx-expose,找到pod所在节点上,但是通过映射的30897端口不通

k8s网络故障排查思路
k8s网络故障排查思路

先来熟悉下Service工作逻辑:

k8s网络故障排查思路

步骤一:是否通过CoreDNS服务访问的内部服务?

如果你是访问的Service名称,需要确保CoreDNS服务已经部署

k8s网络故障排查思路

确认CoreDNS已部署,如果状态不是Running,请检查容器日志进一步查找问题。

测试pod DNS解析是否正常

获取kube-dns pod地址并使用dig或者是nslookup解析,查看是否可以成功解析到service的地址

kubectl get svc -n kube-system
dig -t -A nginx-expose.default.svc.cluster.local @10.96.0.10
nslookup  nginx-expose.default.svc.cluster.local  10.96.0.10
k8s网络故障排查思路
k8s网络故障排查思路

接下来创建一个临时Pod使用nslookup解析相对名称测试下DNS解析是否正常:

k8s网络故障排查思路

如果你能使用完全限定的名称查找,但不能使用相对名称,则需要检查 /etc/resolv.conf 文件是否正确:

k8s网络故障排查思路

说明:

  • nameserver:行必须指定CoreDNS Service,它通过在kubelet设置 --cluster-dns 参加自动配置。
  • search :行必须包含一个适当的后缀,以便查找 Service 名称。在本例中,它在本地 Namespace(default.svc.cluster.local)、所有 Namespace 中的 Service(svc.cluster.local)以及集群(cluster.local)中查找服务。
  • options :行必须设置足够高的 ndots,以便 DNS 客户端库优先搜索路径。在默认情况下,Kubernetes 将这个值设置为 5。

步骤二:是否通过 Service IP访问

假设可以通过Service名称访问(CoreDNS正常工作),那么接下来要测试的 Service 是否工作正常。从集群中的一个节点,访问 Service 的 IP:

k8s网络故障排查思路

如果 Service 是正常的,你应该看到正确的状态码。如果没有,有很多可能出错的地方,请继续。

步骤二排查问题思路:

思路1:Service 端口配置是否正确?

检查 Service 配置和使用的端口是否正确:

kubectl get svc nginx-expose -o yaml

k8s网络故障排查思路

这里重点关注targetPort是否和容器默认暴露端口一致

思路2:Service 是否正确关联到Pod?

k8s网络故障排查思路

在 Kubernetes 系统中有一个控制循环,它评估每个 Service 的选择器,并将结果保存到 Endpoints 对象中。

k8s网络故障排查思路

结果所示, endpoints 控制器已经为 Service 找到了 Pods。但并不说明关联的Pod就是正确的,还需要进一步确认Service 的 spec.selector 字段是否与Deployment中的 metadata.labels 字段值一致。

kubectl get svc nginx-expose -o yaml | grep -A 1 labels:
kubectl get deployment nginx --show-labels
k8s网络故障排查思路

思路3:Pod 是否正常工作?

检查Pod是否正常工作,绕过Service,直接访问Pod IP:

kubectl get pod nginx -o wide

k8s网络故障排查思路

如果不能正常响应,说明容器中服务有问题, 这个时候可以用kubectl logs查看日志或者使用 kubectl exec 直接进入 Pod检查服务。

这里我们可以先通过ksniff抓包进行判断

kubectl sniff nginx-85b98978db-59mc4 -n default

k8s网络故障排查思路

可见,建立TCP三次握手时,服务器主动拒绝连接,这里只能检测pod内container相关问题了

kubectl debug -it nginx-85b98978db-59mc4 --image=nicolaka/netshoot
k8s网络故障排查思路

这里发现容器内部居然开了82端口,而不是80端口,最后通过登陆main container后修改nginx相关配置文件/etc/nginx/conf.d/default.conf的默认监听端口,问题才解决,但是希望继续看下后续排错步骤

k8s网络故障排查思路
k8s网络故障排查思路

除了本身服务问题外,还有可能是CNI网络组件部署问题,现象是:curl访问10次,可能只有两三次能访问,能访问时候正好Pod是在当前节点,这并没有走跨主机网络。

如果是这种现象,检查网络组件运行状态和容器日志:

kubectl get pods -n kube-flannel -o wide
kubectl -n kube-flannel logs kube-flannel-ds-4zwrm
k8s网络故障排查思路

思路4:kube-proxy 组件正常工作吗?

如果到了这里,你的 Service 正在运行,也有 Endpoints, Pod 也正在服务。

接下来就该检查负责 Service 的组件kube-proxy是否正常工作。

登陆pod所在节点,确认 kube-proxy 运行状态:

ps -ef |grep kube-proxy

k8s网络故障排查思路

如果有进程存在,下一步确认它有没有工作中有错误,比如连接主节点失败。

要做到这一点,必须查看日志。查看日志方式取决于K8s部署方式,如果是kubeadm部署,直接查看业务pod所在节点上的kube-proxy日志:

kubectl -n kube-system logs kube-proxy-krqkb

如果是二进制方式部署:journalctl -u kube-proxy

思路5:kube-proxy 是否在写 iptables 规则?

kube-proxy 的主要负载 Services 的 负载均衡 规则生成,默认情况下使用iptables实现,检查一下这些规则是否已经被写好了。

iptables-save | grep nginx-expose

k8s网络故障排查思路

如果你已经讲代理模式改为IPVS了,可以通过ipvsadm -ln方式查看

2.k8s pod之间访问不通

这种问题范围也比较大,排查思路具体如下

1、pod 与所在宿主机网络不通
2、pod 与同主机 pod 网络不通
3、pod 与跨主机网络不通
5、pod 通过 svc 访问 pod 网络不通(这种和上一种问题类似,在这里就不讲了)

这里以跨主机网络问题为例进行讲解

问题:这里我们跑一个busybox在另一台node上,想要通过跨节点方式访问nginx的服务,但是两个node网络不通,为了模拟实验故障,我们将nginx所在的节点上的flannel.1关闭:ifconfig down flannel.1,并将nginx内部默认监听端口修改成82

kubectl run busybox --image=busybox -- sleep 36000

k8s网络故障排查思路
k8s网络故障排查思路

这里先给一张网络拓扑图感受下

k8s网络故障排查思路

使用netshoot进入容器,两端同时抓包,此时显示只有busybox发送包,nginx所在的pod没有包信息

k8s网络故障排查思路

此时我们退一步,尝试ping nginx pod所在节点cni0接口IP地址

k8s网络故障排查思路

这里发现依然没有回应。那么问题继续往前找

k8s网络故障排查思路

此时,再尝试下ping nginx pod所在节点的ip地址,发现有回应了

k8s网络故障排查思路

那么基本可以确定是nginx pod所在节点的flannel.1接口出现问题了,在nginx pod所在node,使用过ifconfig发现flannel.1消失不见

再恢复之前,我们先看下路由规则,busybox pod所在节的路由规则将目标流量发送给了flannel.1进行udp封装,到达对面网卡后进行拆封,相同node中pod路由只需要经过cni0网卡即可

k8s网络故障排查思路
k8s网络故障排查思路

然而在nginx所在的node上面,flannel.1接口找不到,应该是挂掉了,路由规则也没有flannel.1

k8s网络故障排查思路

将nginx所在node上的flannel pod删除掉,发现重新恢复了!

k8s网络故障排查思路
k8s网络故障排查思路

此时再用ping进行测试,ping成功

k8s网络故障排查思路

上面的方法可以使用直接登陆目标所在的node,然后获取接口路径,分别在cni0、flannel.1、ens33上双向侦听网络流量状况

解决了ping的问题后,下面解决TCP端口不通问题,如果curl nginx的podIP,网络监测TCP没有成功握手

k8s网络故障排查思路

此时,我们在外面网卡设备监听流量分析,两边流量其实是通的,只是被拒绝掉了,所以只需要进入nginx 所在的pod中差错即可,若pod是通过service访问另外的pod,根据上个案例查错即可

下面是TCP握手成功后流量展示

k8s网络故障排查思路

发布者:LJH,转发请注明出处:https://www.ljh.cool/39758.html

(1)
上一篇 2024年1月11日 下午3:43
下一篇 2024年1月15日 下午5:18

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注