[{"content":"这次排障最开始看起来像是一个普通的 DNS 问题，日志里反复出现：\n[fetchSubscriptionAndCredits] 获取失败: dial tcp: lookup cloudcode-pa.googleapis.com on 8.8.8.8:53: read udp ... i/o timeout 但继续往下查以后我发现，问题并不只是某个应用的 DNS 配置，而是我这台 VPS 上运行的多个 Docker 应用都存在类似的“半通不通”现象：有些请求能成功，有些请求超时，有些容器能解析域名但实际连通性并不稳定。\n这篇文章记录一下完整的判断过程，以及最后收敛出来的修复方向。\n现象 最初我的直觉是容器里的 DNS 不通，因为报错里明确写到了 8.8.8.8:53。但很快我又意识到几个更重要的信息：\n不只是当前项目报错 换成 axios 也一样 其他 Docker 应用也有类似问题 这意味着问题大概率不在单个 Node.js 项目，而是在 Docker 网络层或者宿主机网络层。\n第一步：先验证宿主机和容器的 DNS 我先在 VPS 上检查宿主机的解析器状态：\ncat /etc/resolv.conf resolvectl status 宿主机上能看到几组关键信息：\n/etc/resolv.conf 走的是 127.0.0.53 当前上游 DNS 是 168.63.129.16 warp 接口上也挂了 1.1.1.1、8.8.8.8 等 DNS 然后我再看容器内部：\ndocker run --rm alpine cat /etc/resolv.conf docker run --rm busybox nslookup cloudcode-pa.googleapis.com 容器内的 /etc/resolv.conf 显示：\nnameserver 10.0.2.3 而 nslookup 是成功的，说明至少有两件事成立：\nDocker 内置 DNS 转发器是通的 cloudcode-pa.googleapis.com 在容器内可以被解析 到这里，我最初“Docker DNS 全挂了”的判断就站不住了。\n第二步：确认是不是 bridge 网络本身不稳定 接下来我分别测试宿主机网络、Docker bridge 网络和 IPv4/IPv6 的差异：\nip link show warp ip link show docker0 docker run --rm --network bridge alpine ip route docker run --rm --network host curlimages/curl:8.8.0 -I https://cloudcode-pa.googleapis.com docker run --rm --network bridge curlimages/curl:8.8.0 -I https://cloudcode-pa.googleapis.com docker run --rm --network bridge curlimages/curl:8.8.0 -4 -I https://cloudcode-pa.googleapis.com docker run --rm --network bridge curlimages/curl:8.8.0 -6 -I https://cloudcode-pa.googleapis.com 结果很关键：\n--network host 正常 --network bridge 也能成功发起 IPv4 请求 --network bridge -4 正常 --network bridge -6 失败 这说明：\nDocker 基础 IPv4 联通性并没有完全坏掉 问题更像是 IPv6 出口异常，或者某些程序优先尝试 IPv6 时出现回退不及时 如果应用在 DNS 返回了 AAAA 记录以后先尝试 IPv6，再经历失败和回退，就很容易表现成“有时通、有时超时”的半故障状态。\n第三步：为什么还会怀疑 MTU 查看链路 MTU 后，我又看到一个明显风险点：\nwarp mtu 1420 docker0 mtu 1500 这并不自动等于根因已经锁定，但它确实是 WARP 场景里非常常见的问题：\n宿主机走 warp 接口，MTU 较小 Docker bridge 还维持默认 1500 小包、DNS、部分短连接可能成功 大包、TLS 握手、HTTP/2 或某些返回路径就会变得随机不稳定 所以这里我的结论不是“只有 DNS 问题”，也不是“只有 MTU 问题”，而是：\n报错表面像 DNS 实际容器 DNS 基本可用 IPv6 明确不可用 Docker bridge MTU 又和 WARP 不一致 这几个因素叠在一起，就足够制造出典型的“网络半通不通”。\n第四步：应用层为什么也会误导排障 这个案例里，应用日志里出现了 8.8.8.8:53，很容易让我一开始直接把锅甩给 Docker 全局 DNS。\n但继续检查以后我也意识到，某些请求路径里还有应用自己的请求器配置，里面可能显式带了单独的 DNS 服务器。也就是说：\n系统层面 Docker DNS 可能是正常的 某条业务请求路径却可能绕过系统默认配置，直接访问固定 DNS 这类应用层配置不会解释“所有 Docker 应用都有问题”，但会让单个报错看起来更像 DNS，进而掩盖真正的系统网络问题。\n最后的修复方向 在这台 VPS 上，我最后认为最合理的第一步修复，是先把 Docker 的 MTU 和 DNS 固定下来：\nsudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json \u0026gt;/dev/null \u0026lt;\u0026lt;\u0026#39;EOF\u0026#39; { \u0026#34;mtu\u0026#34;: 1420, \u0026#34;dns\u0026#34;: [\u0026#34;168.63.129.16\u0026#34;] } EOF sudo systemctl restart docker 这一步的目标很明确：\n让 Docker bridge 的 MTU 与 warp 接口一致 避免容器再去走不确定的外部 DNS 组合 优先使用宿主机当前实际可用的上游 DNS 然后重建相关容器：\ndocker compose down docker compose up -d --build 如果改完以后仍然存在偶发超时，再继续看两个方向：\n让关键应用优先走 IPv4，避免被不可用的 IPv6 拖慢或拖死 对最敏感的服务临时改成 network_mode: host，确认问题是否集中在 bridge 网络层 这次排障里最值得记住的点 1. 单条报错不要直接等于根因 日志里写着 lookup ... on 8.8.8.8:53，不代表“整台 Docker 的 DNS 就一定坏了”。\n先做最小验证：\n容器里能不能 nslookup 容器里能不能 curl host 和 bridge 是否表现一致 -4 和 -6 是否表现一致 这些测试很快就能把问题从“猜测”缩到“网络层的哪一段”。\n2. “半通不通”通常比“完全不通”更像 MTU 或 IPv6 回退问题 纯 DNS 故障更容易表现为完全解析失败。\n而“有时成功、有时超时、不同应用表现不一致”，更像：\nMTU 不匹配 IPv6 不通但被优先尝试 策略路由或隧道网络与 Docker bridge 叠加后的副作用 3. WARP 打开以后，不代表 Docker 自动继承所有网络行为 宿主机能访问，不代表容器完全一样。\n尤其是在 Linux VPS 上，WARP、bridge、NAT、IPv6、MTU 叠加以后，容器网络经常会和宿主机表现不同。\n小结 这次问题最后并没有停留在“换个 HTTP 客户端”或者“改一下 DNS”这种表层处理，而是通过几组很小的验证，把问题逐步收敛到了系统网络层：\nDocker 默认 DNS 可解析 容器 IPv4 基本正常 容器 IPv6 明确失败 warp 与 docker0 存在 MTU 不一致 所以最实际的修复动作，是先把 Docker 的 MTU 对齐到 WARP，并固定到宿主机实际可用的 DNS，再根据结果决定是否继续压制 IPv6 或切换关键服务到 host 网络。\n如果你也遇到类似的“容器里域名能解析，但业务请求还是随机超时”的问题，这套排查顺序通常会比盯着单条报错反复猜更有效。\n","permalink":"https://blog.zsga.de/posts/docker-warp-network-troubleshooting/","summary":"从看起来像 DNS 的报错入手，最后定位到 VPS 上 Docker bridge、IPv6 和 WARP MTU 组合导致的网络不稳定。","title":"一次 Docker + WARP 网络半通不通的排障记录"},{"content":"👋 Hi，我是 Flow 📬 联系方式 GitHub: github.com/Mir237 Email: flow@zsga.de ","permalink":"https://blog.zsga.de/about/","summary":"关于我","title":"🧑 关于我"}]