背景描述
最近把尘封已久的笔记本拿出来作为服务器,准备在上面放一些本地部署的服务。
Server
简单起了两个Docker:
- Gitea作为代码托管平台。因为国内用github时不时抽风,还偷偷拿你的代码训练AI,训练好的AI付费卖你。
- Adguardhome作为私有DNS,主要功能是减少广告和跟踪,另一个是作为本地服务的域名解析,毕竟访问本地服务时用IP地址进行访问非常不方便,一旦Server的IP地址发生了变化,所有直接使用IP地址的都得跟着修改。
我想通过local.adguardhome.com
和local.gitea.com
来访问这两个容器的页面: - 在Adguardhome中配置,将这两个域名都指向我Server的IP。
- Nginx做静态转发。访问网站页面时默认端口是80,当我们有多个服务部署在同一个serve上时,又或者有的服务端口并不是80,可以通过Nginx做转发,Nginx可以自动根据请求内容转发到对应的服务上。
Windows
直接将DNS服务器IP设置为Server的IP地址就可以了。
问题与解决
问题:在一顿折腾修改后,在Windows上面突然发现无法通过域名访问gitea服务。
排查
- 首先确定gitea还在正常工作,看看
docker logs gitea
没看到报错,通过ip:port
方式访问也能正常访问。 - 这时候自然就怀疑DNS域名解析的问题了,在WSL(windows subsystem linux)中,用
nslookup local.gitea.com
看到是能够正确返回Server IP的,DNS域名解析也没问题。 - 怀疑是不是Nginx配置出错了,试了试访问Adguardhome的服务
local.adguardhome.com
,是能够正常访问的。Nginx中关于gitea服务配置和Adguardhome几乎是一样的,应该也不会出错。 - 再看一下Nginx的log
/var/log/nginx/access.log
以及/var/log/nginx/error.log
, 这时候发现问题了,访问local.adguardhome.com
有log,而访问local.gitea.com
没有,似乎就没收到相关请求。 - 用
tcpdump
抓了一下包,访问local.gitea.com
时Server根本就没有包过来。也就是说访问local.gitea.com
时候,根本就没有往server上发请求。 - 返回去再查Adguardhome,看它的log,发现也没有请求对
local.gitea.com
进行域名解析。(这一步其实多余了,因为上一步已经说明Windows访问local.gitea.com
时没有往Server上发包) - 这个时候基本就确定是DNS缓存导致的。为了避免往DNS服务器压力过大,一般会对DNS解析结果进行缓存,查过一次后解析结果有一定的有效期,有效期内访问该域名会直接使用之前查询的结果。在Windows CMD中
ipconfig /displaydns
看到,local.gitea.com
被映射到另一个地址上了,运行ipconfig /flushdns
后就可以正常访问local.gitea.com
。
总结
真是一场酣畅淋漓的找BUG过程,整个链路非常的清晰,从Windows浏览器 => Server的DNS服务(Adguardhome)=> Server的80端口 => Server的Nginx => Server的Gitea Docker,一步步定位问题和缩小问题可能的范围,最后一行命令解决问题。