上周帮朋友公司排查一个奇怪的问题:明明 DNS 记录已经生效,但新上线的虚拟化平台里,容器服务却总连不上内部域名。查日志、抓包、换解析服务器,折腾两天才发现——问题不在 DNS 本身,而在虚拟化管理平台对 DNSSEC 和 EDNS0 的处理逻辑和宿主机不一致。
不是 DNS 不工作,是“它”没看懂
很多团队以为只要 bind 或 CoreDNS 配好了,域名就能通。可当环境迁到 VMware NSX、OpenStack Neutron 或 K8s CNI 插件(比如 Calico + CoreDNS)后,解析行为可能突然变样。比如:
- 某些虚拟交换机默认截断大于 512 字节的 UDP 响应,导致带 OPT 记录的 EDNS 查询失败;
- Kubernetes kube-dns 在启用 hostNetwork 模式时,会绕过节点上的 resolv.conf,直接走集群 DNS,而虚拟化管理平台(如 vCenter 插件)调用的却是宿主机 resolver;
- OpenStack Octavia 负载均衡器后端健康检查若依赖域名,而其控制节点运行的是较老版本的 python-dnspython(<2.0),就无法正确解析 IPv6 AAAA 记录,报错却只显示“connection refused”。
真实场景:一次跨平台迁移踩的雷
某金融客户把原有物理机集群迁到 Nutanix AHV,同时启用了 AHV 的内置 DNS 代理功能。结果开发反馈:CI/CD 流水线里的 curl api.internal 偶发超时。抓包发现,AHV 的 DNS 代理在收到 TCP 回复后,会错误地将 TTL 强制设为 0 并缓存,导致本地 nscd 缓存失效混乱。临时解法是关掉 nscd,长期方案则是升级 AHV 到 2023.2+,该版本修复了 DNS 响应头字段透传逻辑。
怎么快速定位是不是兼容性问题?
别急着改配置,先做三件事:
1. 分层比对解析路径
# 在容器内执行(走 CNI DNS)
curl -v http://api.internal
# 在宿主机执行(走系统 resolv.conf)
dig api.internal @127.0.0.1 +short
# 在虚拟化管理节点执行(如 vCenter appliance 或 OpenStack controller)
nslookup api.internal 10.10.10.102. 看协议细节:用 tcpdump 抓 DNS 包,重点关注 flags(是否 RD/RA)、opcode、edns0 存在与否、response size 是否被截断。
3. 查虚拟化平台文档关键词:搜索 “DNS compatibility”、“EDNS support”、“DNSSEC validation” —— 很多厂商会在 Release Notes 里轻描淡写提一句:“默认禁用 EDNS 以提升稳定性”。
小建议:别让 DNS 成为黑盒
部署虚拟化平台前,拿个最简域名(如 test.dns.local)跑一遍全链路解析测试:从 hypervisor 控制台 → 宿主机 → 虚拟机 → 容器 → Service Mesh sidecar。记录每层的响应时间、TTL、返回 IP 类型(A/AAAA)、是否含 OPT。这个表,比任何架构图都管用。