本文尝试介绍 systemd-resolved、systemd-networkd、NetworkManager、netplan 的关系和联系,并分层详细剖析它们的关系,以及 DNS 配置的传递流程。
介绍
这是一个非常经典且容易让人混淆的问题。Linux 的网络栈在近年来发生了很大的变化,导致这几个组件经常同时出现,让人摸不着头脑。
简单来说,它们的关系是:Netplan 是老板(配置生成器),NetworkManager 和 systemd-networkd 是包工头(后端执行者),而 systemd-resolved 是专门负责查电话本(DNS 解析)的秘书。
四者关系图解
可以将它们分为三层:配置层、后端层、服务层。
graph TD
User[用户 / 管理员] -->|编写 YAML| Netplan[Netplan (配置描述层)]
subgraph "后端 / 渲染器 (Renderers)"
Netplan -->|生成配置| NetworkManager[NetworkManager (适合桌面/WiFi)]
Netplan -->|生成配置| Networkd[systemd-networkd (适合服务器)]
end
subgraph "DNS 服务"
NetworkManager -->|通过 DBus 推送 DNS| Resolved[systemd-resolved]
Networkd -->|通过 socket/DBus 推送 DNS| Resolved
end
Resolved -->|提供服务| App[应用程序 (ping/curl/browser)]
各组件角色详解:
-
Netplan (配置翻译官)
- 角色: 它是 Ubuntu 17.10+ 引入的抽象配置工具。
- 作用: 它本身不运行网络,也不负责联网。它只负责读取
/etc/netplan/*.yaml 文件,然后把这些简单的 YAML 配置翻译(生成)成后端能看懂的配置文件。
- 关键点: 它决定了使用哪个后端(通过
renderer: networkd 或 renderer: NetworkManager 指定)。
-
systemd-networkd (服务器端主力)
- 角色: systemd 自带的网络管理后台进程。
- 作用: 它负责应用 IP 地址、配置路由、启动网卡。它非常轻量,适合服务器和容器环境。
- 关系: 它是 Netplan 的默认后端之一。
-
NetworkManager (桌面端主力)
- 角色: 老牌的网络管理后台进程。
- 作用: 同样负责配 IP、路由。它非常擅长处理动态变化的网络(如 Wi-Fi 漫游、VPN 切换、热点插拔)。
- 关系: 它是 Netplan 的另一个可选后端。
-
systemd-resolved (DNS 专家)
- 角色: 专门处理 DNS 解析的服务(如上一条回答所述)。
- 作用: 不管 IP 是谁配的,DNS 解析请求最终通常都汇聚到这里。
- 关系: 它被设计为与 networkd 和 NetworkManager 配合工作。
Netplan 的 DNS 是如何传递给 systemd-resolved 的?
这是用户最关心的技术细节。Netplan 里的 nameservers 字段并不会直接写入 /etc/resolv.conf,而是经过了一个接力传递的过程。
流程取决于你在 Netplan 中选择的 renderer(渲染器)。
当 renderer 是 networkd (服务器默认)
- 编写: 你在 Netplan YAML 中写下:
ethernets:
eth0:
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
- 生成 (Netplan 阶段): 运行
netplan apply 后,Netplan 会在 /run/systemd/network/ 目录下生成一个 .network 文件(例如 10-netplan-eth0.network)。
- 该文件内容大致如下:
[Network]
DNS=1.1.1.1 8.8.8.8
- 读取 (networkd 阶段):
systemd-networkd 守护进程检测到这个新文件,读取它,并配置网卡。
- 推送 (IPC 阶段): 关键一步 ——
systemd-networkd 会通过内部机制(通常是 DBus 或 socket)通知 systemd-resolved:嘿,eth0 接口的 DNS 服务器是 1.1.1.1。
- 生效:
systemd-resolved 收到通知,将其加入自己的内存配置中,并通过 127.0.0.53 对外服务。
当 renderer 是 NetworkManager (桌面默认)
- 编写: Netplan YAML 内容同上,但
renderer: NetworkManager。
- 生成 (Netplan 阶段):
netplan apply 会在 /run/NetworkManager/system-connections/ 目录下生成 NetworkManager 的配置文件(通常是 .nmconnection 格式)。
- 读取 (NM 阶段):
NetworkManager 读取该配置并应用。
- 推送 (IPC 阶段):
NetworkManager 自身也有管理 DNS 的能力,但现代发行版通常配置它将 DNS 委托给 resolved。
- NetworkManager 会检测到
systemd-resolved 正在运行。
- NetworkManager 通过 DBus 向
systemd-resolved 发送信号,注册这些 DNS 服务器。
- 生效: 同上,
systemd-resolved 接管解析请求。
为什么有时候修改不生效?常见误区
理解了这个传递链条,就能明白为什么有时候 DNS 设置会出问题:
-
直接改 /etc/resolv.conf 被覆盖:
- 因为
systemd-resolved 是最终生效者,它会管理这个文件。如果你不通过 Netplan 或后端工具修改,重启网络服务后,resolved 会重新覆盖它。
-
NetworkManager 未托管:
- 如果 Netplan 设置了
renderer: networkd,但你还在尝试用 nmcli (NetworkManager 的工具) 去改 DNS,那是无效的,因为 NetworkManager 根本不管理那个网卡。
-
systemd-resolved 未启动:
- 如果
systemd-resolved 服务挂了,虽然 Netplan 把配置给了 networkd,networkd 也想推送 DNS,但接收方(resolved)不在,导致 DNS 解析失败。
总结
- Netplan 是编剧,写好剧本(YAML)。
- systemd-networkd / NetworkManager 是导演,根据剧本指挥现场(配置网卡),并把 DNS 信息传达给专用负责人。
- systemd-resolved 是接线员,最终接收导演传来的 DNS 地址,并实际处理所有的电话查询(DNS 解析)。
数据流向:
Netplan YAML -> 后端配置文件 -> 后端守护进程 (networkd/NM) -> (DBus/Socket) -> systemd-resolved -> 应用程序