ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Ubuntu网关路由配置全解析:临时与永久生效及策略路由实践

Ubuntu网关路由配置全解析:临时与永久生效及策略路由实践

1. 为什么“加个网关”这件事值得单独写一篇

在 Linux 系统里给主机补一条网关路由,看起来是运维工作里最不起眼的一个动作——一条ip route add命令的事。但我这些年帮人排查网络问题的经历里,因为网关路由配错、配漏、配了不生效而卡住半天的案例,占比高得离谱。尤其是在 Ubuntu 这类默认启用 Netplan 管理网络配置的发行版上,很多人第一反应是敲route add default gw,敲完发现当前终端能通,一重启全没了;或者改完配置文件,ping网关通、ping外网不通,回头一看是路由表里多了一条优先级更高的旧记录在捣乱。

这篇内容就围绕“在 Ubuntu 上添加网关路由”这一件事展开,把临时生效和永久生效两条路径都讲透,把 Netplan、ip route、route这几套工具的关系理清楚,再补上策略路由、多网卡场景、路由优先级这些实际工作中绕不开的细节。适合刚接触 Linux 网络配置的新手照着做,也适合有一定基础但被 Netplan 的 YAML 缩进和renderer字段坑过的朋友对照排查。核心关键词就三个:Ubuntu、网关路由、默认网关,全文围绕它们展开,不跑偏。

先说清楚一个前提概念,避免后面混淆。网关(Gateway)本质上是本网段内一台能帮你把流量转发到其他网段的设备,通常是路由器的内网口地址。默认网关(Default Gateway)则是路由表里0.0.0.0/0这条目标为“任意地址”的路由所指向的下一跳,所有没有更精确匹配的流量都走它。而“添加网关路由”这个动作,在实操中可能指两件不同的事:一是给主机设置默认网关,二是给某个特定目标网段单独指定一个网关(也就是静态路由)。这两件事命令长得像,但配置位置和生效逻辑不一样,后面会分开讲。

2. 动手之前先把路由表看懂

2.1 三条命令看清当前网络状态

在改任何配置之前,先摸清现状,这是我一直坚持的习惯。Ubuntu 上查看路由表,最推荐的是ip route,输出干净、信息全:

ip route show

典型输出长这样:

default via 192.168.1.1 dev ens33 proto static metric 100 192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.50 metric 100

逐字段拆一下。default via 192.168.1.1就是默认网关,dev ens33说明走的是哪块网卡,proto static表示这条路由是静态配置来的(如果是 DHCP 下发的会显示proto dhcp),metric 100是度量值,数值越小优先级越高。第二行是本网段的直连路由,scope link表示目标就在本地链路上,不需要经过网关。

配套再看两个命令。ip addr show确认网卡名和 IP 地址,网卡名这一步很关键,Ubuntu 从 16.04 之后普遍采用ens33、enp0s3这类可预测命名,不再是eth0,配置里写错网卡名是新手最常见的翻车点之一。cat /etc/resolv.conf或者resolvectl status看 DNS,因为网关配好了但 DNS 没配,表现同样是“上不了网”,容易误判。

2.2 临时路由和永久路由的本质区别

很多人搞不清为什么命令行加的路由重启就没了。原因在于 Linux 的路由表是内核里的一张内存表,ip route add直接操作的是这张运行时表,掉电或重启内核重新初始化,表就清空了。而开机时谁来把路由表填回去?在 Ubuntu 上,这个角色由Netplan扮演——它读取/etc/netplan/下的 YAML 文件,翻译成后端(systemd-networkd或NetworkManager)能理解的配置,再由后端在网卡启动时把地址、路由、DNS 一并下发。

所以逻辑链条是:YAML 配置文件 → Netplan 解析 → 后端渲染 → 内核路由表。你只改内核表(命令行),链条上游没动,重启自然丢失;你只改 YAML 不执行netplan apply,配置没被渲染,当前也不生效。理解这条链,后面所有操作就都有了依据。

提示:Ubuntu 17.10 之后 Netplan 成为默认网络配置工具,老教程里改/etc/network/interfaces的方法在新版本上基本失效,看到这类教程要留个心眼,先确认系统版本。

3. 临时添加网关路由:快速验证的正确姿势

3.1 设置默认网关的命令与参数拆解

临时改默认网关,用ip route系列最稳妥:

sudo ip route add default via 192.168.1.1 dev ens33

如果路由表里已经存在一条默认路由,上面这条会报RTNETLINK answers: File exists。这时候要么先删旧的再添新的,要么用replace一步到位:

sudo ip route replace default via 192.168.1.1 dev ens33

replace的语义是“有则替换、无则新增”,比“先 del 再 add”少一次中间状态,脚本里用它能避免删掉旧路由后、新路由还没加上那一瞬间的断网窗口。这个细节在网络自动化脚本里很重要,我见过因为这两条命令之间隔了几百毫秒,导致健康检查探针误判服务下线的案例。

给特定网段加静态路由则是另一个形态:

sudo ip route add 10.20.0.0/16 via 192.168.1.254 dev ens33

意思是“要去 10.20.0.0/16 这个网段的包,交给 192.168.1.254 转发”。注意这里的via地址必须和本机某块网卡在同一网段、且可达,否则内核会直接拒绝并报Nexthop has invalid gateway。这个报错我踩过不止一次,本质是内核在加路由前会做一次下一跳可达性校验,网关地址本身都 ping 不通,路由自然加不上。

3.2 用 route 命令的兼容写法及注意事项

老系统或老脚本里常见route命令:

sudo route add default gw 192.168.1.1

它在 Ubuntu 上通常还能用,但route属于net-tools包,新版本 Ubuntu 默认不再预装,需要sudo apt install net-tools才有。而且route的输出格式老旧、不支持策略路由等新特性,我的建议是新环境一律用ip route,route只在维护老脚本时作为兼容手段。两者操作的是同一张内核路由表,混用不会冲突,但排查时容易看花眼,统一工具能省不少事。

临时路由的价值在于“验证”。比如你怀疑是网关地址配错了,先用ip route replace切到正确网关,ping一下外网,通了就说明判断成立,再去改永久配置。这种“先验证后固化”的顺序,比直接改配置文件然后netplan apply试错要安全得多——后者一旦 YAML 写错,可能直接把网卡配置搞挂,远程连接当场断掉。

注意:如果你是通过 SSH 远程操作服务器,改默认网关前务必确认新网关可达、且不会把你自己的管理连接路由到黑洞里。稳妥做法是开一个带定时回滚的后台任务,或者干脆用带外管理口操作。

4. Netplan 永久配置:YAML 里的门道

4.1 找到并读懂现有的 Netplan 配置文件

先看目录里有什么:

ls -l /etc/netplan/

常见文件名是00-installer-config.yaml、01-netcfg.yaml或50-cloud-init.yaml。文件名前面的数字决定加载顺序,数字小的先加载,后面的会覆盖前面的同名配置。云主机上经常是50-cloud-init.yaml,这个文件由 cloud-init 生成,直接改它有时会被下次启动覆盖,更稳的做法是新建一个序号更大的文件(比如99-custom.yaml)来叠加配置。

打开文件看结构,典型内容:

network: version: 2 renderer: networkd ethernets: ens33: dhcp4: false addresses: - 192.168.1.50/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: [223.5.5.5, 119.29.29.29]

几个关键字段必须理解到位。renderer决定后端是networkd还是NetworkManager,服务器版一般是networkd,桌面版可能是NetworkManager,写错会导致配置不生效且不报明显错误。routes下的to: default就是默认网关的写法,等价于0.0.0.0/0;老版本 Netplan 用的是gateway4字段,新版本已标记废弃,混用会出警告甚至报错。

4.2 添加默认网关和静态路由的完整写法

给已有网卡补默认网关,在对应网卡的routes列表里加一项:

network: version: 2 renderer: networkd ethernets: ens33: dhcp4: false addresses: [192.168.1.50/24] routes: - to: default via: 192.168.1.1 metric: 100

加静态路由就是再加一个列表项:

routes: - to: default via: 192.168.1.1 metric: 100 - to: 10.20.0.0/16 via: 192.168.1.254 metric: 200

metric字段建议显式写上。不写时不同后端给的默认值不一样,多网卡环境下容易出现“默认路由抢主”的问题——两块网卡都配了默认网关,谁先起来谁生效,重启顺序一变网络行为就变,非常难排查。显式指定 metric,让主线路数值小、备线路数值大,行为就确定了。

YAML 的缩进是硬性要求,只能用空格,不能用 Tab,同级字段对齐必须严格。我见过太多因为复制粘贴带进了 Tab 或者多了一个空格,netplan apply报Invalid YAML的情况。写完先用netplan try验证:

sudo netplan try

它会先应用配置并启动一个 120 秒倒计时,期间网络若异常你可以按回车回滚,超时无操作则自动确认。这个机制对远程操作极其友好,相当于给你留了一条退路。确认没问题后再sudo netplan apply正式生效。

4.3 多网卡多网关的配置策略

一台机器两块网卡、各连一个网络、各有网关,这是很常见的双线路场景。配置时给两块网卡分别写 routes,用 metric 区分主备:

ethernets: ens33: dhcp4: false addresses: [192.168.1.50/24] routes: - to: default via: 192.168.1.1 metric: 100 ens34: dhcp4: false addresses: [192.168.2.50/24] routes: - to: default via: 192.168.2.1 metric: 200

这样默认流量走 ens33,ens33 断了(配合链路监测)才切到 ens34。但要注意,metric 只影响默认路由的选择,源地址选择是另一套逻辑——从 ens34 出去的包,源 IP 可能还是 ens33 的地址,导致对端回包走错路径。这种非对称路由问题在双线路环境里很典型,解决办法是上策略路由,用ip rule按源地址或目的地址分流,这部分内容放在第 6 节展开。

5. 配置生效与验证的完整闭环

5.1 从 apply 到路由表落地的检查清单

netplan apply执行完不代表万事大吉,按顺序做这几步检查:

  1. ip route show确认默认路由和静态路由都在,via地址和metric符合预期;
  2. ip addr show ens33确认 IP 地址没丢(改配置时误删addresses字段是常见事故);
  3. ping -c 3 192.168.1.1确认网关可达;
  4. ping -c 3 223.5.5.5确认外网 IP 层通;
  5. ping -c 3 www.example.com确认 DNS 解析正常。

这五步是一个从链路层到应用层的递进验证链,哪一步断了,问题范围立刻缩小。网关通但外网 IP 不通,问题在网关设备或上游;外网 IP 通但域名不通,问题在 DNS。分层的排查思路比盲目重启服务高效得多。

5.2 重启后配置丢失的排查路径

如果netplan apply后正常、重启后失效,按这个顺序查:

排查点检查命令常见原因
配置文件是否被覆盖ls -l /etc/netplan/cloud-init 重新生成了配置
YAML 是否语法正确sudo netplan generate缩进、Tab、字段名拼写
renderer 是否匹配systemctl status systemd-networkd后端服务未运行
是否有更高优先级配置检查文件名序号后加载文件覆盖了前面的
网卡名是否变化ip link show硬件变动导致命名改变

sudo netplan generate只做语法解析和配置生成、不实际应用,是排查 YAML 问题的利器,报错信息比apply更直接。另外云主机上要特别留意 cloud-init,它可能在每次启动时根据元数据重写网络配置,这时候需要修改 cloud-init 的配置源或者在 Netplan 文件里做好叠加,而不是跟它对着干。

6. 进阶:策略路由解决“网关加了但不走”的怪问题

6.1 什么时候需要策略路由

默认路由只有一条时,一切简单。但当你遇到“明明加了去某网段的路由,流量却还是从另一块网卡出去”的情况,多半是源地址选择在作祟。Linux 默认的路由决策只看目的地址,选好出口网卡后,源 IP 由该网卡的主地址决定。如果出口网卡的主地址不是对端期望的地址,回包就可能被丢弃。

策略路由的思路是:不只看目的地址,还看源地址、入接口、防火墙标记等条件,为不同流量指定不同的路由表。这在多线路、多租户、容器网络场景里是刚需。

6.2 用 ip rule 和自定义路由表分流

假设需求是:来自 192.168.2.0/24 的流量走 ens34 的网关 192.168.2.1,其余走默认。步骤是先在自定义路由表里写好路由,再用规则把流量导过去:

# 在表 100 里加默认路由 sudo ip route add default via 192.168.2.1 dev ens34 table 100 # 让来自 192.168.2.0/24 的流量查表 100 sudo ip rule add from 192.168.2.0/24 table 100 priority 1000 # 查看规则 ip rule show

priority数值越小越先匹配,内置规则里local表优先级是 0,main表是 32766,自定义规则插在中间即可。这套配置要永久生效,Netplan 里对应写法是在网卡下加routing-policy:

routing-policy: - from: 192.168.2.0/24 table: 100 routes: - to: default via: 192.168.2.1 table: 100

注意routes里的table字段和routing-policy要成对出现,只写一个不生效。这块配置的坑在于:自定义路由表里的路由不会自动出现在ip route show的默认输出里,得用ip route show table 100单独看,排查时容易误以为没配上。

7. 实操中踩过的坑与速查表

7.1 高频报错与对应解法

报错信息触发场景解决方向
RTNETLINK answers: File exists重复添加同目标路由改用replace或先del
Nexthop has invalid gateway网关地址不可达检查网关与本机是否同网段、链路是否 up
Invalid YAML缩进或 Tab 问题用netplan generate定位行号
Permission denied忘记 sudo加sudo执行
配置生效但重启丢失只改了运行时表改 Netplan YAML 并 apply
网关通但域名不通DNS 未配置检查nameservers字段

7.2 几条不写在文档里的经验

第一,改网络配置前先备份。sudo cp /etc/netplan/xxx.yaml /etc/netplan/xxx.yaml.bak,一行命令的事,出问题时能救命。远程操作时我还会额外开一个at定时任务,十分钟后自动恢复备份并重启网络,给自己留足回滚窗口。

第二,netplan try比apply更适合远程。它的自动回滚机制相当于给配置加了个保险,尤其是改默认网关这种可能断连的操作,养成先用try的习惯。

第三,metric 一定要显式写。默认值的不确定性是多网卡环境最大的隐形炸弹,写死数值让行为可预测,比事后排查省心一百倍。

第四,验证要分层。网关、外网 IP、域名三步走,别一上来就ping域名,DNS 问题会掩盖路由问题,让你在错误的方向上浪费时间。

第五,容器和虚拟机里的路由要分清命名空间。在宿主机上ip route看到的路由,和容器内看到的是两套表,排查容器网络问题时记得nsenter进对应命名空间再看,否则会对着宿主机正常的路由表一头雾水。

这套流程我在不同版本的 Ubuntu 上反复用过,从 18.04 到 24.04 主体逻辑没变,变的只是 Netplan 字段的废弃与新增(比如gateway4退场、routes成为标准写法)。遇到老教程和老脚本,先对照版本确认字段是否还受支持,比直接照抄稳妥。网络配置这件事,慢一点、验一层、留条后路,比快一步然后断线重连要划算得多。

返回列表