接手一台Ubuntu服务器的网络故障,最忌讳的就是盲目重启网卡或者直接回滚配置。网络异常通常表现为三种形态:完全不通、间歇性丢包、DNS解析失败。针对完全不通,首先要确认是物理层、链路层还是IP层的问题。登录到物理控制台或者带外管理界面,执行ip link show,观察网卡状态。如果显示DOWN,且不是被人为down掉,大概率是网线松动、交换机端口故障或光纤模块不匹配。如果显示UP但NO-CARRIER,说明物理链路没有建立,需要检查对端交换机VLAN划分和端口速率双工模式是否强制匹配。

物理层与驱动层的深度排查

很多运维人员会忽略网卡固件和驱动版本的问题。在Ubuntu 20.04及之后的版本中,部分Intel X710或Mellanox网卡会因为内核驱动自动更新导致不兼容。执行dmesg | grep -i error和dmesg | grep -i fail,如果看到大量的tx hang或firmware failed信息,说明驱动挂了。此时不要急着重装驱动,先通过lspci -nn | grep -i net确认网卡的PCI ID,然后去硬件兼容性列表里比对。如果是驱动bug,通常需要安装linux-modules-extra包,或者回退到特定的dkms版本。对于使用bonding或桥接的场景,物理网卡一旦出现微秒级的硬件延迟,上层协议就会频繁抖动,这种故障在流量低时表现正常,流量一大就丢包,非常隐蔽。

网络配置的静态检查与逻辑校验

Netplan已经成为Ubuntu网络配置的主流,但很多故障恰恰源于YAML缩进错误或渲染逻辑冲突。检查/etc/netplan/目录下的配置文件,缩进必须严格使用空格,不能用Tab。执行netplan apply --debug可以直接看到渲染后的systemd-networkd或NetworkManager配置。如果服务器有多个网卡,要特别注意match字段的macaddress是否写错,导致配置绑定到了错误的接口。对于静态IP场景,除了检查addresses和gateway4,还要确认nameservers的search域是否包含了多余的后缀,导致短域名解析异常。一个容易忽视的点是,当服务器存在多个默认网关时,路由表会出现metric值相同的冲突,此时虽然ip route show看起来正常,但实际出站流量会随机选择网关,造成连接时通时断。

路由表与策略路由的精细化诊断

当物理层和配置都正常,但特定网段不通时,问题一定出在路由表上。执行ip route get 目标IP,这条命令会模拟内核的路由查找过程,直接告诉你数据包将从哪个网卡出去、下一跳是谁。如果返回结果与预期不符,就要检查主路由表和自定义路由表。很多高级运维会使用策略路由,通过ip rule show查看优先级。如果引入了多张路由表,比如基于源地址的策略路由,一旦源地址匹配规则写错,回程流量就会走错路径,导致TCP三次握手都无法建立。在生产环境中,如果使用了云平台的VPC,还要注意MTU的问题,Ubuntu默认MTU是1500,但部分底层网络封装会占用字节,导致大数据包被静默丢弃,此时用ping -M do -s 1472 目标IP测试分片,能快速定位。

DNS解析异常的深层原因

DNS故障的表现是ping域名不通但ping IP通。Ubuntu 22.04开始默认使用systemd-resolved管理DNS,传统的修改/etc/resolv.conf方法已经失效,因为该文件现在是一个指向/run/systemd/resolve/stub-resolv.conf的软链接。正确的排查方式是执行resolvectl status,查看每个网卡的DNS服务器和搜索域。如果显示当前DNS服务器不可达,检查53端口连通性。但有一种更隐蔽的故障:DNS服务器可达,但返回的A记录被本地防火墙或应用程序层面的策略拦截。比如某些安全组件会劫持DNS请求,强制返回一个审查页面地址,导致业务认为解析失败。此时用dig @指定DNS服务器 域名直接绕过systemd-resolved的缓存,对比返回结果,就能判断是上游DNS问题还是本地劫持。

防火墙与安全组件的隐形拦截

Ubuntu自带的iptables和nftables规则经常是网络异常的根源。很多运维在排查时会习惯性执行iptables -L -n,但这在较新的Ubuntu版本中可能看到的是空规则,因为系统实际使用的是nftables框架。正确做法是执行nft list ruleset,查看所有表和链的规则。如果服务器上运行了Docker或Kubernetes,它们会自动添加大量的NAT和转发规则,这些规则优先级很高,可能会意外拦截正常的业务流量。特别是Docker的iptables策略如果与ufw同时开启,会出现规则顺序混乱,ufw明明允许了某个端口,但流量经过Docker网桥时被提前丢弃。临时关闭防火墙测试时,一定要用systemctl stop而非仅仅清空规则,因为某些安全模块会监控规则变化并自动恢复。

连接跟踪表与内核参数的优化

高并发场景下,Ubuntu服务器的网络异常往往表现为新连接无法建立,但已有连接正常。这通常是连接跟踪表满了。执行conntrack -S查看当前连接数,再对比/proc/sys/net/netfilter/nf_conntrack_max的值。如果使用率超过90%,内核会随机丢弃新连接。临时解决可以增大nf_conntrack_max,但根本方案是优化nf_conntrack_tcp_timeout_established等超时参数,让已关闭的连接尽快释放。另外,tcp_tw_reuse和tcp_timestamps的配置组合如果不当,在NAT环境下会导致时间戳回绕,服务器拒绝客户端的SYN包,这种故障抓包会看到大量的SYN重传,但服务器没有任何响应。

抓包分析的实战技巧

当所有配置检查都无果时,必须上tcpdump抓包。抓包位置很关键,要在物理网卡、虚拟网桥、容器接口上分别抓取,对比数据包在哪一层消失。常用命令tcpdump -i eth0 -nn -s0 -w /tmp/capture.pcap host 目标IP。分析时重点关注TCP的flags字段,如果看到服务器返回RST,检查应用程序是否监听了对应端口,或者是否有内核参数tcp_tw_recycle的误杀。如果看到大量的重传和重复ACK,可能是中间网络设备存在丢包,此时用mtr命令做双向路由追踪,比traceroute更直观,能实时看到每一跳的丢包率和延迟波动。对于加密流量,虽然看不到载荷,但通过TLS握手阶段的Client Hello和Server Hello的时间差,可以判断是网络延迟还是服务器端处理慢。

虚拟化与容器网络的特殊场景

在虚拟化环境中,Ubuntu作为宿主机,如果虚拟机网络异常,要检查网桥的STP状态和forward delay参数。执行brctl showstp 网桥名,如果端口处于learning或blocking状态,说明生成树在收敛,这段时间网络是不通的,通常持续15到30秒。对于容器环境,检查CNI插件的路由注入是否正确,执行ip route查看是否有到Pod网段的路由。如果使用了Calico或Flannel,它们依赖BGP或VXLAN,底层网络设备必须允许相应的IP协议通过,比如VXLAN使用UDP 8472端口,如果中间防火墙封了这个端口,跨节点容器通信就会失败,但节点本身网络正常,这种故障非常具有迷惑性。

自动化诊断脚本与预防措施

建立一套标准化的诊断流程能大幅缩短故障恢复时间。可以编写一个诊断脚本,依次执行网卡状态检查、网关连通性测试、DNS解析测试、路由表校验、防火墙规则计数、连接跟踪表使用率、关键端口监听状态。将这些检查项输出为结构化日志,当故障发生时,先跑一遍脚本,能快速排除80%的常见问题。预防层面,所有网络配置变更必须通过netplan try进行验证,该命令会在规定时间内自动回滚,避免配置错误导致断连。内核参数调整要写入/etc/sysctl.d/目录下的独立配置文件,而不是直接修改/etc/sysctl.conf,这样便于版本管理和回退。对于生产环境,建议部署Prometheus的blackbox exporter,持续探测TCP连接和HTTP请求的延迟与成功率,在故障萌芽阶段就发出告警,而不是等业务完全中断才被动响应。