加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang容器内DNS解析问题排查

发布时间:2020-12-16 18:03:41 所属栏目:大数据 来源:网络整理
导读:先写一个一个测试案例 package main import ( "fmt" "net" "os" ) func main() { if len (os.Args) != 2 { fmt.Fprintf(os.Stderr, "Usage: %s hostnamen" ,os.Args [0 ]) fmt.Println( "Usage: " ,os.Args [0 ], "hostname" ) os.Exit (1 ) } name := os.A

先写一个一个测试案例

package main
import (
    "fmt"
    "net"
    "os"
)
func main() {
    if len(os.Args) != 2 {
        fmt.Fprintf(os.Stderr,"Usage: %s hostnamen",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库,也能解决

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读