Kubernetes排错(十)-常见网络故障排查

通用排查思路

Kubernetes 集群内不同服务之间的网络通信出现异常,表现为请求超时、连接失败或响应缓慢,导致服务间依赖关系中断,依赖服务的功能不可用或性能下降,甚至可能波及整个微服务架构,引发连锁反应,造成系统整体不稳定。

排查方法:

第一步:检查Pod网络配置与状态

查看Pod网络配置:

复制代码
kubectl describe pod -n <namespace>

这里要重点关注Events部分是否有网络配置相关的错误提示,以及IP地址是否已正确分配,如果没有异常则再检查Pod运行状态。

复制代码
kubectl get pods -n <namespace>

查看Pod是否处于Running状态,如果不是,检查其状态(如CrashLoopBackOff)并进一步分析日志。

第二步:网络连通性测试

这里主要还是通过常用的ping命令来测试。

进行Pod间连通性测试,在有问题的两个Pod中分别执行以下命令测试连通性,例如使用ping或nc(netcat)。

复制代码
# 在源Pod中执行
kubectl exec -it <source-pod-name> -n <namespace> -- ping <destination-pod-ip>

# 或者使用nc测试端口连通性
kubectl exec -it <source-pod-name> -n <namespace> -- nc -zv <destination-pod-ip> <port>
第三步:查看网络策略规则

如果以上都没有问题,则有可能是网络策略问题,执行如下命令确认是否有网络策略限制了Pod间的访问。

复制代码
kubectl get networkpolicies -n <namespace>

如果有相关策略,检查其spec-ingress和spec-egress规则,确保没有意外地拒绝了必要的通信。

第四步:检查Service配置
复制代码
kubectl describe service <service-name> -n <namespace>

kubectl get endpoints <service-name> -n <namespace>

再次执行上述命令来确认Service的类型、选择器、端口配置是否正确,并确保Service有对应的Endpoints,即后端Pod列表。

第五步:查看集群日志

根据异常Pod所在节点,检查节点上的kubelet、网络插件的日志,寻找有关网络配置、连接尝试或错误的信息。

复制代码
kubectl logs <problematic-pod-name> -n <namespace>

1 . Pod访问外部服务超时

现象: Pod尝试访问外部服务(如数据库或API)时超时。

原因分析:通常情况下是egress规则未正确设置,导致流量无法流出集群。

排查方法:

第一步:确认网络策略

首先,还是检查是否有网络策略限制了Pod访问外部网络,确保没有规则阻止Egress(外出)流量。

复制代码
kubectl get networkpolicies -n <namespace>
第二步:查看Pod网络配置

确认Pod的网络配置,尤其是iptables规则和路由表。进入Pod内部检查:

复制代码
kubectl exec -it <pod-name> -n <namespace> -- bash

在Pod内执行以下命令查看路由表:

复制代码
ip route

并检查iptables规则:

复制代码
iptables -L -nv
第三步:测试外部连接

直接在Pod中尝试访问外部服务,比如ping一个公共DNS服务器或测试端口连接:

复制代码
ping 8.8.8.8
nc -vz example.com 443
第四步:DNS解析测试

如果服务访问依赖域名,检查DNS解析是否正常:

复制代码
nslookup www.baidu.com
第五步:Egress配置检查

如果发现是因为网络策略限制了Egress流量,那么可以创建或修改一个网络策略来允许外部访问。例如,允许所有Egress流量的网络策略:

复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - {}

然后应用此策略:

复制代码
kubectl apply -f allow-egress.yaml -n <namespace>

生产环境中请确保根据实际情况调整策略,仅开放必要的端口和目标,保证系统的安全性。

2 . 服务ClusterIP不可达

现象: 服务的ClusterIP地址无法从集群内部访问。

原因分析: 服务的Kubernetes Service配置错误,或kube-proxy服务异常。

排查方法:

第一步:确认服务状态

检查服务是否已经创建并且状态正常:

复制代码
kubectl get svc -n <namespace>

需要确保服务存在且其类型为ClusterIP。

第二步:服务详情检查

查看服务的详细信息,重点关注ClusterIP、端口映射和Selector是否配置正确:

复制代码
kubectl describe svc <service-name> -n <namespace>

确认Endpoints列表中至少有一个Pod IP,这表明服务能够找到匹配的Pod。

第三步:验证DNS解析

在有问题的Pod中,尝试解析服务名以确认DNS是否工作正常:

复制代码
kubectl exec -it <problematic-pod-name> -n <namespace> -- nslookup <service-name>

此时正常来说应能看到服务对应的ClusterIP地址。

第四步:网络连通性测试

从问题Pod向服务的ClusterIP和端口发起ping或TCP连接测试:

复制代码
kubectl exec -it <problematic-pod-name> -n <namespace> -- bash -c "nc -zv <service-cluster-ip> <service-port>"
第五步:kube-proxy状态检查

kube-proxy负责服务的网络代理,确保它在所有节点上运行正常:

复制代码
kubectl get pods -n kube-system | grep kube-proxy

如果kube-proxy有问题,查看其日志:

复制代码
kubectl logs <kube-proxy-pod-name> -n kube-system
第六步:重启kube-proxy

如果以上都没有异常,作为最后的尝试,可以在所有节点上重启kube-proxy服务,可能会解决可能的临时问题,不过一定需要谨慎!:

复制代码
sudo systemctl restart kube-proxy

3 . Ingress 502 Bad Gateway

当使用Ingress资源时遇到502 Bad Gateway错误,这意味着Ingress控制器无法从后端服务正确接收响应。

第一步:检查Ingress资源配置

首先,确保Ingress资源配置正确,包括路径、服务名称、端口等:

复制代码
kubectl describe ingress <ingress-name> -n <namespace>
第二步:检查Ingress资源配置

检查关联的服务和Pod是否运行正常:

复制代码
kubectl get svc -n <namespace>
kubectl get pods -n <namespace>

确认Pod无CrashLoopBackOff或Error状态,服务有正确的端口映射和Selector。

第三步:检查Endpoints

验证服务是否绑定了正确的Pod:

复制代码
kubectl describe svc <service-name> -n <namespace>

在输出中查找Endpoints部分,确保有Pod IP列表。

第四步:查看Ingress控制器日志

根据使用的Ingress控制器(如Nginx Ingress Controller、Istio Ingress Gateway等),获取其日志以获取更多信息:

复制代码
# 对于Nginx Ingress Controller
kubectl logs -l app.kubernetes.io/name=ingress-nginx -n ingress-nginx

分析日志中是否有与502错误相关的错误信息或警告。

第五步:确认后端服务可达性

从Ingress所在节点或Pod内尝试直接访问后端服务,以排除网络问题:

复制代码
kubectl run -it --rm --restart=Never debug --image=busybox -- /bin/sh -n <namespace>

# 在新Pod中执行
nc -vz <backend-service-ip> <service-port>
第六步:重启Ingress控制器

如果上述步骤未解决问题,尝试重启Ingress控制器Pod:

复制代码
kubectl delete pod <ingress-controller-pod-name> -n <ingress-controller-namespace>

附:常用k8s排查命令

容器网络故障

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

执行命令,确认 Pod 是否已正确启动并运行。

复制代码
kubectl get pods

执行命令,确认容器的网络配置是否正确。

复制代码
kubectl describe pod <pod-name>

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

执行命令 ,查看容器的网络接口信息。

复制代码
kubectl exec <pod-name> -- ifconfig

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

如果使用 Flannel 网络插件,执行命令 查看 Flannel 的日志信息。

复制代码
kubectl logs -n kube-system -l k8s-app=flannel

如果使用 Calico 网络插件,执行命令,查看 Calico 的日志信息。

复制代码
kubectl logs -n kube-system -l k8s-app=calico-node

重启网络插件:如果使用 Flannel 网络插件,执行命令

复制代码
kubectl delete pod -n kube-system -l k8s-app=flannel

如果使用 Calico 网络插件,执行命令。

复制代码
kubectl delete pod -n kube-system -l k8s-app=calico-node

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

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

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

执行命令,查看容器的日志信息。

复制代码
kubectl logs <pod-name>

执行命令 ,查看容器的状态信息。

复制代码
kubectl describe pod <pod-name>

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

如果使用 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

网络策略故障

查看所有网络策略:

复制代码
kubectl get networkpolicies --all-namespaces

查看网络策略的详细信息:

复制代码
kubectl describe networkpolicy <network-policy-name> -n <namespace>

检查网络策略的规则是否正确:

复制代码
kubectl get networkpolicy <network-policy-name> -n <namespace> -o yaml

检查容器是否正确标记:

复制代码
kubectl get pods --selector=<label-selector> -n <namespace> -o wide

检查容器的端口是否正确配置:

复制代码
kubectl get pods <pod-name> -n <namespace> -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

DNS 故障

  • 检查网络设备是否连通:

    ping <network-device-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>

相关推荐
小马爱打代码37 分钟前
K8S - 蓝绿发布实战 - Argo Rollouts 零停机方案解析
云原生·容器·kubernetes
檀越剑指大厂3 小时前
【Docker系列】docker inspect查看容器部署位置
运维·docker·容器
A尘埃5 小时前
K8S有状态服务部署(MySQL、Redis、ES、RabbitMQ、Nacos、ZipKin、Sentinel)
redis·mysql·kubernetes
sg_knight6 小时前
Docker镜像搬运工:save与load命令的实战指南
docker·容器·备份与恢复·docker save·docker image备份
明仔丶7 小时前
开启docker中mysql的binlog日志
运维·docker·容器·binlog
维运8 小时前
【kubernetes】通过Sealos 命令行工具一键部署k8s集群
云原生·容器·kubernetes
bst@微胖子8 小时前
K8S扩缩容及滚动更新和回滚
云原生·容器·kubernetes
Mr.小怪12 小时前
K8s网络从0到1
网络·kubernetes·php
剑哥在胡说12 小时前
高并发PHP部署演进:从虚拟机到K8S的DevOps实践优化
kubernetes·php·devops
长勺15 小时前
Java云原生到底是啥,有哪些技术
java·开发语言·云原生