Ubuntu配置固定IP教程:从netplan到NetworkManager实战详解
1. 为什么要给Ubuntu配一个固定IP说实话我最早接触固定IP这个概念的时候纯粹是因为烦——公司内网的机器每次重启IP就变SSH配置的别名全废了远程连不上还得跑一趟机房看ip addr那叫一个折腾。后来做服务器运维、搭开发环境、跑虚拟机集群慢慢才意识到固定IP不是一个锦上添花的功能而是一个真正的基础设施需求。先说清楚这个文章是干嘛的我会带你走一遍在Ubuntu上配置固定IP也叫静态IP的完整过程覆盖18.04之后默认的netplan方案、老版本还在用的ifupdown方案以及桌面版Ubuntu的NetworkManager图形界面配置。每个方案我都会给出可以直接抄的配置内容、对应的验证命令还有我自己踩过的坑和排查思路。不管你是刚装好Ubuntu想给虚拟机配个固定地址还是接手一台生产服务器需要统一网络规划这篇文章应该都能帮上忙。1.1 哪些场景真的需要固定IP很多人一上来就问固定IP有什么用其实这个问题的答案得看你拿Ubuntu干什么。最常见的场景是服务器。你在一台Ubuntu上跑了Web服务、数据库或者某个API接口客户端程序或者别人需要稳定地访问这个服务。如果IP是DHCP动态分配的一旦租约过期或者网卡重启地址就换了所有依赖这个地址的连接全部打断。更麻烦的是动态IP的地址范围是不可控的你没法提前告诉防火墙、数据库白名单放行哪个地址因为你自己都不知道下一次拿到的是什么。第二个场景是局域网里的网络服务比如你拿Ubuntu做NAS、打印服务器、网关、DNS缓存或者是在开发板上跑Ubuntu做嵌入式项目。这类服务的特点是别人要主动来找你也就是需要被寻址。固定IP等于给你的机器一个稳定的门牌号别的设备无论是通过浏览器访问管理页面还是通过SSH连上来都不用每次去查地址。第三个场景是虚拟机或者容器环境。我用VMware和VirtualBox跑Ubuntu虚拟机的时候特别喜欢给虚拟机配固定IP尤其是搞集群实验的时候——三个节点地址分别是192.168.56.101、102、103写配置脚本的时候直接写死IP完全不担心节点重启之后地址漂移导致集群失联。第四个场景可能很多人忽略调试网络程序和抓包。想用Wireshark抓某个固定IP的流量前提就是那个IP确实固定。如果目标机器的地址天天变你抓包之前的过滤规则就得跟着改那效率实在太低了。1.2 固定IP和DHCP的取舍先泼一盆冷水固定IP不是越多越好也不是所有机器都该配。这里面有个权衡问题。DHCP动态分配的好处是省心你插上网线路由器自动分配一个地址子网掩码、网关、DNS全都自动下发基本不需要人为干预。对于笔记本这种经常在不同网络之间移动的设备DHCP是唯一合理的选择——你不可能每换一个Wi-Fi就手动改一次IP。固定IP的优势在上面说过了稳定、可控、可预测。但它也有成本你得自己规划IP地址段避免和DHCP分配池冲突你得知道网关地址、子网掩码、DNS服务器地址你还得接受网络环境一变配置就得跟着改的事实。我的建议很简单服务器、长期运行的虚拟机、需要被外部访问的设备配固定IP日常办公机、笔记本、移动设备用DHCP。这个原则到现在我都在用没出过大乱子。2. 配置前的准备工作配置固定IP最怕什么最怕你连自己的网卡叫什么都搞不清楚就瞎改配置文件改完发现对应的根本不是你在用的那块网卡网络直接断了。所以正式开始之前先把准备工作做扎实。2.1 查看网卡名称和当前网络状态Ubuntu里查看网络信息我用得最多的命令是ip addr比老掉牙的ifconfig信息更全而且现代Ubuntu默认可能连ifconfig都没装。ip addr输出大概长这样2: ens33: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:0c:29:xx:xx:xx brd ff:ff:ff:ff:ff:ff inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic ens33 valid_lft 86391sec preferred_lft 86391sec这里要重点关注三个东西一是网卡名称。上面例子是ens33这是虚拟机网卡的常见命名。实体机上你可能会看到eno1、enp2s0、wlan0无线网卡、eth0之类。从Ubuntu 18.04开始网卡命名普遍采用基于硬件位置的可预测命名规则不会再出现老的eth0那种混乱命名除非你手动改回传统命名。看清楚是哪个网卡后面所有配置就围绕这个名字来写。二是当前IP地址。inet后面的192.168.1.100/24就是当前地址和子网前缀长度。/24等价于子网掩码255.255.255.0这个信息后面配置里要用到。三是地址来源。如果scope global后面带着dynamic字样说明这个地址是DHCP分配的如果没有dynamic多半是静态地址或者链路本地地址。这能帮你判断当前是不是已经是固定IP。看清楚了网卡名之后再看一眼路由信息确认网关地址ip route输出里默认路由那行是重点default via 192.168.1.1 dev ens33 proto dhcp metric 100这个192.168.1.1就是网关也就是你路由器或者交换机的管理地址。记下来待会儿配置里要用。最后看一眼DNS配置resolvectl status或者简单点直接看/etc/resolv.conf不过在现代Ubuntu上这个文件通常是指向systemd-resolved的软链接里面的内容可能不是你直接配置的。我一般用resolvectl status拿到实际的DNS服务器地址然后决定固定IP配置里DNS该填什么。2.2 确认你的Ubuntu版本和网络栈这一步非常重要因为不同版本的Ubuntu网络配置方式完全不一样。选错方案不仅白折腾还可能把系统网络搞坏。Ubuntu的网络配置经历过三个主要阶段16.04及更早版本使用/etc/network/interfaces文件配合ifupdown工具配置是纯文本格式写起来直观。18.04到22.04默认改用netplan配置文件是YAML格式放在/etc/netplan/下。netplan本身是一个前端的网络配置工具它会把YAML翻译成后端NetworkManager或者systemd-networkd能识别的配置。24.04及更新的版本依然用netplan但对Wi-Fi和桌面场景的默认行为有调整某些场景下NetworkManager接管得更多。查版本很简单cat /etc/os-release重点看VERSION_ID那一行。拿到版本号之后再确认系统现在用的是哪套网络管理工具ps -ef | grep -E NetworkManager|systemd-networkd | grep -v grep看到NetworkManager在跑说明你用的是NetworkManager后端看到systemd-networkd在跑说明是systemd-networkd后端。这个信息在netplan的配置方法里会用到因为netplan支持选择不同的渲染器。我建议拿个小本本或者直接在终端里开个临时文件把网卡名、当前IP、网关、DNS、Ubuntu版本这五个信息记下来后面每一步配置都要用到。3. netplan现代Ubuntu的固定IP配置方法如果你用的是18.04及以上的Ubuntu不管服务器版还是桌面版netplan都是最标准的配置方式。这个方案我实测下来是最稳的只要YAML格式别写错基本一次过。3.1 netplan配置文件结构速览netplan的配置文件统一放在/etc/netplan/目录下常见的文件名有01-network-manager-all.yaml桌面版默认、00-installer-config.yaml服务器版安装时生成或者50-cloud-init.yaml云镜像。文件名前面的数字决定加载顺序数字小的先加载后加载的文件如果配置项有冲突会覆盖先加载的。这个覆盖机制容易坑人后面我会专门讲。先看一个典型的服务器版初始配置通常是DHCP模式network: version: 2 renderer: networkd ethernets: ens33: dhcp4: true这个文件结构不复杂顶层是network下面version固定写2renderer指定后端渲染器可选networkd更适合服务器轻量稳定或NetworkManager更适合桌面ethernets下面按网卡名分条目wifi下面则写无线网卡的配置。3.2 静态IP配置完整示例把上面的DHCP配置改成静态IP我的标准写法是这样的network: version: 2 renderer: networkd ethernets: ens33: dhcp4: false dhcp6: false addresses: - 192.168.1.100/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: - 223.5.5.5 - 192.168.1.1 search: - example.local逐行解释一下我为什么这么写dhcp4: false、dhcp6: false明确关掉IPv4和IPv6的DHCP。如果你只关IPv4而忘了关IPv6某些情况下IPv6地址还是会被分配看起来就像固定IP不稳定。addresses这是核心指定IP地址和前缀长度。这里写的192.168.1.100/24含义是地址和子网掩码绑定在一起。很多人会把子网掩码写成255.255.255.0格式就错了。routes默认路由也就是网关。我习惯明确写出来不依赖DHCP下发的网关。nameservers.addressesDNS服务器。这里写223.5.5.5是阿里的公共DNS你也可以用114.114.114.114或者你们公司的内部DNS。search是DNS搜索域一般写你局域网的域名后缀如果没有可以不写。如果你不需要网关比如某些纯内网隔离环境只配IP不配路由那routes整段可以删掉。但凡是需要上网的机器默认路由必须写对不然网络不通。还有一个细节如果这台机器有多个网卡比如一个接内网一个接外网就在ethernets下面并列写多个条目。多网卡场景下路由配置会稍微复杂些需要用到策略路由policy routing这篇文章不展开先把单网卡搞定。3.3 应用配置与验证配置文件改完之后先检查格式sudo netplan generatenetplan generate只做语法检查和生成后端配置不会实际应用所以哪怕写错了系统网络也不会断。这一步我每次必做纯粹为了保险。然后应用配置sudo netplan apply重点来了netplan apply会重新配置整个网络栈在远程SSH连接的情况下如果配错了极易导致断连你人被锁在外面就麻烦了。我的经验是凡是远程操作一定要准备一个逃生方案。最保守的方式是在执行netplan apply之前先设一个定时任务把网络配置自动恢复sudo shutdown -r 5如果5分钟内配置没生效或者网络断了机器重启之后会回到之前的配置状态前提是配置文件的备份还在。当然如果你用的是带外管理比如服务器的iLO/IPMI或者VMware里的控制台远程断了也能从控制台救回来那这步可以省略。应用成功之后验证三步先看IP是否生效ip addr show ens33正常应该看到inet 192.168.1.100/24且后面没有dynamic字样。再看路由ip route确认default via 192.168.1.1 dev ens33存在。如果路由缺失多半是routes配置有问题或者网关和网卡不在同一个子网。最后测连通性ping -c 4 192.168.1.1 ping -c 4 8.8.8.8第一个ping网关验证链路层通不通第二个ping公网IP验证三层路由通不通。如果网关通了但公网不通基本是DNS或者防火墙的问题这个放到后面的排查部分细说。这里要特别提醒有一类问题是在netplan apply之后当时是通的重启之后配置丢失或者没用上。排查方向很明确一是看配置文件有没有被cloud-init之类的工具覆盖二是看文件名数字顺序是否可能导致多份配置互相覆盖三是看permissions是不是正常netplan文件要求权限为600或者644如果权限不对可能被忽略。4. 老派但好用的ifupdown配置如果你手头的Ubuntu还是16.04或者更早或者你接手了一台从没升级过的旧机器那大概率还是/etc/network/interfaces这套老配置体系。虽然netplan是趋势但老系统在跑你就得会修。4.1 interfaces文件写法传统配置的核心文件是/etc/network/interfaces先把原来的内容做个备份sudo cp /etc/network/interfaces /etc/network/interfaces.bak然后编辑配置静态IP的典型写法auto ens33 iface ens33 inet static address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.1 dns-nameservers 223.5.5.5 192.168.1.1 dns-search example.local这里和netplan的写法有几点不一样新手特别容易搞混一是子网掩码。这里必须是完整的点分十进制255.255.255.0不能写/24。虽然两者本质上是同一个东西但接口文件只认传统写法。二是dns-nameservers这个字段它实际上是老版本ifupdown的一个扩展。在Ubuntu 16.04上如果你装了resolvconf写在这里的DNS会自动进入/etc/resolv.conf这个机制本身是好的。但有个坑现代系统里/etc/resolv.conf可能被systemd-resolved接管你写在这里的DNS不会生效。所以老配置里DNS不生效先查resolvconf是不是在运行。三是auto这一行。auto ens33的意思是开机自动启用这块网卡千万别漏。漏了的话配置写了等于白写重启之后网卡起不来。修改完配置后重启网络服务sudo systemctl restart networking这里有个常见报错如果网络服务起不来看看是不是network.service这个单元不存在。Ubuntu 18.04之后networking.service还在但默认可能没启用因为默认走netplan了老系统上一般没问题。4.2 什么时候需要用ifupdown说实话现在新装的Ubuntu系统你基本遇不到ifupdown了除非你在做一些特殊操作。比如你在写一个嵌入式设备的系统镜像用的还是老内核老工具链或者你在做容器基础镜像镜像是基于16.04定制的又或者你接手了一套历史遗留的自动化脚本脚本里全是ifup eth0这种老命令。这些场景下掌握ifupdown的配置方式依然有价值。还有一个使用场景临时测试网络配置。ifup和ifdown这对命令比netplan灵活得多可以只对单块网卡操作sudo ifdown ens33 sudo ifup ens33这在调试单块网卡的时候非常方便不会像systemctl restart networking那样把所有网卡都重启一遍。netplan没有这么细粒度的命令netplan apply也是整体应用。不过坦白说如果系统支持netplan我还是建议优先用netplan因为它的YAML结构更清晰netplan generate还能帮你提前发现语法错误。ifupdown就是能用但别主动选择。5. 桌面版Ubuntu的NetworkManager配置桌面版Ubuntu带GNOME桌面的那种在装好的状态下网络默认归NetworkManager管。这种情况下你当然可以手动去改netplan文件但更省事的是直接用NetworkManager自己的工具链。5.1 GUI方式如果你人就在桌面跟前最快的方式是图形界面操作。点右上角的网络图标就是上下两个箭头的那个选择有线设置Wired Settings或者Wi-Fi设置在对应的接口旁边点齿轮图标切到IPv4标签页把自动(DHCP)改成手动然后填三样东西地址、掩码、网关。DNS在下面单独填。保存之后重新开关一下网络连接就能生效。这个方法没什么难度但有两个坑你得注意。第一GUI里填掩码的时候有些版本会让你填前缀长度比如24有些版本会让你填掩码255.255.255.0看清楚了再填别搞混。第二GNOME桌面的网络设置改完之后有时候不会立刻生效提示你得手动断开重连一次网络或者重启NetworkManager服务。5.2 nmcli命令行方式如果你是在远程桌面或者纯命令行环境下管理桌面版Ubuntu用nmcli更方便。先看当前有哪些连接nmcli con show输出里NAME列是连接名connection name注意它和网卡名不一定一样。比如有线连接可能叫Wired connection 1但这个连接底层绑的是ens33。修改连接为静态IPsudo nmcli con mod Wired connection 1 \ ipv4.method manual \ ipv4.addresses 192.168.1.100/24 \ ipv4.gateway 192.168.1.1 \ ipv4.dns 223.5.5.5 192.168.1.1然后重启这个连接sudo nmcli con up Wired connection 1这组命令的意思很直白把连接改成手动模式配置地址、网关、DNS重新激活。nmcli处理DNS的方式和netplan不太一样netplan直接操作systemd-resolvednmcli则是通过NetworkManager自己的DNS管理机制。改完配置之后DNS可能要等几秒才刷新或者需要重启一下NetworkManager。如果改完发现域名解析不了先resolvectl status看一眼DNS是不是更新过来了。nmcli的优势是命令可脚本化你要是一次要配置十台机器写个脚本循环跑就完事了。对比GUI方式nmcli更适合批量操作和远程管理。还有一点如果你桌面版Ubuntu里既用了NetworkManager又想用netplan最好保证netplan里的renderer写的是NetworkManager并且只给NetworkManager管理的网卡定义连接。两套系统抢同一块网卡的配置是网络配置混乱的头号原因这一点我踩过不止一次。6. 常见问题与排查实录固定IP这个东西配置本身不难难的是一旦出问题你要是没头绪能折腾一下午。下面这些问题是这些年我在Ubuntu上配固定IP时实际遇到过的我按出现频率排个序。6.1 DNS不生效或者说解析失败症状IP和网关都通了ping 8.8.8.8通但ping www.baidu.com报Temporary failure in name resolution。排查思路很明确问题出在DNS配置上。先看系统实际用的DNS是什么resolvectl status如果这里显示的DNS不是你配的那几个说明配置虽然写了但没生效。常见原因有三个一是netplan的DNS配置格式写错了YAML的列表缩进不对二是/etc/resolv.conf被某个程序覆盖了三是NetworkManager和systemd-resolved在抢DNS管理权。我的经验是先确认你改的是不是正在生效的配置文件。想想我前面强调过的netplan目录里可能有多个yaml文件加载顺序靠文件名数字决定。如果00-installer-config.yaml里写了DNS而99-custom.yaml里也写了后加载的会覆盖前面的。你写的那份可能根本没被当作最终配置。6.2 配置完之后网络直接断了这个是最惊悚的尤其是远程操作的时候。一旦发生先别慌。如果是本地操作有物理控制台或虚拟机控制台先把配置改回原来的DHCP恢复网络再说。如果恰恰是远程操作断了那就只能靠带外登录或者让机房帮忙重启然后利用开机自动恢复机制救回来。怎么避免这种情况我在前面提过远程改配置前加一个定时重启是笨但有效的保命手段。另外还有一个技巧先把新的配置文件写成另一个文件比如/etc/netplan/99-test.yaml然后手动执行sudo netplan trynetplan try和apply不一样它会在指定时间默认120秒后自动回滚到之前的配置如果你在这120秒内确认网络正常并按下回车配置才最终生效。这个命令就是为远程安全操作设计的强烈建议用。人话版本就是它先试一下新配置如果120秒内你不确认它自己就退回老配置了。这比定时重启靠谱多了。6.3 重启之后IP没生效症状netplan apply之后一切正常结果一重启IP又变回DHCP分配的地址了。这个问题我遇到过不少次排查方向有四个。第一配置文件有没有被cloud-init覆盖。云镜像安装的Ubuntucloud-init会在开机时根据云平台的metadata重新生成网络配置你自己写的文件可能被冲掉。解决办法是修改cloud-init的网络配置部分或者直接禁用cloud-init的网络管理echo network: {config: disabled} /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg但请注意这会关闭云平台自动网络配置能力线下环境无所谓云上要谨慎。第二检查netplan目录下的文件权限。netplan要求配置文件权限严格一般600属主root。如果权限不对netplan会静默忽略。第三多个配置文件的加载顺序问题。前面反复提了数字小的先加载后加载的覆盖。如果你把静态配置写在01-xxx.yaml里而DHCP配置在00-xxx.yaml里静态配置不生效就很正常了。第四你可能改了网络配置文件但NetworkManager或者systemd-networkd没真正接管。检查一下服务的启用状态systemctl status systemd-networkd systemctl status NetworkManager看看哪个在跑然后对比netplan配置里的renderer和你实际用的服务是否一致。6.4 固定IP和DHCP地址冲突症状配好固定IP后网络时通时断有时候连着连着突然断一下又自己恢复。这个基本可以断定是IP地址冲突——你配的静态IP恰好在DHCP的分配池范围内而且已经被某台设备占用了。路由器在分配地址时不会主动避让静态IP除非你配置了DHCP保留两边抢同一个地址表现就是时通时断。解决思路有两个一是把你的固定IP规划在DHCP分配池之外比如DHCP分配192.168.1.100到192.168.1.200那你的静态IP就选192.168.1.50这种池子外的地址二是在路由器上做DHCP预留reservation把静态IP和网卡MAC绑定确保路由器永远不会把这个地址分给别人。第二种方案更正规推荐生产环境使用。验证是不是冲突了可以在干净的交换机上抓包或者用arping来检查arping -D -I ens33 192.168.1.100 -c 3如果收到reply说明网络上有别的设备在用这个IP。没有arping的话sudo apt install arping装一下就能用。6.5 配置文件语法对了但就是不生效这类问题多半是YAML格式的细节错误。netplan的YAML对缩进极其敏感两级缩进和四级缩进不是同一个意思。我见过有人把addresses和dhcp4对齐到了不同的层级netplan报错还算友好会告诉你哪个字段类型不对但有些时候它不报错只是静默忽略。我的习惯是写完之后一定执行sudo netplan generate这个命令会生成后端实际使用的配置文件比如systemd-networkd的.network文件一旦语法有误它会明确报错。它不报错也不代表配置语义正确至少语法这关过了。然后打开生成的文件看看内容是否符合预期cat /run/systemd/network/*.network如果看到DHCPno、Address192.168.1.100/24之类的行说明netplan把你的意图正确翻译给了后端。7. 我的实操心得与避坑建议配置固定IP这件事表面上是一串命令和配置文件的问题实际操作中考验的是你对整个系统网络栈的理解。最后这部分聊聊我的心得体会。7.1 几个容易踩的坑第一别在无头服务器没有显示器和键盘的服务器上直接改网络配置。这不是配置方法问题是安全意识问题。你要是人在机房、有控制台随便改你要是只有SSH一条路建议务必用netplan try而不是netplan apply给自己留120秒后悔时间。第二配置静态IP之前一定要确认你选的地址是空闲的。用ping先探一下如果没人回应基本可以认为是空闲的。但这也不是绝对可靠有些主机禁ping地址照样被占用。严谨一点的做法是查路由器的DHCP客户端列表或者用arping做重复地址检测。第三虚拟机环境里配固定IP要注意虚拟网卡的配置模式。VMware里NAT模式、桥接模式、仅主机模式对网络行为的影响很大。比如你在VMware的NAT网络里给虚拟机配了一个和物理局域网相同网段的IP那Network Address Translation网络环境下是连不通的。配固定IP之前先搞明白你用的哪种虚拟网络模式再决定IP规划。第四笔记本这种多网卡、多无线网络切换的设备建议别配固定IP。我见过有人把Wi-Fi配成固定IP带到公司连不上网带回家也连不上网还得自己想起来改成DHCP才能用。固定IP是给固定环境准备的东西移动设备请保持DHCP。第五写netplan配置的时候该删除的旧配置一定删干净。我见过一份配置里既有旧的eth0条目又有新的ens33条目结果网卡名和配置对不上怎么配都不生效。配置文件和现实要一一对应别留僵尸配置。7.2 生产环境的配置建议如果你是在生产环境配固定IP我的建议比开发和测试环境要严格得多。首先所有网络配置文件必须纳入版本管理。/etc/netplan/目录里的yaml文件、/etc/network/interfaces都该提交到git仓库。这样一旦有人误改了配置你可以快速diff出差异并恢复。这个习惯我一直坚持救过不少次火。其次改配置要有变更流程。哪怕是你自己管的服务器也建议按这个顺序来先备份旧配置然后写新配置用netplan try验证确认无误后netplan apply最后观察一段时间我一般看15分钟以上确认没有异常再离开。网卡状态、路由表、DNS解析这三项在变更后半小时内最好都复查一遍。再者配置里的注释要写清楚。YAML支持#注释我习惯在每个网卡条目下面写清楚这地址是给什么服务用的、网关为什么从这里走、DNS是内网还是公网。三个月后你再看这份配置还能想起来当时为什么这么写这就值了。最后记得定期审查地址规划。随着机器数量增多IP可能不够用也可能出现分散配置的情况。我一般会维护一张表记录每台机器的IP、用途、所属网段、负责人。虽然听起来很像运维课教的东西但实际工作中这张表能在排查网络问题时省掉你大量时间。关于固定IP的配置方法上面这些内容基本覆盖了我在Ubuntu上遇到的大部分场景。从netplan到ifupdown从命令行到GUI从配置方法到故障排查核心思路其实就一条搞清楚你的系统用哪套网络管理栈改对应配置改完用对工具验证出问题先排查配置是否真的生效再看底层网络是否通畅。如果你按这个思路走一遍还搞不定欢迎带着具体的报错信息来交流——排查这类问题报错信息比什么都重要。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →