背景:云手机项目,底座为华为鲲鹏 920(ARM64)+ AMD GPU,Android 以容器方式运行在 Docker / K8S 之上(KBox 底座)。AOSP 升级到 15 之后,部分容器出现"能 ping 通 IP、域名解析却失败"的网络故障。本文记录从症状到根因的完整排查过程,最终合成于提交
13585312d9efe158f41530c68a60b225c6e61cfd。
1. 症状
android_59:/ # ping -c 2 223.5.5.5 # IP 层通
64 bytes from 223.5.5.5: icmp_seq=1 ttl=41 time=27.2 ms
android_59:/ # ping -c 2 www.baidu.com # 解析层死
ping: unknown host www.baidu.com
resolver 侧的日志签名把问题钉死在"没有 DNS 服务器",而不是"DNS 查询发出去被拒":
# packages/modules/DnsResolver/res_send.cpp:500-509
doQuery: rcode=0, ancount=0, return value=-3 # -3 = -ESRCH(nameserverCount()==0 → 查询根本没发出)
# packages/modules/DnsResolver/DnsProxyListener.cpp:909-910
GetAddrInfoHandler::run: {0 786432 0 983040 1000 0}
# ^^^^ dns_netid=0:没有默认网络,resolver 拿不到 nameserver 列表
Android 的 DNS 链路是:网络注册 → NetworkAgent 携带 LinkProperties(含 DNS 列表)→ ConnectivityService 交给 DnsManager → setResolverConfiguration 下发给 netd/resolver。链路上任何一环断掉,resolver 的 nameserverCount 就是 0,所有域名解析立即返回 -ESRCH。
排查从此展开,最终发现是三层故障叠加:
flowchart TD
A["症状: 能 ping IP<br/>域名解析 unknown host"] --> B{"第一层:<br/>接口有没有被跟踪?"}
B -->|"正则被 AAPT 剥掉反斜杠"| C["wlan0 不被 EthernetTracker 认领<br/>→ 无 NetworkAgent → dns_netid=0"]
B -->|"已跟踪"| D{"第二层:<br/>静态配置有没有生效?"}
D -->|"id 不匹配 / 文件读不到"| E["lp 无 DNS<br/>AOSP 15 已废弃 net.dns* 兜底"]
D -->|"已生效"| F{"第三层:<br/>网关在不在?"}
F -->|"重启后 main 表 default 丢失"| G["provisioning 失败<br/>无默认路由 + 无 DNS → 全死"]
F -->|"在"| H["健康"]
style C fill:#ffcccc
style E fill:#ffcccc
style G fill:#ffcccc
style H fill:#ccffcc