LabHub
学习 学习路径 课程

网络基础

读一读自己 Pod 的网络

在 LabHub 中继续学习

目标

只靠示意图学习网络,往往很难留下印象。现在亲自读取你正在使用的这个 Pod 的 网络

这里不是为教材特意搭建的示例,而是真正的生产集群,因此书本上没有的情况 也会原样出现——/32 地址、与接口不同的路径 MTU、search 域。

查看位置

ip -4 addr show eth0        # 내 주소
ip route                    # 어디로 나가나
ip route get 1.1.1.1        # 이 목적지로는 어떻게 가나
cat /sys/class/net/eth0/mtu # 인터페이스 MTU
cat /etc/resolv.conf        # 이름을 어떻게 푸나
ss -tan                     # 지금 연결 상태

实验服务器

python3 -m http.server 8080 --bind 127.0.0.1 &

步骤

  1. 地址和子网掩码 → 01-addr.txt
  2. 路由 → 02-route.txt
  3. MTU → 03-mtu.txt
  4. DNS → 04-dns.txt
  5. 端口冲突 → 05-port.txt
  6. 手写 HTTP → 06-http.txt
  7. 连接状态 → 07-states.txt
  8. 总结 → 08-notes.md

提示

这个 Pod **无法访问外部互联网。**只开放了 DNS 查询。 因此所有实验都使用这个 Pod 内的服务器进行——该学的内容一样都不会少。

我的地址和子网掩码

查看这个 Pod 的 IP 和子网掩码并保存到 01-addr.txt,再用一行说明这个子网掩码表示什么

ip -4 addr show eth0。应该会看到 /32

/32 表示这个网络中只有自己。通常会像 /24 那样在同一网段内存在邻居,但这里没有。那么如何访问外部,就是下一步的内容。

那么如何访问外部

导出路由表并保存到 02-route.txt,再说明即使是 /32,仍然可以到达网关的原因。

执行 ip route。应该会看到两行——default via <게이트웨이><게이트웨이> dev eth0 scope link

第二行就是答案。它告诉内核,该地址无需路由便可直接到达(on-link)。虽然根据子网掩码判断,它不在同一网段,但有了这条路由就能到达网关。

接口与路径的 MTU 不同

分别查看 eth0 的 MTU 与默认路径的 MTU,并保存到 03-mtu.txt。如果二者不同,也要写明原因。

接口使用 cat /sys/class/net/eth0/mtu 查看,路径使用 ip route get 1.1.1.1 查看。

接口 MTU 是 1500,而路径 MTU 应该更小。这是因为隧道会额外添加报头——这个集群通过加密隧道连接节点,因此能承载的数据大小也相应减少。

如果 MTU 设置错误,会出现小请求正常、大响应却停住的症状。这是最难排查的一类问题。

短名称如何解析

查看 /etc/resolv.conf,实际查询一个短名称,并把结果保存到 04-dns.txt

cat /etc/resolv.conf 中包含 nameserversearch。尝试像 getent hosts kubernetes.default 这样查询一个短名称

系统会把 search 中列出的域名按顺序追加后逐一尝试。也就是 kubernetes.defaultkubernetes.default.<네임스페이스>.svc.cluster.local → ……因此即使使用短名称也能找到目标。

一个端口只能有一个程序

在 8080 端口启动服务器后,尝试在同一个端口再启动一个,并把此时出现的错误保存到 05-port.txt

先用 python3 -m http.server 8080 --bind 127.0.0.1 & 启动一个服务器,再用 Python 尝试对同一个地址执行 bind

会出现 [Errno 98] Address already in use地址与端口的组合只能由一个程序占用。这就是‘端口已被占用’错误的本质。

手写 HTTP

不使用任何库,在 TCP 连接中直接写入 HTTP 请求字符串来接收响应,并把结果保存到 06-http.txt

只用 bash 就能完成。

exec 3<>/dev/tcp/127.0.0.1/8080
printf 'GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' >&3
timeout 3 head -8 <&3

每行末尾必须是 \r\n,并且在报头结尾还要额外加一个空行。HTTP 只不过是在 TCP 之上传递约定格式的文字。

连接具有状态

在建立和关闭连接的过程中,用 ss 观察状态如何变化,并把结果保存到 07-states.txt。必须能看到 TIME-WAIT

使用 ss -tan 查看。连接期间显示 ESTAB,关闭后则会保留一段时间的 TIME-WAIT

TIME-WAIT 不是错误。它会暂时保留位置,避免迟到的数据包混入下一个连接。在大量建立短连接的服务器中,它积累过多会耗尽端口——因此需要复用连接(keep-alive)。

总结三点

08-notes.md 中至少写三行:使用 /32 仍能通信的原因、MTU 不匹配时出现的症状,以及存在 TIME-WAIT 的原因。

正文中必须包含 경로MTUTIME-WAIT