TT Lab
博客 开始
学习 学习路径 课程

Linux 网络诊断

分诊的顺序与记录

在 TT Lab 中继续学习

一句话总结

故障处理中的水平差距不在工具,而在顺序和记录。有了顺序,同一个地方就不会看两遍;有了记录,下一个人就不必从头开始。

为什么需要这个

凌晨 3 点接到报告,谁都会着急。一着急顺序就乱,顺序一乱,“刚才查过了吗?”这个问题就会反复出现。所以熟练的人会机械地遵循事先定好的顺序。判断要在收集完数据之后再做。

工作原理

顺序是从下往上。因为下层坏了,就没必要看上层。

  1. 名称 —— 并排执行 getent hosts <name> 和 dig +short <name>。两个结果不同,这个差异就是原因所在的位置。
  2. 可达 —— ping -c 3 <IP>。失败了也不要马上下结论,可能是 ICMP 被屏蔽。
  3. 端口 —— nc -zv -w 2 <IP> <port>。一定要区分并记录是 refused 还是 timeout。这一个词决定了下一步的排查方向。
  4. 绑定 —— 在目标主机上执行 ss -ltnp | grep <port>。如果 Local Address 是 127.0.0.1,答案就在这里。
  5. 应答 —— curl -o /dev/null -s -w '...'。同时查看状态码和各段时间。

每一步都要原样留下命令及其输出。 只写着“已确认”的记录对下一个人毫无价值。反过来,命令和输出附在一起,下一个人就能重新读那些输出,甚至得出不同的结论。

事后报告中至少要有以下五项。

项目 内容
症状 用户实际看到的现象(不是猜测)
层 卡在哪一层
原因 附上作为依据的命令输出
处理 改了什么、怎么改的
防止再发 怎样才能让同样的事不再发生

每一层要敲什么

缩小“不行”的范围有一个顺序。从下往上,每上一级候选就少一些。

层 确认命令 在这里失败时
1. 名称 getent hosts api.example.com DNS、/etc/hosts、搜索域
2. 路径 ip route get 10.0.3.12 路由、默认网关
3. 可达 ping -c1 10.0.3.12 ICMP 可能被屏蔽(失败了也继续下一步)
4. 端口 nc -zv 10.0.3.12 8080 或 curl -v telnet://… 防火墙、安全组、没有监听
5. 服务 curl -sv http://10.0.3.12:8080/healthz 应用

重要的是第 3 步失败了也不要停下。ICMP 经常被屏蔽,“ping 不通所以是网络问题”常常是错的。第 4 步才是真正的判定。

nc 的结果分为三种,各自含义不同。

光是区分这三种,排查范围就大不相同。

确认在哪里监听

出现 Connection refused 时,到服务器一侧查看。

ss -ltnp | grep 8080
LISTEN 0 4096 127.0.0.1:8080 0.0.0.0:* users:(("app",pid=42,fd=3))
                ↑ the trap is here

如果是 127.0.0.1:8080,只有自己能连到。 这就是容器内 curl localhost:8080 可以、外部却不行的典型原因。必须是 0.0.0.0:8080 或 [::]:8080,外部才能连上。

在应用配置中修改绑定地址(--host 0.0.0.0、bind = "0.0.0.0")。这一项错了,端口映射改得再对也没用。

Kubernetes 中还多一层

Pod 之间不通时,先怀疑网络策略。在设置了默认拒绝(default deny)的命名空间中,策略里没写的通信全部是 timeout。

kubectl -n <ns> get networkpolicy
kubectl -n <ns> describe networkpolicy <name>   # read from/to

如果症状是“有时可以”,要看的不是策略,而是端点。三个 Pod 中只要有一个不是 Ready,发往它的请求就会失败,从外部看就是间歇性错误。

kubectl -n <ns> get endpoints <svc>    # how many addresses are there?

在现场遇到的样子

假设原因只有一个。 实际故障往往是两个以上的原因叠加在一起。修好一个后说“没好啊”就转向别的方向,连已经修好的也会开始怀疑。所以把每一层都检查到底、把发现的都记下来,最终反而更快。

修完不验证。 改了 hosts 就要用 getent 再确认;改了绑定就要用外部地址再敲一遍。用同一条命令复现失败、再确认成功,才是处理的最后一步。

下一个实验要做的事

你会接到一个同时存在三个缺陷的故障。逐层缩小范围锁定原因,修复,并按规定的格式留下事后报告。