从IP直连到域名配置:一次Nginx代理问题引发的DNS学习笔记
起因
那天在配置Nginx反向代理的时候,碰到个不大不小的问题。配置文件里proxy_pass后面跟的是域名,不是平时习惯的IP加端口。启动之后Nginx报错,说解析不了这个域名。
一开始没想明白。我们这环境是内网,后端服务就在那几台机器上跑着,平时都是IP直接访问,怎么到了Nginx这里还得搞个域名出来。
后来同事说改一下/etc/hosts就行。照做了,确实能用了。但心里一直有个疙瘩------这到底是个什么原理?为什么改了本机的一个文件,Nginx就能找到后端了?同事还提到什么resolv.conf、内网DNS,听着就更迷糊了。
花了点时间把这块彻底捋了一遍,记一笔,也希望能帮到跟我一样从内网IP直连起步、对域名和DNS没怎么接触过的朋友。
先说我原来的习惯
之前不管是开发还是测试,都是IP加端口走天下。
http://192.168.1.100:8080/api/health
简单、直接、不用动脑子。配置里写死,curl测试的时候也写死。反正内网环境,IP又不会天天变。
但随着服务越来越多,问题开始冒头。有一次后端服务迁移,IP从.100换到了.200,所有配置文件要改一遍,还要通知组里其他人。改漏一个就出问题,不厌其烦。
后来看了别人写的Nginx配置,才发现他们用的都是域名。
proxy_pass http://api.backend.com:8080;
当时第一反应是------这域名哪来的?公网上也没注册过啊。后来才知道,原来内网也能用域名,只不过是自己定义的,跟公网没关系。
域名这东西,本质上就是个代号
域名本身不值钱,值钱的是它背后指向的IP。
打个比方,IP地址相当于你家的门牌号,精确、唯一,但不好记。域名就是你家门口挂的牌子,上面写着"张家小院"。邻居找你就认牌子,牌子指向哪个门牌号,他们就奔哪去。
内网域名也是一样。api.backend.com这个名字,你在外网查不到,但在你自己网络里,你可以告诉所有人------"这个名字指的就是192.168.1.100那台机器"。
那怎么让系统认识这个域名呢
两台机器之间通信,说到底还是得靠IP。域名只是给人看的,机器不认。
所以从域名到IP,必须有个翻译过程。负责翻译的这个系统,就是DNS。
但在这之前,系统还会先翻翻本地的一个小本本,就是这个文件:
/etc/hosts
这个文件就是本机的一张手写对照表。格式很简单:
192.168.1.100 api.backend.com
系统收到一个域名解析请求时,会先打开这个文件,一行一行看。如果找到了匹配项,直接就用了,不再问别人。
这也就是为什么修改/etc/hosts能立竿见影的原因------不是问题解决了,是直接跳过了问题的环节。
但改这个文件有一个限制:只对本机有效。我改了,我的机器认识api.backend.com,隔壁同事的机器不认识。他要是想访问,要么也改自己机器上的hosts,要么就得走真正的DNS查询。
那真正的DNS又是怎么回事
如果把/etc/hosts比作自己手里的通讯录,那DNS就是全城的查号台。
我们配置在/etc/resolv.conf里的那个IP地址,其实就是告诉系统------你查不到的时候,去问这个查号台。
nameserver 114.114.114.114
这是一台公网的DNS服务器。你给它一个域名,它给你返回一个IP。比如你问baidu.com,它告诉你110.242.68.66。
但问题是,公网DNS不认识内网自己造的域名。api.backend.com这个域名在公网上没有注册,你问公网DNS,它就回你一句"查无此号"。
所以内网环境里,如果想全域都能通过域名访问,就得自己搭一个DNS服务器,让所有人的机器都把/etc/resolv.conf指向它。
自己动手搭一个最简单的内网DNS
如果公司还没有内网DNS,而你又不想让每台机器都去改hosts,可以自己搭一个简单的。
dnsmasq这个小工具就够用,轻量、配置简单。
找一台内网机器,装一下:
bash
yum install dnsmasq -y
然后编辑配置文件/etc/dnsmasq.conf,在末尾加一行:
address=/api.backend.com/192.168.1.100
这行配置的意思是:所有对api.backend.com的查询,都返回192.168.1.100这个IP。
启动服务:
bash
systemctl start dnsmasq
systemctl enable dnsmasq
然后把这台机器的IP(假设是192.168.1.1)告诉所有人,让他们修改/etc/resolv.conf:
nameserver 192.168.1.1
这样一来,不管谁访问api.backend.com,都会去问这台DNS服务器,得到192.168.1.100这个IP。
如果以后后端IP变了,只需要在dnsmasq的配置里改一次,所有人自动生效,不用挨个通知、挨个改文件。
什么场景用hosts,什么场景用DNS
我自己的习惯是:
- 临时测试 的时候,改
/etc/hosts最快。改完立刻生效,不依赖任何网络服务。 - 机器数量少(两三台以内),改hosts也能接受,维护成本不高。
- 机器多了,或者域名不止一个,就老老实实搭个内网DNS,省心。
还有一种折中情况:Nginx做代理转发的时候,只需要Nginx自己能解析域名就行。这时候只改Nginx所在机器的hosts就够了,其他客户端访问Nginx的IP即可,不需要知道后端域名。
回过头看那次Nginx报错
当时Nginx配置里写的是:
proxy_pass http://api.backend.com:8080;
Nginx启动时需要知道这个域名对应的IP。它去找系统查,系统先翻/etc/hosts,里面没写,再去问/etc/resolv.conf里配的DNS,公网DNS又不认识这个内网域名。于是报错。
后来在/etc/hosts里加了一行:
127.0.0.1 api.backend.com
因为Nginx和后端在同一台机器上,所以指向本机就能通。如果后端在另一台机器,就写那台机器的内网IP。
这就是整个事情的来龙去脉。
一点小建议
如果你也是从内网IP直连一路走过来,遇到域名配置觉得别扭,不用着急。这块不难,只是多了一层"翻译"而已。
搞清楚几个文件的作用,知道它们各自的优先级,剩下的事情就顺理成章了。
/etc/hosts:本机手写对照表,优先级最高/etc/resolv.conf:告诉系统去问哪个DNS服务器- DNS服务器:把域名翻译成IP的查号台
至于什么时候用hosts,什么时候搭DNS,看规模。三五台机器以内,hosts够用。再多,就搭个dnsmasq,一劳永逸。