golang容器内DNS解析问题排查

golang容器内DNS解析问题排查,第1张

概述先写一个一个测试案例 package mainimport ( "fmt" "net" "os")func main() { if len(os.Args) != 2 { fmt.Fprintf(os.Stderr, "Usage: %s hostname\n", os.Args[0]) fmt.Println("Usage:

先写一个一个测试案例

package mainimport (    "fmt"    "net"    "os")func main() {    if len(os.Args) != 2 {        fmt.Fprintf(os.Stderr,"Usage: %s hostname\n",os.Args[0])        fmt.Println("Usage: ",os.Args[0],"hostname")        os.Exit(1)    }    name := os.Args[1]    addr,err := net.ResolveIPAddr("ip",name)    if err != nil {        fmt.Println("Resolution error",err.Error())        os.Exit(1) }    fmt.Println("Resolved address is ",addr.String())    os.Exit(0)}

如果一个主机有多个网卡,可能对应多个IP地址,或者互联网高可用也会使用一个域名对应多个IP

addrs,err := net.LookupHost(name)

解析出多个主机地址

如果自己通过/etc/hosts注入的域名的,在主机上面执行没有任何问题,但放到容器内运行则会出现无法解析域名的问题,通过golang 1.8.3的源码可以看到,golang解析的dns的过程net/lookup_unix.go

func (r *Resolver) lookupHost(ctx context.Context,host string) (addrs []string,err error) {    order := systemConf().hostLookupOrder(host)    if !r.PreferGo && order == hostLookupCgo {        if addrs,err,ok := cGolookupHost(ctx,host); ok {            return addrs,err        }        // cgo not available (or netgo); fall back to Go's DNS resolver        order = hostLookupfilesDNS    }    return GolookupHostOrder(ctx,host,order)}

通过hostLookupOrder确定解析的顺序

nss := c.nss    srcs := nss.sources["hosts"]    // If /etc/nsswitch.conf doesn't exist or doesn't specify any    // sources for "hosts",assume Go's DNS will work fine.    if os.IsNotExist(nss.err) || (nss.err == nil && len(srcs) == 0) {        if c.goos == "solaris" {            // illumos defaults to "nis [NOTFOUND=return] files"            return fallbackOrder        }        if c.goos == "linux" {            // glibc says the default is "dns [!UNAVAIL=return] files"            // http://www.gnu.org/software/libc/manual/HTML_node/Notes-on-NSS-Configuration-file.HTML.            return hostLookupDNSfiles        }        return hostLookupfilesDNS    }    if nss.err != nil {        // We Failed to parse or open nsswitch.conf,so        // conservatively assume we should use cgo if it's        // available.        return fallbackOrder    }

上面的nss就是/etc/nsswitch.conf这个文件,如果这个文件不存在则会通过hostLookupDNSfiles去解析,就是dns优先的顺序去解析

这里有个地方需要注意,就是容器内运行的话,经常是没有/etc/nsswitch.conf这个文件的
而golang的解析又是需要读取这个文件,得到解析顺序的,所以需要在容器内创建这个文件
并且加入

hosts: files dns

就是先读取files 然后走dns解析,这样就ok了 当然你也可以设置cgo的方式,走传统的c库,也能解决

总结

以上是内存溢出为你收集整理的golang容器内DNS解析问题排查全部内容,希望文章能够帮你解决golang容器内DNS解析问题排查所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1272159.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存