Vector 0.10.0 移除自定义 DNS 解析:破坏性变更解析与升级指南
【免费下载链接】vectorA high-performance observability data pipeline.项目地址: https://gitcode.com/GitHub_Trending/vect/vector
Vector 在 0.10.0 版本中正式移除了自定义 DNS 服务器(dns_servers)配置项,这是一个破坏性变更(breaking change),由 PR #2812 引入。本文基于仓库中的变更公告文档,完整梳理该特性的来龙去脉、升级操作步骤、迁移替代方案,并结合当前仓库源码(src/dns.rs 及各类 sink 的网络连接器)剖析移除后 Vector 的 DNS 解析真实实现,帮助你顺利完成配置迁移并理解底层行为。
背景:曾被引入的自定义 DNS 服务器特性
要理解这次移除,先回顾该特性的来源。早在 Vector 0.6.0 时代,官方在2019-12-13 的功能公告(PR #1118、#1362、#1371、#1400、#1451)中引入了自定义 DNS 服务器能力,允许用户在全局配置中通过数组字段dns_servers指定一组 DNS 服务器,例如:
dns_servers: ["0.0.0.0:53"]当时的语义是:一旦设置dns_servers,Vector 将忽略系统 DNS 配置,仅使用用户提供的服务器列表进行域名解析。这为那些运行在特殊网络环境(如封闭内网、非标准 DNS 端口)中的部署提供了便利,但也意味着 Vector 需要自行管理一套独立于操作系统的 DNS 解析链路。
为什么在 0.10.0 移除
变更公告给出了明确的动机,可归纳为两点:
- 代码复杂度代价过高:支持自定义 DNS 服务器需要在 Vector 内部维护一套完整的自定义解析逻辑,显著增加了代码复杂度(该特性涉及 PR #1118 等 5 个 PR 才落地),对长期维护构成负担。
- 职责边界更清晰:DNS 解析本质上是操作系统与网络栈层面的职责,交由宿主环境统一管理更合理。公告明确指出,这类需求"better handled outside of Vector",即更适合通过
systemd-resolved之类的系统级工具或容器网络配置来处理。
移除的总体目标是"让 Vector 保持精简、易于理解,并提升可维护性"(keep Vector lean and understandable, as well as improving its maintainability)。
升级指南:如何修改配置
如果你正在使用该特性,升级到 Vector 0.10.0 后必须移除vector.toml(或vector.yaml)中全局的dns_servers配置项。变更公告给出的 diff 如下:
- dns_servers = [...]只需删除这一行即可。需要说明的是,仓库中仍可找到该配置项的遗留示例,例如 managing-schemas.md 中的示例配置仍包含dns_servers: [](空数组,即不指定任何自定义服务器,等效于使用系统 DNS);该示例属于历史遗留写法,在新版本中应一并移除,避免配置校验告警。
在 Vector 之外启用自定义 DNS
如果移除后你的环境仍依赖非标准 DNS 解析,公告给出了两条替代路径:
- 宿主机级配置:通过
systemd-resolved等系统级 DNS 管理工具配置宿主机的解析行为。systemd-resolved支持按网络接口、按域名(split DNS)等方式灵活下发 DNS 服务器,Vector 作为普通进程会自然继承宿主机的解析结果。 - 容器级配置:将 Vector 放入容器运行,并通过容器的
--dns参数(Podman / Docker 均支持)为容器指定 DNS 服务器。容器运行时负责接管容器内进程的 DNS 查询,Vector 无需感知具体配置细节。
这两条路径的本质是一致的:把 DNS 决策权交还给运行环境,Vector 只使用操作系统提供的标准解析结果。
移除后 Vector 的 DNS 解析实现(源码级)
移除自定义 DNS 后,Vector 的域名解析全部走系统标准机制。当前仓库中 src/dns.rs 完整保留了这一实现,是理解"回归系统 DNS"这一设计的最佳入口。
Resolver:基于系统ToSocketAddrs的轻量解析器
src/dns.rs 中定义了一个零大小的Resolver结构体,其核心方法是lookup_ip:
- 复用
std::net::ToSocketAddrs标准 trait 的to_socket_addrs(),即完全依赖操作系统的解析行为(如/etc/resolv.conf、NSS 配置等); - 解析过程通过
tokio::task::spawn_blocking放入阻塞线程池执行,避免系统解析可能产生的阻塞影响异步运行时; - 对
localhost做了特判,固定解析为 IPv4 的127.0.0.1(注释引用了 RFC 6761 第 6.3 节,因为并非所有操作系统都将localhost解析为 IPv6::1); - 解析前会剥离主机名两侧的方括号,正确处理
[::1]这类 IPv6 字面量写法; - 附加的
dummy_port = 9(discard 端口)仅用于满足ToSocketAddrs对(host, port)的调用签名,解析完成后随即丢弃。
pub(crate) async fn lookup_ip(self, name: String) -> Result<LookupIp, DnsError> { let dummy_port = 9; if name == "localhost" { Ok(LookupIp(vec![SocketAddr::new(Ipv4Addr::LOCALHOST.into(), dummy_port)].into_iter())) } else { spawn_blocking(move || { let name_str = name.as_str(); let name_ref = name_str .strip_prefix('[') .and_then(|s| s.strip_suffix(']')) .unwrap_or(name_str); (name_ref, dummy_port).to_socket_addrs() }) .await .context(JoinSnafu)? .map(LookupIp) .context(UnableLookupSnafu) } }与 Hyper 的集成:实现Service<Name>trait
src/dns.rs 为Resolver实现了tower::Service<hyper::client::connect::dns::Name>,Response类型为迭代器LookupIp(逐个产出IpAddr)。这使得 Vector 的 HTTP 客户端(Hyper 的 DNS 解析钩子)可以直接复用该解析器,LookupIp同时实现了Iterator<Item = IpAddr>(src/dns.rs)。
错误处理
解析错误通过DnsError枚举表达(src/dns.rs),覆盖两类失败:底层系统解析错误(UnableLookup,包装tokio::io::Error)与阻塞任务执行失败(JoinError)。该错误类型被多处复用,例如 src/sinks/mod.rs 中的DnsFailure/DnsError变体,以及 src/sinks/util/service/net/mod.rs 中的FailedToResolve,最终统一以Failed to resolve语义呈现给用户。
调用链:sink 网络连接器
当前仓库中,dns::Resolver被广泛用于各类 sink 的网络连接路径,均遵循"先lookup_ip取第一个 IP,再建立连接"的模式:
- TCP 连接器:
TcpConnector::connect中解析目标主机后构造SocketAddr,再建立 TLS/非 TLS 连接,是 elasticsearch、clickhouse、loki 等大批 HTTP/TCP 型 sink 的通用底座; - UDP 连接器、通用 TCP sink、通用 UDP sink 以及 WebSocket 客户端 均使用同一
lookup_ip路径。
测试用例印证
src/dns.rs 的单元测试覆盖了四种典型解析场景,可作为行为契约:
| 测试 | 输入 | 验证点 |
|---|---|---|
resolve_example | example.com | 常规域名经系统 DNS 可解析 |
resolve_localhost | localhost | 特判路径解析成功 |
resolve_ipv4 | 10.0.4.0 | 纯 IPv4 字面量解析 |
resolve_ipv6 | ::1 | IPv6 字面量(括号剥离逻辑)解析 |
可以看到,移除自定义 DNS 后,Vector 的解析行为完全收敛到"宿主机的标准解析结果",这也与变更公告"Vector once again follows the guidance of the host on DNS lookups"(再次遵循宿主机在 DNS 查询上的引导)的表述完全一致。
总结与迁移检查清单
升级到 Vector 0.10.0 或更高版本时,建议按以下清单核对:
- 检查全局配置(
vector.toml/vector.yaml)中是否存在dns_servers,存在则直接删除(空数组dns_servers: []也应移除); - 确认宿主机 DNS 配置(
systemd-resolved、/etc/resolv.conf等)能够满足 Vector 目标地址(sink 主机名、API 域名)的解析需求; - 如需按部署环境差异化解析,优先选用容器运行时
--dns参数或系统级 split-DNS 方案,而不是在 Vector 配置中实现; - 若解析异常,关注
Failed to resolve类错误日志(对应 src/dns.rs 的DnsError),其根源在于操作系统解析环境而非 Vector 内部。
这一变更本质上是 Vector 架构取舍的缩影:把边界内的事做简单、把边界外的事交给更专业的系统组件——DNS 解析由此回归操作系统,而 Vector 得以保持精简与可维护。
【免费下载链接】vectorA high-performance observability data pipeline.项目地址: https://gitcode.com/GitHub_Trending/vect/vector
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考