懒人阅读,直接结论。 golang应用程序跑在alphine上,默认域名解析顺序是 dns > host, 所以可能造成现象就是/etc/hosts配置不生效。 设置环境变量GODEBUG=netdns=cgo 或者配置文件 /etc/nsswitch.conf (内容为hosts: files dns)即可解决。
在golang项目中,在使用alpine作为项目的基础镜像之后,deployment中的hostaliases会有不同的表现:
- nslookup <域名一>, 返回为unknown host,net.ResolveIPAddr方法解析正常
- nslookup <域名二>,返回为0.0.0.1,net.ResolveIPAddr方法解析失败
- 上面两种情况下,在pod里面,使用命令行ping <域名一>; 或者ping <域名二>,都可以正常解析(初步是net.ResolveIPAddr这个方法的问题)
通过跟net.ResolveIPAddr的代码,发现golang进行域名解析的时候,是有顺序的。(世界上没有通过跟代码解决不了的问题)
从项目的现象来看,golang应该是使用hostLookupDNSFiles顺序进行解析的,进一步跟代码发现:
|
|
从代码上可以看出,若不存在/etc/nsswitch.conf文件,同时又是linux系统时,域名解析顺序是hostLookupDNSFiles,就是优先使用DNS服务器的结果,然后再使用/etc/hosts的配置。
在场景一中,DNS服务器返回unknown host,所以使用/etc/hosts中的配置。在场景二中,DNS服务器返回0.0.0.1,就是可以解析,所以就忽略/etc/hosts配置,使用0.0.0.1作为对端IP进行请求。
其实golang提供了两种解析方式,即pure go方式和cgo方式。pure go方式已经讲述,这里不再赘述。 而cgo实际上直接调用libc的gethostbyname和getaddrinfo实现域名解析的。而alphine的libc版本是musl libc,这个库的gethostbyname和getaddrinfo函数的实现中,是先查/etc/hosts,再查dns。
本文发表于 0001-01-01,最后修改于 0001-01-01。
本站永久域名「 jiavvc.top 」,也可搜索「 后浪笔记一零二四 」找到我。