network error怎么解决(K8S常见故障排查指南)
发布于:2024-12-01 12:22:38
发布于:2024-12-01 12:22:38
故障排查思维导图
当你在 Kubernetes 中部署应用程序时,通常会定义三个组件:
在深入调试损坏的部署之前,必须对 Kubernetes 的工作原理有一个明确定义。
由于每个部署中都包含三个组件,因此我们应该从底部开始按顺序调试所有组件。
大多数时候,问题出在 Pod 本身上。
我们应该确保Pod Running且Ready。
如何检查?
kubectl get pods
NAME READY STATUS RESTARTS AGE
app1 0/1 ImagePullBackOff 0 47h
app2 0/1 Error 0 47h
app3-76f9fcd46b-xbv4k 1/1 Running 1 47h
在上面的输出中,最后一个 Pod 处于Running且Ready 状态,但是,前两个 Pod 既未Running也未Ready。
如何调查出了什么问题?
有四个有用的命令可用于对 Pod 进行故障排除:
那我们应该使用哪一个命令呢?
没有一种方法是放之四海而皆准的。
相反,我们应该使用它们的组合。
Pod 可能会出现启动和运行时错误。
启动错误包括:
运行时错误包括:
有些错误比其他错误更常见。
以下是最常见错误的列表以及如何修复这些错误。
当 Kubernetes 无法检索Pod的image时,会出现此错误。
常见的原因有以下三个:
前两种情况可以通过更正image名称和tag来解决。
最后,应该将私有镜像的凭据添加到Secret,并在Pod中引用它。
如果容器无法启动,Kubernetes 会显示 CrashLoopBackOff作为状态。
通常,容器在以下情况下无法启动:
这时,我们应该尝试从该容器日志来检查失败的原因。
如果由于容器重新启动太快而看不到日志,可以使用以下命令,它打印前一个容器的错误消息。
kubectl logs <pod-name> --previous
当容器无法启动时会出现该错误。
这甚至是在容器内的应用程序启动之前。
该问题通常是由于配置错误造成的,例如:
这时,应该用来kubectl describe pod <pod-name>检查和分析错误。
当创建 Pod 时,Pod 处于Pending状态。
假设调度程序组件运行良好,原因如下:
最好的选择是通过以下检查命令,查看Pod事件。
kubectl describe pod <pod name>
对于由于 ResourceQuotas 创建的错误,还可以使用以下命令检查集群的日志:
kubectl get events --sort-by=.metadata.creationTimestamp
如果 Pod 正在Running但Pending中,则意味着ReadinessProbe失败。
当ReadinessProbe失败时,Pod 不会加到Service,并且不会将任何流量转发到该实例。
失败的ReadinessProbe是特定于应用程序的错误,因此我们应该使用kubectl describe命令检查事件
如果 Pod 正在Running并Ready,但仍然无法收到应用程序的响应,则应该检查Service是否配置正确。
Service旨在根据 Pod 的label将流量路由到 Pod。
因此,我们应该检查的第一件事是该Service映射了多少个 Pod。
可以通过检查Service的Endpoints来执行此操作:
kubectl describe service my-service
Name: my-service
Namespace: default
Selector: app=my-app
IP: 10.100.194.137
Port: <unset> 80/TCP
TargetPort: 8080/TCP
Endpoints: 172.17.0.5:8080
Endpoint是一对<ip address:port>,并且应该至少有一个,当服务以(至少)一个 Pod 为目标时。如果Endpoints为空,则有两种解释:
如果看到Endpoints列表,但仍然无法访问应用程序,那么Service targetPort可能配置错误。
无论Service type是什么,都可以使用以下方式kubectl port-forward访问到。
kubectl port-forward service/<service-name> 3000:80
备注:
如果已检查到这部分,那么:
但仍然看不到应用程序的响应。
这意味着 Ingress 很可能配置错误。
由于 Ingress 控制器是集群中的第三方组件,因此根据 Ingress 控制器的类型有不同的调试方式。
但在深入了解 Ingress 检查工具之前,我们可以检查一些简单的内容。
Ingress 使用service.name和service.port访问到服务。
我们应该检查这些配置是否正确,还可以检查 Ingress 是否已正确配置:
kubectl describe ingress my-ingress
Name: my-ingress
Namespace: default
Rules:
Host Path Backends
---- ---- --------
*
/ my-service:80 (<error: endpoints "my-service" not found>)
如果Backend列为空,则配置中一定存在错误。
如果可以在Backend列中看到Endpoint,但仍然无法访问应用程序,则问题可能是:
首先,检查 Ingress 控制器的 Pod(可能位于不同的命名空间中):
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS
kube-system coredns-5644d7b6d9-jn7cq 1/1 Running
kube-system etcd-minikube 1/1 Running
kube-system kube-apiserver-minikube 1/1 Running
kube-system kube-controller-manager-minikube 1/1 Running
kube-system kube-proxy-zvf2h 1/1 Running
kube-system kube-scheduler-minikube 1/1 Running
kube-system nginx-ingress-controller-6fc5bcc 1/1 Running
通过describe pod检查端口:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system \
| grep Ports
Ports: 80/TCP, 443/TCP, 8443/TCP
Host Ports: 80/TCP, 443/TCP, 0/TCP
最后,访问到 Pod:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-system
Forwarding from 127.0.0.1:3000 -> 80
Forwarding from [::1]:3000 -> 80
此时,每次访问计算机上的 3000 端口时,请求都会转发到 Pod 上的 80 端口。
如果仍然无法让 Ingress 控制器工作,则应该开始调试它。
Ingress 控制器有许多不同版本。
流行的选项包括 Nginx、HAProxy、Traefik 等。
我们应该查阅 Ingress 控制器的文档以查找故障排查指南。
由于Ingress Nginx是最流行的 Ingress 控制器,因此我们在下面中提供了一些技巧。
Ingress-nginx 项目有一个Kubectl 的官方插件。
您可以用来kubectl ingress-nginx:
我们应该尝试的三个命令是:
请注意,您可能需要使用 为 Ingress 控制器指定正确的命名空间--namespace <name>。
如果我们不知道从哪里开始,在 Kubernetes 中进行故障排除可能是一项艰巨的任务。
我们应该始终记住自下而上地解决问题:从 Pod 开始,然后通过 Service 和 Ingress 向上排查。
在本文中学到的相同调试技术可以应用于其他对象,例如: