K8s (Kubernetes, 容器编排系统) 容器网络排查的“瑞士军刀”:getent 与 curl 的妙用

🚀 K8s (Kubernetes, 容器编排系统) 容器网络排查的“瑞士军刀”:getent 与 curl 的妙用

在云原生时代,我们经常遇到这样的场景:应用在本地跑得好好的,一部署到 K8s (Kubernetes, 容器编排系统) 集群里,就报各种连接错误:Connection RefusedUnknown HostTimeout… 🤯

当我们兴冲冲地进入容器终端(Terminal)想排查时,却发现:

  • ping: command not found
  • telnet: command not found
  • nslookup: command not found
  • vi: command not found

绝望吗?别急! 大多数生产级的精简镜像(如 Alpine, Distroless, Slim)为了安全和体积,去掉了这些工具。但是,它们通常会保留两个不起眼但功能强大的“神器”:getentcurl

今天就来聊聊如何用这两个命令,在“徒手空拳”的情况下搞定网络排查。🛠️

📊 总结:排查工具速查表

工具命令主要用途替代的传统工具检查层级典型输出
getent hosts <域名>检查 DNS (Domain Name System, 域名系统) 解析nslookup, dig网络层 (IP (Internet Protocol, 互联网协议) 地址)IP (Internet Protocol, 互联网协议) 地址 + 域名
curl -v telnet://<IP>:<端口>检查 TCP (Transmission Control Protocol, 传输控制协议) 端口连通性telnet, nc传输层 (端口握手)Connected (成功) / Refused (被拒)

1. 🗺️ 问路神器:getent hosts (排查 DNS 问题)

在怀疑网络不通之前,首先要确认的是:“地址对不对?”

很多时候,连接失败是因为 DNS (Domain Name System, 域名系统) 解析出了旧的 IP (Internet Protocol, 互联网协议),或者根本解析不到 IP (Internet Protocol, 互联网协议)(比如 K8s (Kubernetes, 容器编排系统) 的 CoreDNS 挂了,或者阿里云 VPC (Virtual Private Cloud, 专有网络) 切换后的 DNS (Domain Name System, 域名系统) 缓存问题)。

为什么不用 nslookupdig

因为它们通常不在基础镜像里。而 getent (Get Entries) 是 Linux 标准库的一部分,几乎所有的 Linux 容器里都有它。它直接查询系统的 /etc/nsswitch.conf,告诉你操作系统当前到底“看”到了什么 IP (Internet Protocol, 互联网协议)

📝 使用方法

getent hosts <域名>

🌰 实战案例

假设你的应用连不上阿里云 Redis,域名是 r-2vc6...rds.aliyuncs.com

情况 A:DNS (Domain Name System, 域名系统) 解析正常

root@pod:/app# getent hosts r-2vc6...rds.aliyuncs.com
10.71.42.223    r-2vc6...rds.aliyuncs.com  <-- ✅ 只有一个 IP (Internet Protocol, 互联网协议),且是你预期的 VPC (Virtual Private Cloud, 专有网络) 内网段

情况 B:DNS (Domain Name System, 域名系统) 缓存污染 / 裂脑 (Split-Brain)
这正是我最近遇到的坑!阿里云 VPC (Virtual Private Cloud, 专有网络) 切换后,DNS (Domain Name System, 域名系统) 同时返回了新旧两个 IP (Internet Protocol, 互联网协议):

root@pod:/app# getent hosts r-2vc6...rds.aliyuncs.com
10.71.42.223    r-2vc6...rds.aliyuncs.com  <-- ✅ 新 IP (Internet Protocol, 互联网协议) (能通)
172.23.241.113  r-2vc6...rds.aliyuncs.com  <-- ❌ 旧 IP (Internet Protocol, 互联网协议) (已断网)

💡 分析: 如果出现这种情况,Java/Go 客户端可能会随机连到那个死掉的旧 IP (Internet Protocol, 互联网协议),导致服务间歇性报错。getent 让你一眼看穿真相!


2. 🛣️ 探路神器:curl -v telnet:// (排查端口连通性)

确定 IP (Internet Protocol, 互联网协议) 没问题后,下一步是:“路通不通?门开没开?”

我们习惯用 ping 测连通性,用 telnet 测端口。但容器里往往没有这两个命令。而且,ping 通不代表端口通(防火墙可能禁了 ICMP (Internet Control Message Protocol, 互联网控制消息协议) 但开了 TCP (Transmission Control Protocol, 传输控制协议)),ping 不通也不代表端口不通

这时候,curl 就登场了。很多人只知道用它发 HTTP (HyperText Transfer Protocol, 超文本传输协议) 请求,其实它支持多种协议,包括底层的 Telnet (TCP (Transmission Control Protocol, 传输控制协议))

📝 使用方法

curl -v telnet://<IP (Internet Protocol, 互联网协议) 或域名>:<端口>
  • 注意要加 -v (verbose),否则你看不到握手过程。
  • 协议头必须是 telnet://

🌰 实战案例

情况 A:连接成功 (通了!🎉)

root@pod:/app# curl -v telnet://10.71.42.223:6379
*   Trying 10.71.42.223:6379...
* Connected to 10.71.42.223 (10.71.42.223) port 6379 (#0)  <-- ✅ 看到 Connected 就是通了!

说明: 看到 Connected 后,通常卡在这里不动是正常的,因为 Redis 在等你发指令。按 Ctrl + C 退出即可。

情况 B:连接拒绝 (白名单/防火墙问题 🚫)

root@pod:/app# curl -v telnet://10.71.42.223:6379
*   Trying 10.71.42.223:6379...
* Connection refused  <-- ❌ 对方服务器收到了请求,但拒绝了

💡 分析: 这通常意味着目标服务没启动,或者配置了白名单拒绝了你的 IP (Internet Protocol, 互联网协议)。

情况 C:连接超时 (路由/网络隔离问题 ⏳)

root@pod:/app# curl -v telnet://172.23.241.113:6379
*   Trying 172.23.241.113:6379...
(一直卡在这里不动)

💡 分析: 这说明数据包发出去了,但像石沉大海一样没回来。通常是因为网络不通(比如跨了 VPC (Virtual Private Cloud, 专有网络) 且没打通,或者交换机路由不可达)。


🎯 总结

在精简的 Docker/K8s (Kubernetes, 容器编排系统) 容器中排查“连不上数据库/中间件”的问题,谨记这套组合拳:

  1. 查地图 🗺️:getent hosts <域名>
    • 看解析对不对,有没有混入奇怪的旧 IP (Internet Protocol, 互联网协议)。
  2. 测道路 🚦:curl -v telnet://<域名>:<端口>
    • 看是 Connected (通),Refused (被拒),还是卡住 (网断)。

掌握这两个命令,哪怕给你一个只有 5MB 大小的 Alpine 镜像,你也能从容地定位网络故障!💪


📊 图表解析

1. 排查流程图 (Flowchart)

是 (显示正确IP)
否 (无结果/旧IP)
否 (Refused)
否 (Trying...卡住)
开始网络排查
使用 getent hosts 检查DNS解析
解析结果是否正确?
使用 curl -v telnet:// 检查端口
排查 CoreDNS 或 VPC (Virtual Private Cloud) 缓存
是否显示 Connected?
网络层正常
检查应用层配置
检查目标服务白名单/安全组
检查路由表/网络隔离

2. 交互时序图 (Sequence Diagram)

开发者容器终端DNS (Domain Name System) 服务器目标服务 (Redis)阶段一:DNS (Domain Name System) 解析检查执行 getent hosts <域名>1查询域名对应的 IP (Internet Protocol)2返回 IP (Internet Protocol) 列表 (例如 10.71.x.x)3显示解析结果4阶段二:TCP (Transmission Control Protocol) 连通性检查执行 curl -v telnet://<IP>:<端口>5发起 TCP (Transmission Control Protocol) 三次握手 (SYN)6确认 (SYN-ACK)7确认 (ACK)8显示 Connected (连接成功)9复位 (RST)10显示 Connection Refused (拒绝)11数据包丢失长期卡在 Trying... (超时)12alt[网络通畅][连接被拒][网络不通]开发者容器终端DNS (Domain Name System) 服务器目标服务 (Redis)

3. 网络状态图 (State Diagram)

执行 getent
解析成功 (获得 IP)
解析失败 (Unknown Host)
curl 返回 Connected
curl 返回 Connection refused
curl 卡住 (Trying...)
需检查域名拼写
需检查白名单
需检查 VPC (Virtual Private Cloud) 路由
未知状态
DNS (Domain Name System) 解析中
TCP (Transmission Control Protocol) 握手中
连接成功
解析失败
连接拒绝
连接超时

4. 工具类图 (Class Diagram)

在这里插入图片描述

5. 实体关系图 (Entity Relationship Diagram)

PODstringnameK8s (Kubernetes) Containerstringshellbash/shCOMMANDDNS_CHECKstringtoolgetentstringtargetDomain NamestringresultIP (Internet Protocol) AddressTCP_CHECKstringtoolcurlstringprotocoltelnetstringtargetIP:PortstringstatusConnected/Refused/Timeoutexecutestype_istype_is

🧠 知识点思维导图

  • K8s (Kubernetes, 容器编排系统) 容器网络排查
    • 背景痛点
      • 精简镜像缺失工具 (Alpine/Distroless)
      • 缺失 ping, telnet, nslookup
    • 核心神器 1: getent
      • 全称: Get Entries
      • 用途: 检查 DNS (Domain Name System, 域名系统) 解析
      • 优势: Linux 标配,无需安装
      • 命令: getent hosts <域名>
      • 典型故障: DNS (Domain Name System) 裂脑 (新旧 IP (Internet Protocol, 互联网协议) 并存)
    • 核心神器 2: curl
      • 全称: Client URL
      • 用途: 检查 TCP (Transmission Control Protocol, 传输控制协议) 端口连通性
      • 技巧: 使用 telnet:// 伪协议
      • 命令: curl -v telnet://<IP>:<端口>
      • 结果解读
        • Connected: 通了
        • Refused: 白名单/防火墙拦截
        • Trying...: 路由中断/网络隔离
    • 排查口诀
      • 先查地图 (DNS)
      • 再测道路 (TCP)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值