DinD 中 OBS 请求超时:根因是 MTU 黑洞

在容器中调用华为云 OBS 时,请求在 DNS 解析成功后长时间没有响应,最终超时。相同 endpoint 从 Pod 的 host network 访问可以正常返回 403,因此问题集中在容器网络路径,而不是 OBS 服务本身。 先看服务端日志 失败容器的 runtime 日志有一条很重要的时间线: Endpoint=https://obs.cn-north-4.myhuaweicloud.com:443/ internet host address: phoenix-autotest.obs.cn-north-4.myhuaweicloud.com/123.60.240.82, phoenix-autotest.obs.cn-north-4.myhuaweicloud.com/123.60.240.83 这说明 DNS 解析已经完成。之后没有 HTTP 状态码,也没有 OBS 的业务异常。因此,失败点位于 DNS 之后、HTTP 响应之前,更接近 TCP/TLS,而不是 bucket、路径或签名参数。 产品的华为云插件确实直接使用 OBS SDK: this.obsClient = new ObsClient( settings.accessKeyId(), settings.secretAccessKey(), settings.endpoint()); 目录操作会调用 listObjects。在本机使用相同的 OBS 配置和 SDK 3.25.10 重放,接口可以正常返回。因此没有证据表明 AK/SK 或配置错误。 对照不同网络路径 运行服务的 Pod 使用 DinD sidecar: DOCKER_HOST: unix:///var/run/docker/docker.sock Phoenix 容器位于 DinD 的 bridge 网络中。在同一个 Pod 中做只读 HTTPS 探测,结果非常明确: ...

September 2, 2026

Talos 节点因 page_table_check BUG 重启:一次从误判到内核栈的调查

自动化测试使用 Playwright、Testcontainers 和 Docker-in-Docker。测试运行一段时间后,talos2 会从 Kubernetes 中消失,iDRAC 报告 System CPU Resetting,对应的测试分片失败。 这次调查最终拿到了完整的内核 panic 栈。直接原因不是硬件 reset,也不是 pid_max 耗尽,而是 Linux 6.18 中 PAGE_TABLE_CHECK 对 time namespace 的 VVAR 页面错误记账,触发了 BUG_ON()。 最初看到的现象 高并发 testcontainers 场景下,监控 Pod 观察到: loadavg=90+ pids=6890 threads=12513 dstate_count=6 eBPF 还记录到一分钟内大量进程和网络命名空间操作: fork_parent[runc]: 1597 fork_parent[containerd-shim]: 1209 fork_parent[dockerd]: 779 netns operations: 1303 unshare: 38 同时出现两类 D-state 栈。一类在网络命名空间清理路径: rcu_barrier netdev_run_todo default_device_exit_batch ops_undo_list cleanup_net process_scheduled_works worker_thread 另一类在容器文件清理路径: folio_wait_bit_common folio_wait_writeback truncate_inode_partial_folio truncate_inode_pages_range xfs_fs_evict_inode evict do_unlinkat __x64_sys_unlinkat 这些现象很容易让人得出一个合理但不完整的结论:高并发容器创建、删除导致 netns、workqueue、XFS 和 NVMe 同时拥塞,最后触发 hard lockup。 ...

August 31, 2026

用 LD_PRELOAD 解决容器环境中的 Chrome ERR_NETWORK_CHANGED

运行 Playwright 自动化测试时,我们遇到过一种很难稳定复现的失败:页面正在正常加载,Chrome 却突然报错: net::ERR_NETWORK_CHANGED 它看起来像目标服务断网,但实际检查后发现: 被访问的服务没有重启 Pod 本身的网络仍然可用 同一时刻,Pod 内的容器引擎正在创建或销毁其他容器 重试通常又能成功 真正变化的不是 Chrome 正在使用的网络,而是同一网络命名空间中的虚拟网卡。 为什么启动容器会影响 Chrome 在服务器运行 Docker 时,每次创建或销毁容器,都可能伴随这些操作: 创建或删除 veth 设备 给虚拟网卡增加或移除 IP 地址 更新链路状态和路由信息 这些变化会通过 Linux Netlink 机制通知用户空间。Chrome 恰好也是这些通知的订阅者。 Chromium 在 Linux 上使用 AddressTrackerLinux 跟踪网络状态。初始化时,它会创建一个路由 Netlink 套接字: netlink_fd_.reset(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)); 随后订阅多组网络事件: addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NOTIFY | RTMGRP_LINK; 因此,同一网络命名空间里任何网卡的地址或链路发生变化,都可能被 Chrome 观察到。事件再经由 NetworkChangeNotifierLinux 向网络栈传播,最终让正在进行的请求以 ERR_NETWORK_CHANGED 结束。 整个链路可以简化成: 创建或销毁容器 ↓ 虚拟网卡、IP 或链路状态变化 ↓ 内核发送 NETLINK_ROUTE 消息 ↓ Chrome 的 AddressTrackerLinux 收到变化 ↓ NetworkChangeNotifier 通知网络栈 ↓ 正在进行的请求被中断 Chrome 的行为对桌面用户是合理的。例如从 Wi-Fi 切换到有线网络后,旧连接确实可能已经失效。但在 CI 中,其他容器产生的虚拟网卡变化通常与浏览器访问的目标毫无关系。 ...

July 23, 2026