ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Ubuntu固定IP配置全攻略:Netplan原理、实操与避坑指南

Ubuntu固定IP配置全攻略:Netplan原理、实操与避坑指南

1. 为什么固定 IP 这件事值得认真对待

在局域网里折腾过服务的人大概都有过这种体验:明明昨天还能访问的测试机,今天开机后地址变了,SSH 连不上、数据库客户端配置失效、容器编排里的节点地址对不上,排查半天才发现是 DHCP 重新分配了租约。这种问题不致命,但极其消耗时间,尤其是在多机协作、自建服务、远程调试的场景下,地址漂移带来的连锁反应会让人抓狂。

Ubuntu 设置固定 IP 地址这件事,本质上是在解决"地址稳定性"这个基础问题。它适合所有需要在局域网内提供稳定服务的场景:自建文件服务器、数据库主机、开发测试环境、容器宿主机、监控采集节点、打印服务器等等。对刚接触 Linux 网络配置的新手来说,这是一道绕不开的坎;对有经验的从业者来说,这也是每次新机器上线时必做的一步标准动作。

但这里有个现实问题:Ubuntu 从 17.10 开始把网络配置从传统的/etc/network/interfaces迁移到了Netplan,而桌面版和服务器版的行为还不完全一样,再加上 Ubuntu 22.04、24.04 在 Netplan 版本上的演进,网上大量老教程直接照抄会踩坑。我见过不少人照着几年前的博客改配置,结果netplan apply报错、网络直接断掉,只能跑到机器跟前接显示器救场。

这篇内容就把这件事从头到尾讲透:Netplan 的配置逻辑是什么、YAML 文件怎么写、静态地址和网关 DNS 怎么配合、桌面环境和服务器环境有什么差异、改完之后怎么验证、出问题了怎么回滚。所有步骤都可以直接照着操作,参数选择也会给出计算和判断依据,不是那种"复制粘贴就完事"的流水账。

2. Netplan 的设计逻辑与方案选型

2.1 为什么 Ubuntu 要用 Netplan 这层抽象

要理解 Netplan,先得理解它想解决什么问题。在 Netplan 之前,Ubuntu 用的是ifupdown这套体系,配置文件是/etc/network/interfaces,写法偏命令式,不同发行版之间差异大,而且和 NetworkManager、systemd-networkd 这些后端管理工具容易打架。Netplan 的思路是引入一层声明式的 YAML 描述层,你只负责描述"我想要什么网络状态",具体怎么落地交给后端渲染器去执行。

这个设计的好处很直接:同一份 YAML 可以渲染给不同的后端。Ubuntu 服务器版默认用systemd-networkd作为渲染器,桌面版默认用NetworkManager。你在 YAML 里写的是同一套语法,Netplan 根据/etc/netplan/下配置文件的renderer字段决定交给谁执行。这就避免了以前"桌面用一套、服务器用另一套"的割裂感。

从实操角度看,这意味着你改配置时不需要关心底层是 networkd 还是 NetworkManager,只要 YAML 写对、渲染器指定对,netplan apply一执行就生效。但反过来说,如果渲染器指定错了,或者 YAML 缩进有问题,报错信息往往不够直观,这是新手最容易卡住的地方。

2.2 静态 IP、DHCP 保留、手动绑定三种方案怎么选

在动手改配置之前,先想清楚一件事:固定 IP 不一定非得在系统里配。实际有三种常见做法,各有适用场景。

方案实现位置优点缺点适用场景
系统内静态配置主机 Netplan不依赖路由器,地址绝对稳定换网段要改配置,多机管理分散服务器、固定机房环境
DHCP 地址保留路由器/ DHCP 服务端集中管理,主机零配置依赖 DHCP 服务可用性家庭网络、小型办公网
手动绑定 ARP交换机/路由器不改主机配置配置繁琐,维护成本高特殊兼容场景

我的建议很明确:服务器和需要长期稳定提供服务的机器,直接在系统里配静态地址。原因是它不依赖任何外部服务的可用性,DHCP 服务挂了、路由器重启了,你的机器地址照样不变。DHCP 保留适合那种机器多、又不想逐台登录改配置的场景,但它有个隐性风险——如果 DHCP 服务本身出问题,机器可能拿不到地址或者拿到错误地址。

手动绑定 ARP 这种方式现在用得很少了,除非是某些老旧设备不支持静态配置,否则没必要绕这个弯。

2.3 配置文件命名与优先级规则

/etc/netplan/目录下的配置文件按文件名字典序加载,后加载的会覆盖先加载的同名配置项。Ubuntu 安装后默认会生成一个类似50-cloud-init.yaml或01-network-manager-all.yaml的文件,具体名字取决于安装方式。

这里有个实操细节:不要直接改默认生成的那个文件,尤其是50-cloud-init.yaml,因为 cloud-init 在某些环境下会重新生成它,把你的修改覆盖掉。正确做法是新建一个编号更靠前的文件,比如99-static.yaml或者01-static.yaml,让它的配置优先生效。命名用两位数前缀是社区惯例,99-表示最后加载、优先级最高,01-表示最先加载。我一般用99-开头,语义上更符合"这是我的最终配置"的直觉。

注意:如果目录里同时存在多个配置文件且都定义了同一块网卡,Netplan 会按加载顺序合并,后加载的覆盖先加载的。改之前先ls /etc/netplan/看清楚有哪些文件,避免配置冲突。

3. 核心配置细节与参数计算

3.1 先搞清楚网卡名字和当前网络状态

改配置前必须先确认两件事:网卡的实际名称、当前使用的地址和网关。Ubuntu 现在的网卡命名规则是可预测网络接口名,不再是eth0这种简单名字,常见的有ens33、enp3s0、eno1等。名字搞错,配置写了也不生效。

查看网卡名称和状态,用这几条命令:

ip addr show ip route show

ip addr show会列出所有网卡及其地址,找到那个有state UP且有地址的接口。ip route show输出的第一行通常是default via x.x.x.x dev xxx,这里的x.x.x.x就是网关,xxx就是出口网卡名。

如果想看更结构化的信息,可以用:

networkctl status

这条命令在 systemd-networkd 环境下会给出每个接口的详细状态,包括 DHCP 租约信息、DNS 服务器等,排查问题时很好用。

3.2 地址、掩码、网关、DNS 的取值逻辑

静态配置需要四个关键参数:IP 地址、子网掩码(或 CIDR 前缀)、网关、DNS。这四个值不是随便填的,得和你的局域网规划对齐。

IP 地址要选一个在当前网段内、且没有被 DHCP 池占用、也没有被其他设备使用的地址。判断方法:先看当前 DHCP 分配的地址段,比如192.168.1.100/24,那网段就是192.168.1.0/24,可用范围是.1到.254。避开路由器常用的.1、.254,避开 DHCP 池的范围(很多路由器默认池是.100到.200),选个池外的地址,比如.50或.250。

子网掩码用 CIDR 表示,/24对应255.255.255.0,这是最常见的家用和小型办公网配置。如果是/16对应255.255.0.0,/25对应255.255.255.128。CIDR 和点分十进制的换算,记住一个简单规律:/24是 24 个 1,即前三个字节全 1;每减少一位,掩码范围翻倍。

网关通常是路由器的 LAN 口地址,从ip route show的default via后面直接读出来就行,不用猜。

DNS可以填网关地址(很多路由器自带 DNS 转发),也可以填公共 DNS。企业内网如果有内部 DNS 服务器,必须填内网的,否则域名解析会出问题。多个 DNS 用逗号分隔,按顺序尝试。

3.3 YAML 配置文件的完整写法与缩进陷阱

Netplan 的配置文件是 YAML 格式,缩进必须用空格,绝对不能用 Tab。这是新手翻车率最高的地方,一个 Tab 就能让netplan apply报出让人摸不着头脑的解析错误。

一个完整的静态配置长这样,假设网卡名是ens33,地址192.168.1.50/24,网关192.168.1.1,DNS 用192.168.1.1和8.8.8.8:

network: version: 2 renderer: networkd ethernets: ens33: dhcp4: no addresses: - 192.168.1.50/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: - 192.168.1.1 - 8.8.8.8

逐行解释一下关键点。version: 2是 Netplan 的配置版本,现在固定写 2。renderer: networkd指定用 systemd-networkd 渲染,服务器版用这个;桌面版如果 NetworkManager 在管理网络,要改成renderer: NetworkManager。ethernets下面是网卡定义,键名就是网卡实际名称。

dhcp4: no关闭 IPv4 的 DHCP。addresses是地址列表,注意 CIDR 后缀不能省。routes里to: default表示默认路由,via是网关地址。老版本 Netplan 用的是gateway4字段,但新版本已经废弃,用routes写法更稳妥,兼容性更好。

nameservers下的addresses是 DNS 列表。这里有个容易忽略的点:如果你只写 DNS 不写dhcp4: no,DHCP 拿到的 DNS 可能会和静态配置的混在一起,导致解析行为不确定。所以静态配置时一定要显式关掉 DHCP。

提示:写完配置后,先用netplan try而不是直接netplan apply。netplan try会应用配置并等待你确认,如果在规定时间内没有确认(或者按了 Ctrl+C),会自动回滚到之前的配置。这个机制在远程操作时是救命稻草,能防止配置写错导致失联。

3.4 桌面版与服务器版的渲染器差异

前面提到渲染器要匹配环境,这里展开说清楚。判断当前用的是哪个渲染器,看/etc/netplan/下默认配置文件里的renderer字段,或者直接看哪个服务在跑:

systemctl is-active systemd-networkd systemctl is-active NetworkManager

哪个返回active,基本就是哪个在管网络。Ubuntu 服务器版默认systemd-networkd活跃,桌面版默认NetworkManager活跃。如果两个都活跃,以 Netplan 配置里指定的renderer为准。

桌面版用 NetworkManager 有个额外好处:图形界面里的网络设置和 Netplan 配置是联动的,改完 YAML 后桌面右上角的网络图标状态会同步更新。但反过来,如果在图形界面里手动改了 IP,NetworkManager 可能会生成自己的配置文件,和你的 YAML 产生冲突。所以桌面版建议要么全用图形界面配,要么全用 Netplan 配,别混着来。

4. 完整实操流程与验证方法

4.1 从零开始配置静态地址的完整步骤

假设场景:一台 Ubuntu 服务器,网卡ens33,当前 DHCP 地址192.168.1.123/24,网关192.168.1.1,要改成静态192.168.1.50/24。

第一步,备份现有配置。这一步别省,出问题时能快速回滚:

sudo cp -r /etc/netplan /etc/netplan.bak

第二步,查看现有配置文件,确认没有冲突:

ls -l /etc/netplan/ cat /etc/netplan/*.yaml

第三步,新建配置文件。用nano或vim都行,文件名用99-static.yaml:

sudo nano /etc/netplan/99-static.yaml

把前面 3.3 节的 YAML 内容按你的实际参数填进去。注意网卡名、地址、网关、DNS 都要换成你自己的。

第四步,设置文件权限。Netplan 对配置文件权限有要求,太开放会报警告:

sudo chmod 600 /etc/netplan/99-static.yaml

第五步,先试运行:

sudo netplan try

如果配置语法没问题,会提示你按 Enter 确认。确认后配置生效。如果报错,根据错误信息检查 YAML 缩进和字段拼写。

第六步,正式应用(如果netplan try已经确认过,这步可跳过,但有些场景下try的超时机制会干扰,直接 apply 更干脆):

sudo netplan apply

第七步,验证。用ip addr show ens33看地址是否变成192.168.1.50/24,用ip route show看默认路由是否指向192.168.1.1,用ping -c 3 192.168.1.1测网关连通性,用ping -c 3 8.8.8.8测外网连通性,用ping -c 3 www.example.com测 DNS 解析。

4.2 验证清单与逐项排查

配置改完不是看到地址变了就完事,得逐项验证。我整理了一个验证清单,按顺序过一遍基本能覆盖所有问题点。

验证项命令预期结果异常含义
地址生效ip addr show <网卡>显示配置的静态地址配置未加载或网卡名错
默认路由ip route showdefault via <网关>网关字段写错或路由未渲染
网关连通ping -c 3 <网关>有回包网关地址错或链路问题
外网连通ping -c 3 8.8.8.8有回包路由或上游问题
DNS 解析ping -c 3 www.example.com解析出地址并回包DNS 配置错
渲染器状态networkctl status <网卡>显示 configured渲染器未接管

如果地址生效但外网不通,优先查路由;如果外网通但域名解析不了,查 DNS;如果网关都 ping 不通,查网卡名和链路。这个顺序是从底层往上排,能快速定位问题层级。

4.3 远程操作时的安全操作规范

在远程 SSH 会话里改网络配置,风险比本地操作高得多,因为一旦配置错误导致网络断开,你就失去了连接手段。几个必须遵守的规范:

第一,永远先netplan try再netplan apply。try的超时回滚机制是远程操作的保险绳。

第二,开两个 SSH 会话。一个用来操作,另一个保持连接不动。如果操作会话断了,另一个还能用(前提是配置没有彻底破坏网络栈)。

第三,改配置前记录当前状态。把ip addr、ip route、cat /etc/resolv.conf的输出保存下来,出问题时能对照恢复。

第四,避免在配置里同时改网卡名和地址。一次只改一个变量,改完验证通过再改下一个,降低排查难度。

第五,如果机器有带外管理(IPMI、iDRAC 之类),提前确认带外通道可用,这是最后的兜底手段。

注意:netplan apply执行后如果网络断了,SSH 会话会卡住,但机器本身可能还在运行。这时候不要反复重试连接,等一两分钟,有些配置需要时间收敛。如果确认断了,只能通过本地控制台或带外管理恢复。

5. 常见问题排查与避坑实录

5.1 配置不生效的六种典型原因

改完配置netplan apply没报错,但地址就是没变,这种情况我遇到过很多次,原因基本集中在以下几类。

YAML 缩进错误。这是最高频的。YAML 对缩进极其敏感,同一层级必须对齐,子层级必须比父层级多缩进。用netplan generate可以单独验证语法,它会渲染配置但不应用,报错信息比apply更详细:

sudo netplan generate

网卡名写错。ens33写成ens3或者eth0,配置会静默失效,因为 Netplan 找不到匹配的接口。用ip link show确认准确名称。

渲染器不匹配。服务器上写了renderer: NetworkManager但 NetworkManager 没装或没跑,配置就不会生效。反过来桌面版写了networkd但 networkd 没启用也一样。

配置文件权限不对。权限过于开放时 Netplan 会拒绝加载,netplan apply可能只给个警告。用chmod 600修正。

多个配置文件冲突。目录里有多个文件都定义了同一网卡,加载顺序导致你的配置被覆盖。ls /etc/netplan/看清楚,把冲突的旧文件移走或改名。

cloud-init 覆盖。云环境或某些安装方式下,50-cloud-init.yaml会被 cloud-init 重新生成。解决办法是在/etc/cloud/cloud.cfg.d/下加一个配置禁用网络配置,或者直接改 cloud-init 的 network 配置源。

5.2 网络断开后的紧急恢复手段

配置写错导致网络彻底断开,这是最让人紧张的时刻。恢复手段按可用性排序:

如果还能本地登录(物理机接显示器、虚拟机开控制台),直接编辑/etc/netplan/下的配置文件改回正确值,或者从备份恢复:

sudo cp /etc/netplan.bak/*.yaml /etc/netplan/ sudo netplan apply

如果只能远程但还有另一个会话连着,在另一个会话里操作恢复。如果所有会话都断了,只能走带外管理或请人到现场。

预防永远比恢复重要。我现在的习惯是:任何网络配置改动前,先确认带外管理可用,或者确认机器物理可达。这个习惯救过我很多次。

5.3 静态配置后 DNS 解析异常的排查

地址配好了、网关通了、外网 IP 能 ping 通,但域名解析不了,这是静态配置后很常见的问题。原因通常是/etc/resolv.conf的内容和 Netplan 配置不一致。

Netplan 配置的nameservers会通过渲染器写入/etc/resolv.conf(或者通过 systemd-resolved 管理)。检查实际生效的 DNS:

resolvectl status cat /etc/resolv.conf

如果resolv.conf是个软链接指向systemd/resolve.conf,说明 systemd-resolved 在管理 DNS,这时候要看resolvectl status里每个接口的 DNS 配置。如果 Netplan 里配了 DNS 但resolvectl里没显示,说明渲染器没把 DNS 传下去,检查nameservers字段的缩进层级是否正确。

还有一种情况:/etc/resolv.conf被其他工具(比如某些容器运行时或手动修改)覆盖了。检查文件是否是软链接,如果不是,说明有东西在直接写这个文件,需要找到源头处理。

5.4 双网卡与多网段环境的注意事项

机器有两块以上网卡时,静态配置的复杂度会上升。核心问题是默认路由只能有一个,多网卡都配网关会导致路由冲突。

正确做法是:只有一块网卡配默认路由(to: default),其他网卡只配地址和网段内路由,不配默认网关。如果确实需要多路径,得用策略路由,那是另一个话题了。

多网卡配置示例,ens33走默认路由,ens34只配内网地址:

network: version: 2 renderer: networkd ethernets: ens33: dhcp4: no addresses: - 192.168.1.50/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: - 192.168.1.1 ens34: dhcp4: no addresses: - 10.0.0.50/24

ens34不写routes和nameservers,它只负责同网段通信。跨网段流量走ens33的默认路由。这个结构在多网卡环境里最稳,不会出现路由抖动。

6. 我踩过的坑与实操心得

6.1 几个反直觉的细节

第一个坑:netplan apply不一定会重启网卡。在某些情况下,它只是重新渲染配置并通知后端,如果后端判断配置变化不影响链路,网卡不会 down/up。这意味着某些依赖链路状态变化才能生效的设置可能不生效。遇到这种情况,可以手动sudo ip link set <网卡> down再up,或者重启网络服务。

第二个坑:gateway4字段的废弃。老教程里大量用gateway4: 192.168.1.1,新版本 Netplan 虽然还兼容,但会给出 deprecated 警告,而且和routes混用时行为不确定。统一用routes写法,别用gateway4。

第三个坑:DNS 的search域。企业内网经常需要配搜索域,让短主机名能解析。这个在 Netplan 里是nameservers下的search字段,不是addresses。写错位置不报错,但解析行为不符合预期。

第四个坑:虚拟机快照和静态 IP 的冲突。用虚拟机做实验时,如果从一台配了静态 IP 的机器克隆出多台,所有克隆机地址都一样,网络直接冲突。克隆后第一件事就是改地址,或者克隆前先改回 DHCP。

6.2 配置管理的长期建议

机器多了之后,逐台登录改 Netplan 不现实。我的做法是把 Netplan 配置纳入配置管理,用 Ansible 之类的工具批量下发。模板里把网卡名、地址、网关做成变量,按主机清单渲染。这样新机器上线时一条命令搞定,也避免了手改出错。

对于少量机器,至少把配置文件纳入版本控制。/etc/netplan/目录用 git 管理,每次改动有记录,出问题能 diff 出改了什么。这个习惯成本很低,收益很高。

6.3 什么情况下不该用静态 IP

最后说个反向的经验:不是所有机器都该配静态 IP。临时测试机、频繁迁移的容器宿主机、笔记本这类会换网络的设备,配静态反而添麻烦。判断标准很简单:这台机器是否需要在固定地址上长期提供服务。是,就配静态;不是,用 DHCP 保留或者干脆动态分配更省心。

我见过有人给开发笔记本配了静态 IP,结果换个办公室网络就上不了网,还得手动改回来。这种场景用 DHCP 加路由器端的地址保留,体验好得多。工具是为人服务的,别为了"稳定"两个字给自己找不必要的工作量。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进