一个用go语言开发程序,运行时会使用”net/http”中的方法”http.Client.Do()”发起http请求:
http://www.XXX.com
url中的域名对应的ip地址配置在了/etc/hosts中:
1.1.1.1 www.XXX.com
预期go程序会使用/etc/hosts中配置的IP,但实际使用的却是从dns server中查询到的ip。
比较奇怪的是,同样的go程序,同样的容器,在另一个环境中运行的时候,没有这个问题, 在宿主机中运行时也没有问题。
net.Dial seems to ignore /etc/hosts if I don’t provide GODEBUG=netdns=(c)go中提到了nsswitch.conf文件。
查看出现的问题的容器(基于alpine 3.5),发现容器中没有这个文件。将宿主机(centos7.2)的/etc/nsswitch.conf
复制到容器中,问题解决。
复制到容器中的nsswitch.conf中明确指定了地址解析顺序:
$ cat /etc/nsswitch.conf|grep host
hosts: files dns myhostname
另外,pkg/net: Name Resolution提到,可以通过环境变量指定go程序使用的resover:
export GODEBUG=netdns=go # force pure Go resolver
export GODEBUG=netdns=cgo # force cgo resolver
经验证可行,不过最好还是用nsswitch.conf明确规定地址解析顺序。
另一个环境中不存在这个问题是因为它的dns server中查询不到目标域名,所以使用了/etc/hosts中的地址。
在使用容器的时候,要检查下容器中的/etc/nsswitch.conf文件是否存在,是否指定了解析顺序。