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 showip 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 show | default 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/24ens34不写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 加路由器端的地址保留,体验好得多。工具是为人服务的,别为了"稳定"两个字给自己找不必要的工作量。