08-网络配置
上一篇《系统服务管理》把长期运行的软件纳入 systemd 生命周期。本篇继续向外扩展:服务要被用户访问、要连接数据库、要解析域名、要获取时间、要上报监控,最终都依赖主机网络。Linux 网络配置看起来只是 IP、掩码、网关和 DNS 四个字段,生产故障却经常跨越网卡驱动、链路聚合、VL。

从“配一个 IP”到“交付可运营的主机网络”
上一篇《系统服务管理》把长期运行的软件纳入 systemd 生命周期。本篇继续向外扩展:服务要被用户访问、要连接数据库、要解析域名、要获取时间、要上报监控,最终都依赖主机网络。Linux 网络配置看起来只是 IP、掩码、网关和 DNS 四个字段,生产故障却经常跨越网卡驱动、链路聚合、VLAN、地址、邻居表、路由、策略路由、防火墙、DNS、监听端口和应用健康状态。
本文是 Linux 系统管理系列第 8 篇,采用配置实战与故障排查 runbook 相结合的方式。目标不是让读者记住某个发行版的配置文件,而是建立一套不依赖单一工具的网络心智模型。读完后,你应该能够:
- 判断当前主机由 NetworkManager、systemd-networkd、Netplan、云初始化还是其他工具管理网络。
- 使用
ip、ss、resolvectl、nmcli、networkctl、tcpdump等工具观察真实运行状态。 - 配置静态地址、DHCP、默认路由、DNS、VLAN、bond、bridge 和多网卡策略路由。
- 在远程 SSH 环境中设置自动回滚,降低改网后失联风险。
- 按链路、地址、邻居、路由、DNS、防火墙、监听和应用顺序定位故障。
- 把网络配置纳入变更、监控、资产和安全治理,而不是停留在单机手工操作。
本文于 2026-06-12 核对 NetworkManager 最新参考文档、systemd 260 系列网络手册、Netplan 官方文档和 Linux man-pages。不同发行版携带的 NetworkManager、systemd、Netplan 和 iproute2 版本可能明显不同,实施前必须使用 --version、本机 man page 和发行版文档确认可用字段。
1. Linux 网络是一条分层数据路径
应用发起连接时,内核需要完成名称解析、源地址选择、策略规则匹配、路由查找、邻居解析、封包、netfilter 处理和网卡发送。接收方向则反向经过驱动、内核协议栈、防火墙、socket 和应用。网络管理器负责把期望状态写入这条路径,但真正转发数据的是内核。
图中将配置管理器、内核网络对象和应用放在同一条链上。排障时要先判断问题属于“持久配置没有生成正确运行状态”,还是“运行状态正确但外部路径或应用异常”。
1.1 五类必须区分的对象
| 对象 | 典型命令 | 解决的问题 |
|---|---|---|
| Link | ip link, ethtool |
网卡是否存在、是否 Up、是否有 carrier、速率与错误 |
| Address | ip addr |
接口配置了哪些 IPv4/IPv6 地址和前缀 |
| Neighbor | ip neigh |
IP 到 MAC 的 ARP/NDP 解析是否成功 |
| Route/Rule | ip route, ip rule |
数据包从哪张表、哪个接口、哪个网关发出 |
| Socket | ss |
服务是否监听、连接处于什么状态 |
DNS、防火墙和应用健康是另外三个关键层次。一个域名解析失败不会改变接口状态;一个服务未监听也不会让网关不可达。把所有现象都归为“网络不通”,会让排障反复绕圈。
1.2 配置状态与运行状态
Linux 网络至少存在两套状态:
- 持久配置:NetworkManager connection profile、
/etc/systemd/network/*.network、Netplan YAML、云平台元数据等。 - 内核运行状态:接口、地址、路由、规则、邻居、qdisc、netfilter 和 socket。
修改持久配置后,不一定已经应用;临时执行 ip addr add 又不一定能在重启后保留。因此每次变更都要回答两个问题:
- 当前内核状态是否符合预期?
- 系统重启或接口重连后是否还能恢复?
2. 先识别谁在管理网络
同一台主机不应让多个管理器同时争夺同一接口。Ubuntu Server 常见 Netplan 作为声明层,后端可能是 NetworkManager 或 systemd-networkd;RHEL、Rocky Linux、AlmaLinux 和 Fedora 服务器通常使用 NetworkManager;某些精简系统、容器主机和嵌入式环境使用 systemd-networkd;云镜像还可能由 cloud-init 首次生成配置。
2.1 识别服务与配置来源
systemctl is-active NetworkManager.service
systemctl is-active systemd-networkd.service
systemctl is-enabled NetworkManager.service
systemctl is-enabled systemd-networkd.service
nmcli general status 2>/dev/null
networkctl list 2>/dev/null
ls -la /etc/netplan 2>/dev/null
ls -la /etc/NetworkManager/system-connections 2>/dev/null
ls -la /etc/systemd/network 2>/dev/null
再检查 cloud-init 是否管理网络:
cloud-init status --long 2>/dev/null
grep -R "network:" /etc/cloud /var/lib/cloud/seed 2>/dev/null | head
判断不能只看“某个服务在运行”。NetworkManager 可以把特定接口标记为 unmanaged,systemd-networkd 也只会处理匹配到 .network 文件的接口。应继续查看接口归属:
nmcli -f GENERAL.DEVICE,GENERAL.STATE,GENERAL.CONNECTION device show
networkctl status --all 2>/dev/null
2.2 避免双重管理
典型冲突包括:
- Netplan renderer 指向 NetworkManager,但管理员又手工创建 systemd-networkd 配置。
- cloud-init 每次启动重新生成 Netplan,覆盖本地手工修改。
- NetworkManager 管理 bridge,但成员接口又被旧 ifcfg 或脚本单独配置地址。
- 容器平台、虚拟化平台或 SDN Agent 接管接口,管理员仍把它当普通物理网卡修改。
变更前应确认接口的最终所有者。生产环境里“能用”不代表配置正确,两个管理器轮流重配接口可能只在重启、链路抖动或 DHCP 续租时暴露。
3. 建立网络基线
任何网络变更前都应保存当前状态。建议创建一次性审计目录:
audit_dir="$HOME/network-audit-$(date +%F-%H%M%S)"
mkdir -p "$audit_dir"
ip -details link show > "$audit_dir/ip-link.txt"
ip -details address show > "$audit_dir/ip-address.txt"
ip route show table all > "$audit_dir/ip-route-all.txt"
ip rule show > "$audit_dir/ip-rule.txt"
ip neigh show > "$audit_dir/ip-neigh.txt"
ss -s > "$audit_dir/ss-summary.txt"
ss -lntup > "$audit_dir/ss-listen.txt"
resolvectl status > "$audit_dir/resolvectl.txt" 2>&1 || true
NetworkManager 主机补充:
nmcli general status > "$audit_dir/nm-general.txt"
nmcli device status > "$audit_dir/nm-device.txt"
nmcli connection show > "$audit_dir/nm-connections.txt"
nmcli -f all device show > "$audit_dir/nm-device-all.txt"
systemd-networkd 主机补充:
networkctl list > "$audit_dir/networkctl-list.txt"
networkctl status --all > "$audit_dir/networkctl-status.txt"
journalctl -u systemd-networkd --since "-1 hour" \
> "$audit_dir/networkd-journal.txt"
基线的价值在于保留接口名、MAC、地址、默认路由、DNS、管理器和监听服务。失联或回滚后,可以准确比较变化,而不是靠记忆恢复。
4. 使用 iproute2 观察和临时验证
ip 是现代 Linux 网络观察的基础工具。即使持久配置由 NetworkManager 或 Netplan 管理,最终状态仍可用 ip 检查。
4.1 接口与链路
ip -br link
ip -details link show dev enp1s0
ethtool enp1s0
ethtool -S enp1s0 | head -80
重点判断:
UP是管理状态,表示接口被启用。LOWER_UP或 carrier 表示底层链路已建立。- 速率、双工和自动协商是否符合交换机配置。
- RX/TX errors、dropped、CRC 等计数是否持续增长。
接口 Up 但没有 carrier,应优先检查网线、光模块、交换机端口、聚合成员和驱动,而不是修改 IP。
4.2 地址与生命周期
ip -br address
ip address show dev enp1s0
IPv6 地址可能同时包含 link-local、临时地址和全局地址。IPv4 DHCP 地址也可能有租约生命周期。tentative、deprecated、dadfailed 等标志能够解释“地址存在但不可正常使用”的现象。
临时添加地址用于验证:
sudo ip address add 192.0.2.20/24 dev enp1s0
验证结束后删除:
sudo ip address del 192.0.2.20/24 dev enp1s0
不要把 ip 临时命令当作永久配置。接口重启、管理器重连或系统重启后,它们通常会消失。
4.3 路由查找比只看路由表更重要
ip route
ip route show table all
ip rule
ip route get 203.0.113.10
ip route get 203.0.113.10 from 192.0.2.20
ip route get 会让内核按当前规则模拟一次路由决策,直接显示目标使用的网关、接口和源地址。多网卡或策略路由故障时,它通常比肉眼阅读多张路由表更可靠。
5. NetworkManager 配置实战
NetworkManager 使用 connection profile 描述配置。一个 profile 可以绑定到接口,也可以在不同接口之间迁移。nmcli connection show 展示配置,nmcli device show 展示设备运行状态,两者不能混淆。
5.1 创建静态 IPv4 连接
sudo nmcli connection add \
type ethernet \
ifname enp1s0 \
con-name server-lan \
ipv4.method manual \
ipv4.addresses 192.0.2.20/24 \
ipv4.gateway 192.0.2.1 \
ipv4.dns "192.0.2.53 192.0.2.54" \
ipv4.dns-search "example.internal" \
ipv6.method auto
检查:
nmcli connection show server-lan
nmcli -f GENERAL,IP4,IP6,DNS device show enp1s0
激活前必须确认有控制台或回滚手段:
sudo nmcli connection up server-lan
5.2 修改现有连接
sudo nmcli connection modify server-lan \
ipv4.addresses 192.0.2.21/24 \
ipv4.gateway 192.0.2.1 \
ipv4.dns "192.0.2.53 192.0.2.54"
修改 profile 不一定立即改变活动连接,需要重新激活或使用支持的 reapply 能力。先看当前版本帮助:
nmcli --version
nmcli connection help
nmcli device help
生产中不要机械执行 connection down && connection up,因为 down 会先断开 SSH。应使用独立控制台、NetworkManager checkpoint 或窗口内自动回滚。
5.3 NetworkManager checkpoint
NetworkManager 官方 nmcli-examples 提供 device checkpoint and restore。它可以先为设备创建检查点,再执行可能中断连接的命令;如果管理员无法确认,超时后恢复原状态。官方示例形式为:
sudo nmcli device checkpoint enp1s0 -- \
nmcli connection up server-lan
工具会要求确认是否提交。若命令导致远程 SSH 中断,无法确认时会在超时后回滚。不同版本的参数和默认超时应以本机 nmcli device checkpoint --help 为准。使用前必须在测试主机演练,因为 checkpoint 只能恢复 NetworkManager 管理范围内的状态,不能替你回滚交换机、防火墙或外部路由。
5.4 DHCP 与自动连接
sudo nmcli connection add \
type ethernet \
ifname enp1s0 \
con-name dhcp-lan \
ipv4.method auto \
ipv6.method auto \
connection.autoconnect yes
查看 DHCP 获取结果:
nmcli -f IP4.DHCP4,IP4.ADDRESS,IP4.GATEWAY,IP4.DNS device show enp1s0
journalctl -u NetworkManager --since "-15 min"
如果企业通过 DHCP Reservation 固定服务器地址,应同时记录 MAC、client-id 和租约。克隆 VM 后要检查 machine-id 与 DHCP 身份,避免多个实例被视为同一客户端。
6. Netplan 与 systemd-networkd
Netplan 是 YAML 声明层,它根据 renderer 生成 NetworkManager 或 systemd-networkd 配置。不要把 Netplan 当作独立转发引擎。
6.1 Netplan 静态地址
network:
version: 2
renderer: networkd
ethernets:
enp1s0:
addresses:
- 192.0.2.20/24
routes:
- to: default
via: 192.0.2.1
nameservers:
search:
- example.internal
addresses:
- 192.0.2.53
- 192.0.2.54
先检查语法和生成结果:
sudo netplan generate
远程主机优先使用:
sudo netplan try
netplan try 会在确认超时后回滚,适合降低 SSH 失联风险。但官方文档也提示,虚拟设备创建或重命名等场景的回滚并非绝对可靠,关键生产变更仍然需要独立控制台和配置备份。
确认后检查:
networkctl status enp1s0
ip address show dev enp1s0
ip route
resolvectl status enp1s0
6.2 直接使用 systemd-networkd
systemd-networkd 使用 .network 文件匹配接口,使用 .netdev 创建 bond、bridge、VLAN 等虚拟设备,使用 .link 影响链路属性。官方文档说明这些文件来自 /usr/lib/systemd/network、/usr/local/lib/systemd/network、/run/systemd/network 和 /etc/systemd/network,按文件名排序处理;本地管理配置通常放在 /etc/systemd/network。
静态配置示例 /etc/systemd/network/10-lan.network:
[Match]
Name=enp1s0
[Network]
Address=192.0.2.20/24
Gateway=192.0.2.1
DNS=192.0.2.53
DNS=192.0.2.54
Domains=example.internal
重新加载并重配:
sudo networkctl reload
sudo networkctl reconfigure enp1s0
networkctl status enp1s0
文件名顺序很重要。多个 .network 文件可能同时匹配接口,但通常只有第一个匹配文件生效。排障时使用:
networkctl status enp1s0
networkctl cat @enp1s0 2>/dev/null || true
journalctl -u systemd-networkd --since "-15 min"
如果发行版版本不支持某个 networkctl 子命令,应直接查看本机 man page,不要套用更新版本文档。
7. DNS:地址可达不等于名称可用
现代 systemd 环境常由 systemd-resolved 提供解析,/etc/resolv.conf 可能是指向 stub 文件的符号链接。NetworkManager 也可以直接管理 resolv.conf 或与 resolved 集成。
7.1 观察解析路径
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
resolvectl status
resolvectl query example.com
getent ahosts example.com
dig 直接查询 DNS,而 getent 更接近应用通过 NSS 获取名称的路径。两者结果不同,可能说明 /etc/nsswitch.conf、本地 hosts、缓存或 resolved 路由域参与了决策。
7.2 Split DNS
多网卡、VPN 或企业内外域环境可能需要不同 DNS 服务器处理不同域。NetworkManager 和 systemd-resolved 支持按连接设置 DNS 与路由域。设计时要明确:
- 内部域由哪个连接的 DNS 解析。
- 公共域是否允许走内部 DNS。
- VPN 断开后内部域是否应该失败,而不是泄露到公共 DNS。
- 多个连接同时提供默认 DNS 时优先级如何。
不要只把多个 DNS 地址写入一个列表。解析器可能轮询或在超时后切换,错误的 DNS 服务器会制造间歇性延迟。
7.3 DNS 故障排查
resolvectl query app.example.internal
dig @192.0.2.53 app.example.internal
dig +trace example.com
getent hosts app.example.internal
若直接指定 DNS 成功而系统解析失败,重点检查 resolved、NSS 和连接 DNS 优先级;若指定 DNS 也失败,检查 UDP/TCP 53、路由、防火墙和 DNS 服务端。
8. 默认路由、metric 与多网卡
单网卡服务器通常只有一条默认路由。多网卡服务器可能同时连接管理网、业务网、备份网和存储网。如果多个连接都安装默认路由,内核会根据 metric 和策略规则选择路径,回包可能从错误接口发出。
8.1 使用 metric 决定主备默认路由
NetworkManager 示例:
sudo nmcli connection modify primary \
ipv4.never-default no \
ipv4.route-metric 100
sudo nmcli connection modify backup \
ipv4.never-default no \
ipv4.route-metric 500
如果管理网不应提供默认路由:
sudo nmcli connection modify mgmt ipv4.never-default yes
验证:
ip route
ip route get 203.0.113.10
8.2 非对称路由
假设请求从管理接口 enp1s0 进入,但主默认路由指向业务接口 enp2s0。应用会收到请求,响应却从 enp2s0 发出。上游状态防火墙、反向路径过滤或对端路由可能丢弃响应。现象通常是同网段访问正常、跨网段间歇失败,或者抓包能看到 SYN 进入却看不到正确方向的 SYN-ACK。
检查:
ip route get <client-ip>
ip route get <client-ip> from <service-ip>
sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.enp1s0.rp_filter
不要为了快速恢复就全局关闭 rp_filter。应先修复路由设计,只有多宿主、策略路由或特殊转发场景确有需要时,再按安全评审调整。
9. 策略路由:让源地址决定出口
当一台服务器需要多个有效默认网关,仅靠 metric 不够。策略路由可以按源地址、fwmark、入口接口等条件选择不同路由表。
这张图强调“请求从哪条路径进入,响应应如何回到同一路径”。正确的源地址规则可以避免状态防火墙和反向路径检查丢包。
假设:
- 管理网:
192.0.2.20/24,网关192.0.2.1,接口enp1s0。 - 业务网:
198.51.100.20/24,网关198.51.100.1,接口enp2s0。
临时验证:
sudo ip route add 192.0.2.0/24 dev enp1s0 src 192.0.2.20 table 100
sudo ip route add default via 192.0.2.1 dev enp1s0 table 100
sudo ip rule add from 192.0.2.20/32 table 100 priority 100
sudo ip route add 198.51.100.0/24 dev enp2s0 src 198.51.100.20 table 200
sudo ip route add default via 198.51.100.1 dev enp2s0 table 200
sudo ip rule add from 198.51.100.20/32 table 200 priority 200
验证:
ip rule
ip route show table 100
ip route show table 200
ip route get 203.0.113.10 from 192.0.2.20
ip route get 203.0.113.10 from 198.51.100.20
确认逻辑后再用 NetworkManager、Netplan 或 systemd-networkd 持久化。具体字段随版本变化,必须以目标工具官方文档为准。不要在配置管理器之外长期维护 ip rule add 脚本,否则接口重连和规则清理会变得不可预测。
10. VLAN、bond 与 bridge
企业服务器经常通过 VLAN 承载多个网络,通过 bond 提供链路冗余,通过 bridge 给虚拟机或容器提供二层接入。三者的顺序通常是:
物理接口 -> bond -> VLAN 子接口 -> bridge -> 虚拟机/容器
也可能根据平台要求使用:
物理接口 -> bond -> bridge -> VLAN filtering
选择必须与虚拟化平台、交换机和发行版工具一致,不能混用两套模型。
10.1 VLAN
NetworkManager 示例:
sudo nmcli connection add \
type vlan \
con-name bond0.110 \
ifname bond0.110 \
dev bond0 \
id 110 \
ipv4.method manual \
ipv4.addresses 10.110.0.20/24 \
ipv4.gateway 10.110.0.1
验证:
ip -details link show bond0.110
ip address show bond0.110
tcpdump -eni bond0 vlan 110
如果 VLAN 子接口正确但无邻居响应,检查交换机 trunk、native VLAN、允许列表和上联路径。
10.2 Bond
创建 bond 前先与网络团队确认模式:
- active-backup:切换简单,交换机无需 LACP。
- 802.3ad:支持多链路聚合,但交换机必须配置 LACP;跨交换机需要 MLAG、堆叠或等价能力。
NetworkManager 示例:
sudo nmcli connection add type bond \
ifname bond0 \
con-name bond0 \
bond.options "mode=active-backup,miimon=100"
sudo nmcli connection add type ethernet \
ifname enp1s0 \
con-name bond0-port1 \
master bond0
sudo nmcli connection add type ethernet \
ifname enp2s0 \
con-name bond0-port2 \
master bond0
验证:
cat /proc/net/bonding/bond0
ip -s link show bond0
故障切换测试必须在维护窗口进行,并持续观察 ping、TCP 会话和交换机聚合状态。单端口拔线成功不代表整台交换机故障时也能恢复。
10.3 Bridge
Linux bridge 常用于 KVM、容器或二层转发。NetworkManager 示例:
sudo nmcli connection add type bridge \
ifname br0 \
con-name br0 \
ipv4.method manual \
ipv4.addresses 192.0.2.20/24 \
ipv4.gateway 192.0.2.1
sudo nmcli connection add type ethernet \
ifname enp1s0 \
con-name br0-port \
master br0
注意:地址通常配置在 bridge 上,而不是被 enslave 的物理端口上。若物理端口和 bridge 同时配置相同网段地址,可能产生重复路由、ARP 混乱或源地址选择异常。
验证:
bridge link
bridge vlan show
bridge fdb show br br0
ip address show br0
11. IPv6 不能靠“先关掉再说”
很多网络问题被简单处理为禁用 IPv6,但现代操作系统、云平台、容器和应用可能依赖 IPv6 link-local、双栈 DNS 或 IPv6 优先连接。正确做法是先判断企业网络是否支持 IPv6,再决定启用、受控配置或明确禁用。
11.1 常见 IPv6 地址
fe80::/10link-local:同链路通信、邻居发现和路由协议常用。- 全局单播地址:可路由的 IPv6 地址。
- ULA:企业内部使用的唯一本地地址。
- 临时地址:用于隐私保护,服务器场景需评估可管理性。
检查:
ip -6 address
ip -6 route
ip -6 neigh
sysctl net.ipv6.conf.all.disable_ipv6
IPv6 默认网关通常通过 Router Advertisement 学习,并以 link-local 地址出现。看到 default via fe80::... dev enp1s0 不代表配置错误。
11.2 双栈排障
当域名同时返回 A 和 AAAA,应用可能优先尝试 IPv6。如果 IPv6 地址存在但外部路径不完整,会表现为首次连接慢、超时后 IPv4 才成功。
getent ahosts example.com
curl -4 -v https://example.com/
curl -6 -v https://example.com/
ping -6 <ipv6-gateway-or-peer>
应修复 IPv6 路由、防火墙和 DNS,或在明确不使用 IPv6 时按发行版规范禁用。不要只删除一个接口地址,却保留错误的 AAAA 和默认路由。
12. 防火墙、连接跟踪与监听端口
网络接口和路由正确,服务仍可能因防火墙或未监听而不可达。
12.1 先看服务监听
ss -lntup
ss -lntup '( sport = :443 )'
systemctl status <service>
区分:
- 监听
127.0.0.1:443:只允许本机访问。 - 监听
0.0.0.0:443:所有 IPv4 地址。 - 监听
[::]:443:行为取决于应用和bindv6only,可能同时接受 IPv4-mapped 连接。
如果服务根本没有监听,继续查交换机没有意义。
12.2 nftables 与 firewalld
sudo nft list ruleset
sudo firewall-cmd --get-active-zones 2>/dev/null
sudo firewall-cmd --list-all 2>/dev/null
不要用“临时关闭防火墙”作为常规排障。更安全的方法是先查看计数器、日志和规则匹配,必要时添加精确的临时测试规则,并在验证后删除。
12.3 conntrack
状态防火墙会跟踪连接。非对称路由、NAT 或旧会话可能导致新配置看似不生效。安装了 conntrack 工具时可查看:
sudo conntrack -L | head
sudo conntrack -L -p tcp --dport 443
清理连接跟踪会影响现有会话,只能在明确范围和维护窗口内执行。
13. 远程改网的安全工作流
远程 SSH 改网络最大的风险不是语法错误,而是成功应用了一个会切断管理路径的配置。所有生产远程变更都应满足:
- 有 BMC、虚拟机控制台、云串口或现场人员等独立访问路径。
- 保存当前配置和运行状态。
- 设置自动回滚。
- 先做临时或有超时保护的应用。
- 从外部验证管理和业务路径。
- 成功后再提交持久配置并取消回滚。
这条流程把“能改”与“能恢复”放在同一层级。没有独立控制台和回滚手段时,不应在关键主机上直接切换默认网关、bond 模式或管理地址。
13.1 一个通用的自动回滚思路
如果工具本身没有可靠的 try/checkpoint,可以使用 at 或 transient systemd timer 安排回滚脚本。回滚脚本必须在变更前创建并本地验证。例如:
sudo install -m 600 /etc/NetworkManager/system-connections/server-lan.nmconnection \
/root/server-lan.nmconnection.backup
然后安排数分钟后恢复并重载。具体脚本必须根据管理器和配置来源编写,不能直接套用通用删除命令。成功验证后取消计划任务。使用这种方式前要确认 atd 或 systemd timer 本身可用,且回滚不会依赖已经断开的网络。
13.2 验收顺序
在保持原 SSH 会话的同时,新开一个会话验证:
ip -br address
ip route
ip route get <admin-client-ip>
resolvectl query <internal-domain>
ping -c 3 <gateway>
curl --connect-timeout 3 http://<health-endpoint>
还要从外部监控节点验证 SSH、业务端口和监控采集。不要只在服务器本机 ping 网关,因为本机自测无法覆盖上游 ACL、NAT 和回程路径。
14. 从链路到应用的排障 runbook
排障顺序应尽量固定。每一层通过后再进入下一层,避免同时修改多个变量。
14.1 第一步:明确症状和范围
先回答:
- 单台主机还是同网段多台主机?
- 所有目标都失败还是只有一个域名、端口或方向?
- 本机访问失败还是远程访问失败?
- 持续失败还是间歇失败?
- 何时开始,之前发生了哪些变更?
范围决定优先级。同交换机多台主机同时失败,应优先看网络设备;只有一个服务端口失败,应先看监听和防火墙。
14.2 第二步:链路
ip -br link
ethtool enp1s0
ip -s link show enp1s0
dmesg -T | grep -Ei 'link|nic|firmware|reset|timeout'
没有 carrier 时处理物理层、虚拟网卡连接状态、交换机端口和驱动。不要继续修改路由。
14.3 第三步:地址
ip -br address
ip address show dev enp1s0
journalctl -u NetworkManager --since "-15 min"
journalctl -u systemd-networkd --since "-15 min"
检查地址、前缀、重复地址、DHCP 失败和 IPv6 DAD。地址前缀错误可能让主机误以为远端在本地链路,导致它不断 ARP 而不走网关。
14.4 第四步:邻居
ip neigh show dev enp1s0
arping -I enp1s0 <gateway-ip>
INCOMPLETE 或 FAILED 表示 ARP/NDP 没有完成,重点检查 VLAN、交换机、网关、重复地址和二层路径。
14.5 第五步:路由与策略
ip rule
ip route show table all
ip route get <destination>
ip route get <destination> from <source-ip>
检查默认路由、metric、源地址和策略表。多网卡故障尤其要看回程路径。
14.6 第六步:DNS
getent hosts <name>
resolvectl query <name>
dig @<dns-server> <name>
IP 可达而域名失败才进入 DNS 层。不要用修改 /etc/hosts 长期掩盖 DNS 问题。
14.7 第七步:防火墙与 socket
ss -lntup
sudo nft list ruleset
sudo tcpdump -ni any host <peer-ip> and port <port>
抓包判断:
- 没有 SYN 到达:上游路由、防火墙、NAT 或目标地址错误。
- SYN 到达,无 SYN-ACK:服务未监听、本机防火墙或应用没有响应。
- SYN-ACK 发出但客户端收不到:回程路由、上游状态设备或非对称路径。
- 三次握手完成后应用超时:进入 TLS、代理、应用和后端依赖排查。
14.8 第八步:外部设备与应用
主机证据正常时,再检查交换机 MAC/VLAN、网关 ARP/路由、防火墙会话、负载均衡健康检查和应用日志。主机管理员应提供时间、源/目的、端口、抓包和路由结果,而不是只说“网络不通”。
15. 常见故障场景
15.1 SSH 改 IP 后立即断开
如果配置了 checkpoint/try,等待自动回滚;否则使用独立控制台恢复。恢复后检查新地址是否与现有地址冲突、网关是否在正确前缀、默认路由是否改变、管理客户端回程是否正确。
15.2 能 ping IP,不能访问域名
检查 /etc/resolv.conf 指向、resolvectl status、DNS 路由域和 UDP/TCP 53。若短域名失败但 FQDN 成功,检查 search domain。
15.3 能访问同网段,不能访问外网
检查默认路由和网关邻居:
ip route
ip route get 1.1.1.1
ip neigh show
再检查上游路由、NAT 和防火墙。不要假设网关可 ping 就一定配置了正确 NAT。
15.4 某些连接慢,重试后成功
可能原因包括:
- IPv6 路径不通,超时后回退 IPv4。
- DNS 列表中第一个服务器不可达。
- MTU/PMTUD 黑洞。
- ECMP 某条路径异常。
- 邻居表或连接跟踪压力。
使用 curl -4/-6、dig @server、tracepath 和抓包区分。
15.5 小包正常,大包失败
ping -M do -s 1472 <peer-ip>
tracepath <peer-ip>
ip link show
检查端到端 MTU、隧道封装和防火墙是否允许 ICMP Fragmentation Needed。不要只在一端设置 9000。
15.6 重启后网络配置消失
说明只修改了内核运行状态,或持久配置被 cloud-init、配置管理或另一个网络管理器覆盖。检查日志、配置来源和文件时间,不要简单把临时命令写入 rc.local。
16. 网络命名空间、容器与虚拟化边界
现代 Linux 主机上的网络不一定全部位于默认 network namespace。容器运行时、Kubernetes、虚拟化平台、VPN 和测试工具会创建新的 network namespace、veth、bridge、tun/tap、VRF 或 overlay 接口。管理员在主机默认命名空间执行 ip addr 看不到容器内部地址,并不代表地址不存在;看到大量随机接口,也不意味着它们都是异常残留。
16.1 Network Namespace 的基本模型
network namespace 拥有独立的接口、路由表、邻居表、防火墙规则和 socket。两个 namespace 通常通过 veth pair 连接,veth 一端位于主机,另一端被移动到目标 namespace。
查看命名空间:
ip netns list
lsns -t net
进入命名空间检查:
sudo ip netns exec <namespace> ip -br address
sudo ip netns exec <namespace> ip route
sudo ip netns exec <namespace> ss -lntup
并非所有容器运行时都用 ip netns 名称注册 namespace。此时可以通过进程 PID 进入:
sudo nsenter -t <pid> -n ip address
sudo nsenter -t <pid> -n ip route
sudo nsenter -t <pid> -n ss -lntup
排障前先确认应用在哪个 namespace。主机上 ss -lntup 看不到容器监听端口,可能只是服务在容器 namespace 中监听,再由 NAT、代理或 CNI 暴露。
16.2 veth、bridge 与 NAT 路径
容器常见数据路径是:
容器 eth0 -> veth peer -> 主机 bridge/CNI -> 路由或 NAT -> 物理接口
如果容器能访问同节点容器但不能访问外部,检查主机转发、NAT 和默认路由;如果外部能到主机端口但不能到容器,检查端口发布、DNAT、代理和容器监听地址。
ip -details link
bridge link
bridge fdb show
sysctl net.ipv4.ip_forward
sudo nft list ruleset
不要直接删除看似陌生的 veth 或 bridge。它们可能由 Docker、Podman、libvirt、Kubernetes 或系统服务管理,删除后控制器会重建,甚至影响正在运行的工作负载。先用接口索引、master 关系、进程 namespace 和运行时工具确认归属。
16.3 VRF 与独立路由域
VRF 允许在同一主机中维护独立路由表,适合管理网与业务网严格分离、网络设备仿真、运营商多租户或复杂多宿主场景。VRF 比简单策略路由提供更清晰的接口归属,但应用是否绑定到正确 VRF、DNS 如何处理、监控如何进入都需要额外设计。
检查:
ip -details link show type vrf
ip route show vrf <vrf-name>
ip vrf exec <vrf-name> ping <destination>
如果团队没有 VRF 运维经验,不要仅为解决一个默认路由问题就引入它。简单双网卡优先使用明确默认路由、静态路由或源地址策略规则;只有确实需要路由域隔离时再采用 VRF。
16.4 虚拟机宿主机的特殊边界
KVM/libvirt、Harvester 节点或其他虚拟化宿主机通常存在 bridge、tap、bond 和 VLAN。宿主机管理地址可能配置在 bridge 上,物理接口只是 bridge port。此时直接给物理端口添加地址会破坏原有模型。
变更前检查:
bridge link
ip -br link
virsh net-list --all 2>/dev/null
virsh domiflist <vm-name> 2>/dev/null
虚拟化宿主机的网络变更必须考虑虚拟机流量、迁移、存储和管理平面。不能只验证宿主机 SSH,还要验证至少一台测试虚拟机在变更前后仍能访问网关和业务服务。
17. 自动化配置与持续验证
手工 nmcli 或修改 YAML 适合学习和单机排障,但批量服务器必须使用配置管理。自动化的目标不是把手工命令复制到更多主机,而是让网络配置具备幂等、分批、校验和回滚能力。
17.1 配置数据模型
建议把主机网络抽象为结构化数据:
hostname: app-01
interfaces:
- name: enp1s0
role: management
addresses:
- 192.0.2.20/24
gateway: 192.0.2.1
dns:
- 192.0.2.53
- 192.0.2.54
mtu: 1500
- name: enp2s0
role: business
addresses:
- 198.51.100.20/24
routes:
- to: 198.51.100.0/24
via: 198.51.100.1
数据应来自 IPAM/CMDB 或经过审批的 inventory,而不是散落在 playbook 模板中。这样可以在生成 NetworkManager profile、Netplan 或 networkd 配置前先做一致性检查:
- 地址是否重复。
- 网关是否位于接口前缀。
- 同主机是否出现多个同 metric 默认路由。
- VLAN ID、MTU 和 bond 模式是否符合站点标准。
- DNS、NTP 和管理网段是否完整。
17.2 分批发布
网络配置不适合一次推送到全部主机。建议按以下节奏:
- 测试环境单机。
- 同硬件、同交换机的一台非关键主机。
- 一个冗余组中的单台节点。
- 小批次生产主机。
- 剩余范围。
每批都要等待监控稳定,确认 SSH、监控、业务健康、默认路由、DNS 和错误包。对于集群节点,永远不要同时修改一个高可用组的全部成员。
17.3 自动化前置检查
发布任务在修改前至少执行:
ip -br link
ip -br address
ip route
ip rule
ss -lntup
并确认:
- 目标接口存在,MAC 与 inventory 一致。
- 当前主连接就是预期连接。
- 独立控制台可用。
- 回滚任务已创建。
- 当前没有其他网络维护。
- 关键业务已有冗余或摘流。
如果任何条件不满足,应让自动化失败退出,而不是“尽量继续”。
17.4 自动化后置验证
成功不能只依赖命令返回码。任务需要执行语义验证:
ip route get <management-probe>
getent hosts <internal-domain>
timeout 3 bash -c '</dev/tcp/<service-host>/<port>'
同时由外部探针主动访问主机,确认入站与回程。配置管理器在目标主机上自测成功,只能证明出站路径的一部分。
17.5 漂移检测
主机管理员可能为临时排障直接执行 ip 或 nmcli,形成与 Git/CMDB 不一致的状态。建议定期采集:
- 接口与 MAC。
- 地址和路由。
- NetworkManager profile 或 networkd 文件摘要。
- DNS、MTU、bond 和 VLAN。
- 防火墙规则版本。
发现漂移后先解释来源,再决定回收。不要自动覆盖所有差异,因为某些差异可能是正在进行的事故处置或云平台动态配置。成熟的流程应该把紧急变更补录到配置源,再恢复一致性。
18. 案例复盘:双网卡服务器“偶发失联”
某生产应用服务器有两块网卡:
enp1s0:管理网10.20.10.15/24,网关10.20.10.1。enp2s0:业务网10.30.20.15/24,网关10.30.20.1。
应用通过业务地址提供服务,管理员通过管理地址 SSH。系统上线后出现三个现象:
- 同管理网段 SSH 正常,跨网段跳板机 SSH 间歇超时。
- 应用访问大多正常,但某些经过防火墙的客户端连接失败。
- 重启 NetworkManager 后故障概率变化。
18.1 初始误判
值班人员先怀疑交换机端口和 SSH 服务,重启了 sshd,也清理过防火墙规则,但问题没有消失。因为同网段 SSH 一直正常,网卡和 sshd 实际都在工作。
18.2 证据采集
ip route
ip rule
ip route get 10.20.99.25 from 10.20.10.15
ip route get 10.30.99.25 from 10.30.20.15
结果显示两块网卡都通过 DHCP 安装了默认路由,metric 在续租后发生变化。某些时候业务网默认路由优先。来自跳板机的 SSH 请求从管理网进入,响应却从业务网发出,被上游状态防火墙丢弃。
同时抓包验证:
sudo tcpdump -ni enp1s0 host 10.20.99.25 and port 22
sudo tcpdump -ni enp2s0 host 10.20.99.25 and port 22
可以在 enp1s0 看到 SYN 进入,在 enp2s0 看到错误方向的 SYN-ACK。问题由此从“网络偶发”收敛为“多默认路由导致非对称回程”。
18.3 修复方案
团队明确业务网承担主默认路由,管理网只用于管理网段访问:
sudo nmcli connection modify mgmt \
ipv4.never-default yes \
+ipv4.routes "10.20.0.0/16 10.20.10.1"
sudo nmcli connection modify business \
ipv4.never-default no \
ipv4.route-metric 100
随后使用 NetworkManager checkpoint 应用,并从两个外部探针验证 SSH 和业务端口。对于仍需管理地址访问更多外部网段的需求,团队评估后增加了源地址策略路由,确保管理地址的响应始终经管理网关返回。
18.4 为什么重启后概率变化
两条 DHCP 默认路由的 metric 和激活顺序会影响最终主路由。重启 NetworkManager、链路抖动或 DHCP 续租都可能改变连接激活时序,因此故障呈现“偶发”。这类问题不能靠重启解决,必须让路由策略显式化。
18.5 复盘改进
- 服务器模板禁止两个 DHCP 连接同时提供默认路由。
- CMDB 增加接口角色、默认网关和路由策略字段。
- 上线检查增加
ip route get的双源地址验证。 - 监控增加默认路由变更和 NetworkManager 连接重激活事件。
- 双网卡主机必须记录
rp_filter和策略路由设计。
这个案例说明,真正有效的排障不是反复重启服务,而是用路由查找和抓包证明请求与响应分别走了哪条路径。
19. 网络监控与日常治理
19.1 关键监控
- 接口 up/down、carrier 变化。
- RX/TX errors、dropped、CRC、队列丢弃。
- 带宽利用率与突发。
- 默认路由和关键静态路由存在性。
- DNS 延迟与失败率。
- 关键网关、NTP、目录、监控和业务端口可达性。
- conntrack 使用率、socket backlog 和 TCP 重传。
常用内核统计:
ip -s link
ss -s
nstat
cat /proc/net/snmp
cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null
cat /proc/sys/net/netfilter/nf_conntrack_max 2>/dev/null
19.2 配置治理
- 网络配置进入 Git 或配置管理,禁止只有主机本地副本。
- IP、MAC、接口、VLAN、网关和主机名同步到 IPAM/CMDB。
- 静态路由和策略路由必须记录业务原因、负责人和复核日期。
- bond、VLAN 和 bridge 命名形成团队标准。
- 云镜像明确 cloud-init 与本地配置的边界。
- 关键主机保留 BMC/控制台访问,并定期验证。
19.3 安全基线
- 只开放必要监听地址和端口。
- 管理接口与业务接口按安全域隔离。
- 转发、源路由、重定向和 rp_filter 按主机角色配置。
- nftables/firewalld 规则通过配置管理维护。
- 抓包文件按敏感数据处理,限制保留和访问。
- 网络变更与防火墙变更分阶段执行,保留证据和回滚。
19.4 启动阶段的网络依赖
服务开机启动失败时,不要简单给所有 unit 添加 After=network-online.target。网络接口进入 configured 状态,不代表 DNS、网关、VPN、远端数据库或云 API 已经可用。network-online.target 只能表达网络管理器认为配置过程达到某个阶段,不能替代应用层连接重试。
更稳妥的做法是:
- NetworkManager 环境确认
NetworkManager-wait-online.service的启用状态和超时符合需求。 - systemd-networkd 环境检查
systemd-networkd-wait-online.service的等待接口范围,避免一个不重要的未连接接口拖慢启动。 - 应用自身实现带退避的 DNS、TCP 和认证重试。
- 对远端依赖使用健康检查和启动超时,而不是假设开机后立即可达。
- 在日志中区分“本机没有地址”“默认路由缺失”“DNS 不可用”和“远端服务拒绝连接”。
如果一台服务器有管理口、业务口和暂未接线的备用口,wait-online 若等待所有接口,系统可能长时间停在启动阶段。应明确哪些接口是 required-for-online,并在变更后通过重启演练验证,而不是只测试运行中的接口重载。
20. 生产验收清单
配置与所有权
- [ ] 已确认 NetworkManager、systemd-networkd、Netplan 和 cloud-init 的职责。
- [ ] 每个接口只有一个明确管理者。
- [ ] 持久配置与
ip运行状态一致。 - [ ] 配置文件已纳入备份或版本管理。
链路与地址
- [ ] 接口、速率、双工、MTU 和 carrier 正常。
- [ ] 地址和前缀符合 IPAM。
- [ ] 网关邻居解析正常,无重复地址。
- [ ] IPv4/IPv6 策略符合设计。
路由与 DNS
- [ ]
ip route get的接口、网关和源地址正确。 - [ ] 多网卡回程路径对称或有明确策略路由。
- [ ] 内外域 DNS 和反向解析正常。
- [ ] 默认路由、metric 和静态路由有文档。
服务与安全
- [ ] 服务监听在预期地址和端口。
- [ ] 防火墙允许必要流量并拒绝非授权流量。
- [ ] 从外部节点完成管理和业务访问测试。
- [ ] 日志和监控能发现链路、丢包、DNS 和端口异常。
变更与恢复
- [ ] 有独立控制台。
- [ ] 变更前已保存基线。
- [ ] 已设置 checkpoint、try 或自动回滚。
- [ ] 新旧 SSH 会话和外部监控均验证通过。
- [ ] 回滚计划已取消或归档,CMDB 已更新。
21. 总结
Linux 网络配置的核心不是记住某个 YAML、keyfile 或 .network 语法,而是理解配置管理器如何把期望状态转化为内核接口、地址、邻居、路由、规则、DNS 和防火墙状态。NetworkManager、systemd-networkd 与 Netplan 的配置方式不同,但排障时最终都要回到 ip、ss、resolvectl、nft 和 tcpdump 展示的真实数据路径。
生产网络变更必须把恢复能力放在首位。先识别管理器,保存基线,使用 checkpoint 或 try,保持独立控制台,再逐层验证地址、网关、DNS、回程和业务端口。多网卡场景要重点治理默认路由、metric、策略路由和反向路径过滤;VLAN、bond、bridge 则必须与交换机和虚拟化平台使用同一模型。
故障排查应从范围和时间线开始,按链路、地址、邻居、路由、DNS、防火墙、socket 和应用逐层推进。抓包的价值是确定数据包在哪一层消失,而不是替代所有判断。把配置、IPAM、监控、回滚和审计结合起来,才能让 Linux 网络从“管理员会配置”走向“团队可运营”。
下一篇将进入 磁盘管理,继续讲解块设备识别、分区、LVM、文件系统扩容、挂载治理和磁盘故障排查。
参考资料
- NetworkManager Reference Manual
- nmcli Reference
- nmcli Examples - Device Checkpoint and Restore
- systemd.network
- systemd-networkd
- networkctl
- Netplan Documentation
- Linux man-pages - ip(8)
- Linux man-pages - ip-route(8)
- Linux man-pages - ss(8)
本文最后更新于 2026-06-12