LabHub
学习 学习路径 课程

网络排障

怎么读 ss 的输出,以及绑定地址的陷阱

在 LabHub 中继续学习

一句话总结

ss -ltnp一句话说,如果忽略了“在听什么”和“在听谁”,那么远程连接故障就有一半是由于忽略了后者。

概念图: 回环中 · connection refused · 绑定地址 · Recv-Q和Send-Q根据状态会有不同的含义。

为什么需要这个?

让我们看看最常见的分配事故。

LISTEN  0  4096  127.0.0.1:8080  0.0.0.0:*  users:(("api",pid=1,fd=7))

这个过程只在回环中听。在同一个主机上curl localhost:8080成功了。但是用其他主机或pad IP连接的话,内核会以RST拒绝。也就是说,会出现connection refused

在这里判断分歧。用pad IP的话是refused,但如果pad内部用localhost的话成功的话,原因不是网络政策,而是绑定地址。相反,如果用pad IP的话也是timeout的话,从那时开始看NetworkPolicy和CNI。这一次分歧将调查范围缩小了一半。

每个框架都确定了容易犯错的点。

框架 安全的标记 错误标记
Express app.listen(8080) app.listen(8080, '127.0.0.1')
Go net/http ":8080" "localhost:8080"
Gunicorn --bind 0.0.0.0:8000 --bind 127.0.0.1:8000
Rails -b 0.0.0.0 基本值(仅限本地)
PostgreSQL listen_addresses = '*' 基本值localhost

怎么行动

ss的选项是数一数二的。

ss -ltnp                      # 리슨 중인 TCP + 프로세스
ss -tulpn                     # TCP/UDP 리슨 전체
ss -s                         # 소켓 총계 (누수 판별)
ss -tan state established     # 확립된 연결만
ss -tanp state syn-sent       # 나갔는데 응답 없는 연결
ss -tnio                      # rto/rtt/cwnd 같은 타이머까지

选项的意思:-tTCP,-uUDP,-l李森万,-a全部,-n不解释名字,-p过程。

**Recv-Q和Send-Q根据状态会有不同的含义。**这个经常出现在考试中。

套接字状态 Recv-Q Send-Q
LISTEN accept 等待中的完成队列长度 后台日志最大值
ESTABLISHED 尚未读取的接收数据 尚未确认的发送数据

LISTEN套接字的Recv-Q与Send-Q相连的话,意味着accept队列满了。这时nstat -az | grep -E 'ListenOverflows|ListenDrops'如果增加的话,不是网络而是应用程序处理量的原因。无论如何搜索防火墙都找不到。

整理一下按TCP状态进行的运营评价吧。

/proc/net/tcp也最好知道直接读的方法。在没有工具的最小容器中成为最后的手段。本地地址是小端16进制,端口也是16进制(8080 =1F90),状态栏的0A是LISTEN。

在现场相遇的样子

**将refused归咎于防火墙的吴珍。**实际防火墙几乎总是DROP政策,所以被阻止的端口会进入timeout。除非故意使用了回RST的REJECT规则,否则refused的意思是“已经走了,但没有人听”。

**当Kubernetes Endpoints为空时。**如果附加到服务IP上,就会立即被拒绝。kubectl get endpoints <svc><none>如果这个,选择器不对,或者readynessProbe正在失败。不是网络的问题,是标签的问题。

ss按一行缩小的顺序

查看网络问题时netstat相反ss使用的话,可以快速提取所需的内容。 有。如果确定经常使用的形式,调查时间就会大大缩短。

ss -tlnp                       # 듣고 있는 TCP 와 그 프로세스
ss -tanp state established '( dport = :5432 or sport = :5432 )'
ss -s                          # 상태별 요약
ss -tin                        # rtt, cwnd, 재전송 — 성능을 볼 때

在听筒上Recv-Q/Send-Q的意思不同。在连接的插座上,分别 虽然是未读的数据和未发送的数据,但在听取的套接字中,目前accept队列 是长度和其上限。如果两个数字相连的话,应用程序就无法接收连接。 是中,这时内核会丢弃完成的连接。

nstat -az | grep -E 'ListenDrops|ListenOverflows|TCPBacklogDrop'

看看在哪里绑定了。127.0.0.1:8080不能从外面进来。集装箱 最常见的情况是将数据包绑定在内部的环形包中,然后说“端口无法打开”。 0.0.0.0伊娜*要出来才能在外面接触到。

连接在哪个状态下停止是决定原因的。

状态 意思
SYN-SENT积攒 对方不回应(防火墙安静地被抛弃)
SYN-RECV堆积 我们这边accept队列或SYN队列问题
CLOSE-WAIT堆积 我们的应用程序不会close()
FIN-WAIT-2积攒 对方不关闭
TIME-WAIT很多 正常。60秒后消失

CLOSE-WAIT不是内核,而是指唯一指代我们代码的错误的状态。 特别重要。时间流逝也不会消失。

区分拒绝和无回应。Connection refused甚至去了对方主机 那个端口没有打开,超时是因为数据包丢失在某个地方。前面 的是服务问题,后面的是路由和防火墙问题。

下次实习要做的事情

启动两个服务器,但其中一个是0.0.0.0,一个是127.0.0.1然后绑定。然后用自己的IP敲打两个端口,直接制作为什么哪一个失败/proc/net/tcp也用手读。