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>

相关推荐
chuanauc1 小时前
Kubernets K8s 学习
java·学习·kubernetes
小张是铁粉1 小时前
docker学习二天之镜像操作与容器操作
学习·docker·容器
烟雨书信1 小时前
Docker文件操作、数据卷、挂载
运维·docker·容器
IT成长日记1 小时前
【Docker基础】Docker数据卷管理:docker volume prune及其参数详解
运维·docker·容器·volume·prune
这儿有一堆花1 小时前
Docker编译环境搭建与开发实战指南
运维·docker·容器
LuckyLay1 小时前
Compose 高级用法详解——AI教你学Docker
运维·docker·容器
Uluoyu2 小时前
redisSearch docker安装
运维·redis·docker·容器
IT成长日记6 小时前
【Docker基础】Docker数据持久化与卷(Volume)介绍
运维·docker·容器·数据持久化·volume·
疯子的模样10 小时前
Docker 安装 Neo4j 保姆级教程
docker·容器·neo4j
虚伪的空想家11 小时前
rook-ceph配置dashboard代理无法访问
ceph·云原生·k8s·存储·rook