阿里云风险核验处理 阿里云服务器内网DNS服务
你有没有经历过这种场景:在阿里云ECS上跑着一个内部服务,用curl http://backend-api.internal死活不通,但一换成curl http://10.123.45.67立马活蹦乱跳?日志里只留一行冰冷的curl: (6) Could not resolve host: backend-api.internal——仿佛域名在服务器眼里,是个被拉黑的前任。
别急,这不是你的代码有bug,也不是网络策略在搞鬼,大概率是——你和阿里云的内网DNS,还没正式交换过微信名片。
一、它不是“那个DNS”,它是“阿里云特供版DNS”
很多人第一反应是:“不就是改个/etc/resolv.conf,填个8.8.8.8完事?”醒醒,那是公网DNS,专治全球网站;而阿里云VPC内网DNS,是嵌在你虚拟网络毛细血管里的本地向导——它不查根域名,不走公网,不翻墙,只认三件事:你在哪个VPC、属于哪个地域、是否开了内网域名解析功能。
它的默认地址通常是:100.100.2.136(主)和100.100.2.138(备),注意:这两个IP只在VPC内有效,出了网关就变“404”。它能自动解析三类名字:
- ECS实例名:比如
i-bp1a2b3c4d5e6f7g8h9(系统分配)或你自定义的order-service-prod; - 私有Zone域名:如
redis.cache.vpc、mysql.db.internal(需在云解析PrivateZone控制台手动创建); - 经典网络遗留兼容名(已逐步淘汰,不建议依赖)。
二、为什么nslookup说“server can't find…”,但ping却能通IP?
这是最经典的认知断层。真相是:ping直接走IP,绕过了DNS;而curl/wget/Java应用默认走域名解析——一旦DNS没配对,它们就集体失语。
验证步骤超简单:
# 查看当前DNS配置
$ cat /etc/resolv.conf
nameserver 100.100.2.136
nameserver 100.100.2.138
# 👉 如果这里写的是114.114.114.114?恭喜,你正在用公网DNS查内网名,注定失败
再试解析:
$ nslookup order-service-prod
Server: 100.100.2.136
Address: 100.100.2.136#53
** server can't find order-service-prod: NXDOMAIN
别慌——NXDOMAIN不等于“DNS坏了”,而是“这个名字根本没注册进阿里云的内网字典”。这时候你要问自己三个灵魂问题:
- 这台ECS是否绑定了
hostname?(hostname命令输出的值,就是它在内网DNS里的“身份证号”) - 该ECS是否在VPC中?且未开启“DHCP选项集”覆盖DNS?(很多企业账号会全局配置DHCP选项集,悄悄把
100.100.2.136替换成自建DNS,后果很严重) - 你查的域名,是不是压根没在PrivateZone里添加A记录?(比如想查
redis.cluster.local,但PrivateZone里只建了redis.cluster.internal)
三、手把手:让内网DNS真正为你打工
✅ 步骤1:确认基础连通性
先确保ECS能访问DNS服务器本身:
$ telnet 100.100.2.136 53
Trying 100.100.2.136...
Connected to 100.100.2.136.
连不上?检查安全组——入方向要放行UDP/TCP 53端口(目标是ECS本身,不是DNS!DNS在阿里云侧,你只需确保出方向畅通)。
✅ 步骤2:启用PrivateZone(推荐!)
登录云解析DNS控制台 → 左侧选“PrivateZone” → 创建私有域名,例如:svc.cloud → 关联你的VPC → 点击“添加记录”,填:
| 主机记录 | 记录类型 | TTL | 记录值 |
|---|---|---|---|
| mysql | A | 600 | 10.123.45.101 |
| redis | A | 600 | 10.123.45.102 |
从此,所有同VPC的ECS都能直接ping mysql.svc.cloud——干净、可读、不怕IP漂移。
✅ 步骤3:禁止“手贱改resolv.conf”
很多同学喜欢手动改/etc/resolv.conf,结果重启后被cloud-init覆盖回默认值。正解是:通过DHCP选项集统一管控(VPC级)或使用systemd-resolved(CentOS 8+/Ubuntu 20.04+)。一句话口诀:改配置,不改文件;管全局,不管单机。
阿里云风险核验处理 四、那些年我们共同踩过的坑
❌ 坑1:“跨可用区解析失败”
现象:杭州VPC内,可用区H的ECS能解析es-node-01,但可用区I的ECS查不到。
原因:实例名解析仅限同可用区内生效(阿里云设计如此)。
解法:必须用PrivateZone + 全VPC可见的域名,或通过SLB/NLB做统一入口。
❌ 坑2:“容器里DNS失效”
Docker/K8s Pod里nslookup返回127.0.0.11?那是dockerd内置DNS代理。它默认不转发到宿主机DNS!
解法:docker run --dns=100.100.2.136 或K8s中在Pod spec加:dnsPolicy: Default + dnsConfig指定nameserver。
❌ 坑3:“/etc/hosts优先级太高”
某次上线,开发同学为测试临时加了127.0.0.1 api.test到hosts,上线后忘了删——结果全量流量打到localhost,数据库直接躺平。内网DNS再准,也干不过本地hosts的“一票否决权”。
建议:生产环境禁用hosts做服务发现,用Consul或PrivateZone替代。
五、终极检查清单(运维人随身带)
- ✅
cat /etc/resolv.conf—— 是否为100.100.2.136? - ✅
dig @100.100.2.136 your-service.svc.cloud—— 直连DNS查,排除中间环节干扰 - ✅ 在PrivateZone控制台确认:域名已关联VPC、记录存在、状态为“启用”
- ✅ 检查ECS的“实例元数据”是否开启(
curl http://100.100.100.200/latest/meta-data/hostname应返回实例名) - ✅ 如用K8s,
kubectl get configmap -n kube-system coredns -o yaml里是否含forward . 100.100.2.136?
最后送一句大实话:DNS不是玄学,是基础设施的呼吸阀。它不声不响,一堵就全栈窒息;你多花15分钟理清它,未来能省下3小时抓包、5次重启、2次背锅大会。
下次再看到Could not resolve host,别先骂curl——先打开终端,敲下nslookup -debug your-domain,然后深呼吸,慢慢读那几行返回。你会发现,错误码背后,站着一位沉默但靠谱的内网向导,一直等你主动打招呼。

