干过运维的朋友应该都有这种经历服务器跑着跑着网络不通了机房不让进只有远程控制台一屏黑底白字ifconfig、ip addr、route、arp 轮流敲好不容易排到问题改配置文件还得小心翼翼怕手一抖服务起不来。后来我慢慢养成习惯凡是能用 NetworkManager 的场景一律用 nmcli 来管网络确实省了不少事。nmcli 是 NetworkManager 自带的命令行管理工具不需要图形界面几乎集成了网络管理所有常见操作查看连接、启停网卡、改 IP、配 DNS、加路由甚至搭建 bond 链路聚合都可以用它一条条命令搞定。写这篇东西是想把我平时用得最多的 nmcli 常见操作整理一遍重点放在真实服务器上一定会遇到的那些场景尤其是 bond 配置给刚开始接触 Linux 网络管理的朋友一条比较省心的路子。1. 为什么我推荐用 nmcli 管网络1.1 它相当于给 NetworkManager 装了一个命令行开关NetworkManager 大家不陌生发行版默认都在跑桌面环境下右上角那个网络图标就是它的前端。问题是一到服务器上没有图形界面那个图标就成了纯资源占用很多人干脆把它 mask 掉转头去用 systemd-networkd 或者直接改 ifcfg 文件。我的观点是NetworkManager 本身没毛病问题在于没有好用的交互入口。nmcli 就是这个入口。它直接把 NetworkManager 的管理能力拉到了终端里连接、设备、Wi-Fi、bond、vlan、桥接全部可以作为对象来操作。而且 nmcli 的输出是纯文本方便脚本抓取和自动化这在批量运维里是刚需。这里先解释“连接”和“设备”这两个概念新手经常搞混。设备是物理网卡或者虚拟网卡比如 eth0、eno1连接是一组配置参数比如 IP、网关、DNS它绑在某一个设备上。你可以先定义很多连接但只有一个连接能在一个设备上处于激活状态。nmcli connection 管的是连接nmcli device 管的是设备。把这一层关系搞清楚后面的命令基本就能对上号了。1.2 比手改配置文件更安全传统做法是直接编辑 /etc/sysconfig/network-scripts/ifcfg-eth0CentOS/RHEL或者 /etc/network/interfacesDebian/Ubuntu改完还要判断要不要重启网络服务。这里有两个痛点第一配置文件格式容易记错单词拼错一个网卡可能直接起不来第二如果同时改了多张网卡重启一瞬间所有网络全部断开远程连接直接熔断。用 nmcli 修改不会立即生效需要主动执行 nmcli connection up 才会应用而且在 up 之前你可以通过 nmcli connection show 检查配置是否完整等于多了一道保险。更重要的是nmcli 会把你的配置同步写入 NetworkManager 自己的配置存储里下次 NetworkManager 启动后自动加载不依赖特定发行版的启动脚本。1.3 适合哪些场景我主要在三种场景下用 nmcli。第一种是云服务器和物理服务器初始化拿到机器后第一件事就是配置静态 IP 和 DNS第二种是虚拟机里调试网络比如模拟多网卡和 bond第三种是自动化运维把 nmcli 命令写进脚本或 Ansible Playbook。如果你是用笔记本装 Linux 桌面平时靠 WiFi 联网nmcli 同样能帮你在终端里连 WiFi、查看信号强度体验不比图形界面差。2. nmcli 基础操作先学会看网络状态2.1 一条命令看全局最常用的开局命令是 nmcli general status。它直接告诉你 NetworkManager 整体状态是不是 running有没有在管控网络。执行后的输出类似$ nmcli general status STATE CONNECTIVITY WIFI-HW WIFI WWAN-HW WWAN connected full enabled enabled enabled enabledSTATE 是 connected说明 NetworkManager 正在正常工作CONNECTIVITY 是 full表示网络连通性正常。WIFI-HW 表示无线硬件开关WIFI 是无线功能开关WWAN 是移动网络服务器上通常都是 disabled 或 unavailable不用在意。如果 STATE 显示 running 但 CONNECTIVITY 是 limited多半是 DHCP 拿不到地址或者 DNS 有问题排查的时候先看这一行能省下不少时间。2.2 查看连接列表nmcli connection show 是用的最多的命令之一。它能列出所有已经定义好的连接不管连接是否激活。示例输出$ nmcli connection show NAME UUID TYPE DEVICE bond0 abc... bond bond0 eno1 def... ethernet eno1注意排在末尾的 DEVICE 列如果显示为空说明这个连接没在用了。查看当前活跃的连接加一个 --active 参数nmcli connection show --active。这个命令在检查多网卡服务器时特别好用一眼能看出哪几张网卡正在承载网络流量。2.3 查看设备状态nmcli device status 是设备层的总览输出$ nmcli device status DEVICE TYPE STATE CONNECTION eno1 ethernet connected eno1 eno2 ethernet disconnected -- bond0 bond connected bond0STATE 表示设备当前状态比如 connected、disconnected、unavailable。unavailable 通常意味着物理链路没接上或者驱动有问题。CONNECTION 列是这个设备当前激活的连接名。想查看某块网卡的详细配置例如 IP、MAC、网关、DNS用 nmcli device show eno1。这个命令的输出很长但信息全尤其在核对双网卡路由的时候比 ip addr 更直观。2.4 快速启停连接和刷新 DHCP需要临时断网再恢复用 nmcli connection up 连接名 和 nmcli connection down 连接名 是最直接的。up 会确保该连接被成功激活如果配置有改动也会在这时应用down 会让设备脱离连接设备状态变成 disconnected。我在测试网络修改时常用的一个动作是nmcli connection up bond0 之后紧接着 ping 网关验证联通性。另外如果设备处于 connected 但 IP 过期或者 DHCP 租约异常可以先用 nmcli connection down 再 up强制重新走一遍 DHCP。注意 down 当前正在使用的连接会断开网络远程操作时小心断连建议配合控制台或者把修改命令写成脚本批量执行不要手一抖把自己关在门外。2.5 无线网卡也不在话下虽然服务器上无线网卡用得少但笔记本装 Linux 的时候nmcli 连 WiFi 比图形界面点来点去更快。扫描热点用 nmcli device wifi list连接指定 WiFi 用nmcli device wifi connect MyWiFi password pass1234如果机器上有多个无线网卡可以指定 ifnamenmcli device wifi connect MyWiFi password pass1234 ifname wlan0想临时开一个热点给手机用nmcli device wifi hotspot ifname wlan0 ssid myssid password pass1234 就能搞定。这些操作在调试无线网络时很实用关键是命令简洁不依赖桌面环境。3. 用 nmcli 创建和修改网络连接前面说过连接就是一组配置。创建连接需要明确两个关键参数连接名和设备名。连接名是逻辑名随便起设备名是物理接口名比如 eno1、ens3必须和系统实际接口对上。查看接口名用 ip link 或者 nmcli device status。3.1 创建一个静态 IP 连接假设服务器有两个网卡eno1 用于业务eno2 用于管理。现在要给 eno1 配一个静态 IP比如 192.168.10.100/24网关 192.168.10.1DNS 用 223.5.5.5 和 114.114.114.114。nmcli connection add type ethernet con-name eno1 ifname eno1 \ ipv4.addresses 192.168.10.100/24 \ ipv4.gateway 192.168.10.1 \ ipv4.dns 223.5.5.5 114.114.114.114 \ ipv4.method manual这条命令创建了一个名为 eno1 的 ethernet 类型连接绑定了 ifname eno1。ipv4.method manual 是核心表示不使用 DHCP完全按手动配置来。DNS 可以写多个用空格分隔必须用引号包起来。执行后 NetworkManager 会自动生成一个连接配置文件路径通常是 /etc/NetworkManager/system-connections/eno1.nmconnection。注意两个容易犯的错第一IP 地址必须要写前缀长度比如 /24 不能丢丢了你可能拿到一个没有掩码的地址后续路由各种诡异第二con-name 和 ifname 可以相同也可以不同但如果像很多教程那样写成 con-name 业务网卡容易在后期混淆我建议连接名直接用设备名或者加一个业务/管理前缀一目了然。创建完连接后还需要激活nmcli connection up eno1这时如果原设备上还有另一个活跃连接它会自动替换掉。如果不放心可以先 nmcli device status 看看 eno1 的状态。3.2 创建一个 DHCP 连接如果网卡不需要固定 IP比如虚拟机 NAT 网络、DHCP 环境创建命令更简单nmcli connection add type ethernet con-name eno2 ifname eno2 ipv4.method autoipv4.method auto 表示自动获取地址。这里不写 ipv4.addresses 也不会报错。激活后可以用 nmcli device show eno2 看到从 DHCP 拿到的 IP、网关和 DNS。如果发现 DHCP 没有拿到地址最常见的坑是上游没有开 DHCP 服务或者虚拟机网卡没有接对网线先检查这些再折腾命令。3.3 修改现有连接需要改 IP 的时候用 nmcli connection modify 而不是删了重建。常见用法nmcli connection modify eno1 \ ipv4.addresses 192.168.10.200/24 \ ipv4.gateway 192.168.10.1 \ ipv4.method manual注意modify 只是修改配置不会立刻生效必须再次 nmcli connection up eno1。另外如果你新加了一个 IP而之前已经有一个 IP默认情况下会把旧 IP 替换掉。如果你希望同时保留多个 IP可以这样写nmcli connection modify eno1 ipv4.addresses 192.168.10.200/24加了加号表示追加不加就是覆盖。这个细节很多教程里没写但实际非常有用。比如服务器需要临时加一个管理网段地址这招比重新写配置文件快得多。DNS 的修改也类似nmcli connection modify eno1 ipv4.dns 223.5.5.5 nmcli connection modify eno1 ipv4.dns 114.114.114.114第二行的加号是追加 DNS注意追加时如果 DNS 里已经存在你写的那个地址不会重复添加。3.4 删除连接和整理连接删连接用nmcli connection delete eno1被删除的连接会同时从磁盘和内存中移除网卡会回到未配置状态需要重新创建。删除时一定要确认这个连接没有承载当前紧要业务因为不会二次确认。如果连接创建错了但不想完全删除可以重命名连接nmcli connection modify eno1 connection.id 业务网卡修改 connection.id 就能改连接名名称变了不影响设备绑定。这个操作在批量初始化服务器时很好用可以先统一用模板名配置完成后再按业务改成有意义的名字。4. nmcli 配置 bond一张网卡挂了另一张顶上bond 是文章的重头戏。不少朋友在服务器上遇到网卡冗余的需求。bond 的原理简单说把多张物理网卡绑成一个逻辑网卡对外表现成一个 IP 地址对内由 bond 驱动分担流量或做故障切换。最常见的是两张千兆网卡绑成一个 bond0一张断了另一张自动接管业务不中断。4.1 先说清楚 bond 的几种模式配置 bond 之前必须选模式模式选错会导致两张网卡只能一张用或者流量分配不符合预期。用 nmcli 配置时mode 参数支持以下几种模式名称作用active-backup主备模式同一时刻只有一张网卡工作主卡故障自动切换备份卡balance-rr轮询模式数据包轮流从两张网卡发出带宽利用率高balance-xor基于源目 MAC 的 XOR 计算性能均衡broadcast广播模式所有包往所有网卡发适合特殊环境802.3ad动态链路聚合需要交换机支持 LACP 协议balance-tlb发送负载均衡接收由当前活跃卡负责balance-alb自适应负载均衡发送和接收都做了负载分配我平时用得最多的是 active-backup 和 802.3ad。服务器没有特殊交换机配置时active-backup 最省心两张卡一主一备不需要交换机配合。如果想提高整体带宽且交换机确定了开启 LACP那就用 802.3ad。不要天真地以为 bond 一定能带宽翻倍balance-rr 虽然可以同时用两张网卡发流但很多交换机或网络环境并不兼容balance-alb 对网卡驱动和系统要求也高。保守方案就是在 active-backup 下确保可用性。4.2 创建 bond 主连接第一步创建 bond 逻辑网卡。比如要建一个名为 bond0 的 bond 连接模式选 active-backup然后给 bond0 配置静态 IP 192.168.1.50/24nmcli connection add type bond con-name bond0 ifname bond0 \ bond.options modeactive-backup \ ipv4.addresses 192.168.1.50/24 \ ipv4.gateway 192.168.1.1 \ ipv4.dns 223.5.5.5 \ ipv4.method manual这一步生成的 bond0 连接本身已经带 IP 和网关。注意如果纯粹想先创建 bond 再单独配网络也可以不带 ipv4 参数后面再用 modify 补但既然一步能做完我更推荐直接带上。type bond 和 ifname bond0 要分清type 是设备类型ifname 是逻辑接口名。创建完成后可以用 nmcli connection show bond0 看有没有生成不过此时 bond0 还没有真正工作因为下面要加入物理网卡。4.3 把物理网卡加入 bond接下来需要为每张物理网卡创建一个“子连接”告诉 NetworkManager 这张网卡属于 bond0。假设服务器有两张物理网卡 eno1 和 eno2nmcli connection add type ethernet con-name bond0-port1 ifname eno1 master bond0 nmcli connection add type ethernet con-name bond0-port2 ifname eno2 master bond0注意master bond0 是关键参数表示这个 ethernet 连接是 bond0 的成员。不要给这两个成员连接配置 IP因为 IP 在 bond0 主连接上如果给成员单独配 IP会造成地址冲突。创建时不需要指定 modemode 在 master 连接上决定。如果你已经用传统方式创建了成员连接也可以用 modify 把它挂到 bond 下nmcli connection modify bond0-port1 master bond0但前提是原来的连接类型要合适我这里直接新建更省事。还有一个细节成员连接的 con-name 不要和物理网卡名一样我用 bond0-port1 这种格式看到名字就知道它是哪个 bond 的哪个口排查问题时比一长串 UUID 舒服多了。4.4 激活 bond 连接成员加完后激活 bond0nmcli connection up bond0激活 bond0 时NetworkManager 会自动把两个成员连接也激活。这时执行 nmcli device status你会看到 bond0、eno1、eno2 都变成 connected其中 bond0 的 CONNECTION 列是 bond0eno1、eno2 的 CONNECTION 列是各自的成员连接名。马上验证一下逻辑接口是否存在ip link show bond0 cat /proc/net/bonding/bond0/proc/net/bonding/bond0 的输出很关键里面可以看到 Bonding Mode、MII Status、Slave Interface 等信息。MII Status 是 upSlave Interface 下面列出了 eno1 和 eno2说明两张网卡都已经被 bond 接管了。4.5 验证 failover 是否正常配置完成不能只看状态必须做故障切换测试。最简单的测试方法拔掉一张物理网线或者在系统层面禁用一张网卡nmcli device disconnect eno1或者用 ip link set eno1 down。这时再 cat /proc/net/bonding/bond0应该能看到 active slave 切换到了 eno2MII Status 还是 up。然后 ping 网关确认网络没有长时间中断。恢复 eno1 用 nmcli device connect eno1。我实测过在 active-backup 模式下故障切换通常在百毫秒级别但 ping 丢包可能有一到两包这是正常现象。如果丢包太多甚至断流几十秒先检查是不是 mode 选错了或者网卡驱动在切换时被重置。如果成员连接没有自动激活也可以手动 nmcli connection up bond0-port1 补一下。5. 配置 bond 和日常维护中的疑难杂症5.1 注意 bond 与不同网卡驱动、NetworkManager 版本的关系不同发行版的 NetworkManager 对 bond 的支持程度有细微差别。有些版本中bond 连接创建时如果不显式指定 connection.autoconnect yes重启后可能不会自动启用。所以我会在建完 bond 后顺手加一句nmcli connection modify bond0 connection.autoconnect yes成员连接也可以加一下避免重启之后 bond 起来了成员却掉线。另外如果用的是特定厂商的网卡驱动里可能还要设置 ethtool 的参数比如 offload 相关这些一般不归 nmcli 管系统初始化时单独配置。遇到网卡模式异常先用 ethtool eno1 查看网卡速率、自协商状态别急着改 bond 配置。5.2 网卡名对不上是最常见的坑Linux 网卡命名有 udev 规则有时机器重启后 eno1 和 eno2 的物理对应关系会变尤其是添加新网卡后导致 bond 成员接错卡。排查时用 ethtool -p eno1 可以让网卡指示灯闪烁确认物理位置。还有一个办法是看 /sys/class/net/eno1/device/uevent 里的 PCI 地址和 lspci 对照。这一步在物理机操作时特别重要别等到配置完发现 bond 用的是两张无关网卡才后悔。5.3 常见问题速查现象可能原因解决办法nmcli 命令找不到NetworkManager 未安装或未启动安装 NetworkManager 并 systemctl enable --now NetworkManagerbond0 创建后看不到没有激活连接nmcli connection up bond0bond0 起来了但两张网卡都不通IP 配到了成员连接上删除成员上的 ipv4 配置确保 IP 只在 bond0主备切换后 IP 短暂丢失ARP 缓存和路由更新需要时间等待几秒或清 ARP 缓存确认网关在同一网段balance-rr 模式网速反而变慢交换机不支持或开启了 STP 干扰改回 active-backup 或启用 802.3ad重启后 bond 没自动起来autoconnect 没有启用connection.autoconnect yes删除成员连接后 bond 少了一块网卡NetworkManager 没有感知变化nmcli connection reload这些坑我基本都踩过。尤其是把 IP 配置到成员连接上这个问题几乎每个新手都会犯bond 没建好就先给 eno1 配了 IP然后把 eno1 挂进 bond0结果 bond0 一直没地址eno1 又提示 connected排查了大半天才发现是概念混了。记住一句话bond 的 IP 只在主连接上成员连接永远只负责“入队”。5.4 修改 bond 参数的技巧如果想修改 bond 模式或参数比如把 active-backup 改成 802.3ad不能直接改先确认交换机支持 LACP然后再执行nmcli connection modify bond0 bond.options mode802.3ad,miimon100改完要 down 再 up 连接nmcli connection down bond0 nmcli connection up bond0也可以一次指定多个参数。miimon 表示链路监测间隔单位毫秒默认是 100一般可以保守设成 100。数值太大链路断开后检测会变慢太小对网卡和系统中断负担会变大。还有 primary 参数可以指定主网卡。例如nmcli connection modify bond0 bond.options modeactive-backup,miimon100,primaryeno1这样 active-backup 模式下系统会优先用 eno1eno1 恢复后会自动切回避免主备来回抖动。修改 bond.options 会整体覆盖原有选项改之前最好先记一下当前的完整 options 值以免把之前调好的参数弄丢。6. 我平时积累的几个 nmcli 小习惯6.1 批量检查所有连接状态写脚本的时候我习惯用 terse 模式输出方便传给 awk、cut 处理。比如列出所有连接名nmcli -t -f NAME connection show这会输出每一行一个连接名。如果要拿设备状态用nmcli -t -f DEVICE,STATE device status输出类似 eno1:connected数据是以冒号分隔的。字段名记不住可以先看 nmcli help 或者 nmcli connection --help。批量巡检时把这些命令套进 for 循环效率比一条条人肉看高多了。6.2 使用 nmcli 修改而不重启网卡以前改 IP 的老套路是 vi ifcfg-eth0 然后 systemctl restart network每次都要担心断连。用 nmcli 之后可以彻底告别这种状态。改配置和激活分两步配合脚本可以做到比较平滑的切换。例如把 IP 改成新网段的命令nmcli connection modify eno1 ipv4.addresses 10.0.0.10/24 ipv4.gateway 10.0.0.1 ipv4.method manual nmcli connection up eno1注意如果你的机器是通过这个 IP 远程连接的执行 up 瞬间网络会中断然后再恢复。为了避免把自己断出去建议先把新 IP 用 ipv4.addresses 追加进去等确认能连通后再把旧 IP 移除。这是我在生产环境切换 IP 时常用的技巧nmcli connection modify eno1 ipv4.addresses 10.0.0.10/24 nmcli connection up eno1 ping 10.0.0.10 nmcli connection modify eno1 -ipv4.addresses 192.168.10.100/24 nmcli connection up eno1先加新地址等新地址通了再减掉旧地址。中间网络不会完全断开远程操作安全性高很多。6.3 配置文件的备份和恢复虽然 nmcli 面向命令行但底层还是要写配置文件的。要从一个环境复制网络配置到另一台机器最省事的是直接拷贝 /etc/NetworkManager/system-connections/ 下对应的 nmconnection 文件。拷贝前先 nmcli connection show 查看有哪些连接再 cp 文件到新机器后执行 nmcli connection reload 加载。不过要注意文件权限NetworkManager 要求连接文件权限通常是 600属主 root否则拒绝加载。我遇到过复制过去一切正常但 NetworkManager 不认文件的情况最后发现是权限变成了 644。每次修改重要网络配置之前我都会先把当前连接文件备份一下cp -a /etc/NetworkManager/system-connections/ /root/netbak-$(date %F)这个习惯救过我两次一次是 bond 配置损坏导致网卡起不来另一次是 DNS 改成错误地址后网络全断。有备份在手恢复网络就是一两分钟的事。6.4 我最后想提醒的一件小事别看 nmcli 的命令面面俱到它也不是万能的。比如复杂的策略路由、多路由表规则nmcli 支持不如直接写 ip rule / ip route 顺手。我的习惯是普通网络配置用 nmcli路由策略和高级 QoS 用 iproute2两边不打架。最后分享一个检查习惯每次配置完 bond 或者改完网卡我都会先 nmcli general status 看整体状态再 nmcli device status 看设备最后 cat /proc/net/bonding/bond0 确认链路细节三层检查全过才敢收工。刚开始你会觉得多条命令啰嗦但等你碰到过几次半夜被报警电话叫起来排查网络的事就会明白这种检查习惯能省下多少睡眠时间。