简单总结
使用containerd仓库Makefile构建的containerd时添加了netgo的编译参数
导致了contaienrd只会在启动时候读取一次/etc/hosts加载到内存中,后续/etc/hosts的修改对于containerd不会生效
这是go build的行为
解决方案
使用netcgo重新编译containerd
GODEBUG=netdns=cgo或者build tags netcgo
修改完/etc/hosts后重启containerd
相关源码
net/lookup_unix.go中
dns解析
func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
查看order和conf
order, conf := systemConf().hostLookupOrder(r, name)
if order == hostLookupCgo {
cgo dns解析
if cname, err, ok := cgoLookupCNAME(ctx, name); ok {
return cname, err
}
}
go dns解析
return r.goLookupCNAME(ctx, name, order, conf)
}
net/conf.go
dns解析配置
func systemConf() *conf {
初始化confVal
confOnce.Do(initConfVal)
return confVal
}
初始化confVal
func initConfVal() {
dnsMode, debugLevel := goDebugNetDNS()
GODEBUG=netdns=go或者build tags netgo
confVal.netGo = netGoBuildTag || dnsMode == "go"
GODEBUG=netdns=cgo或者build tags netcgo
confVal.netCgo = netCgoBuildTag || dnsMode == "cgo"
...
}
查询order和conf
func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrder, dnsConf *dnsConfig) {
...
查询order和conf
return c.lookupOrder(r, hostname)
}
查看order和conf
func (c *conf) lookupOrder(r *Resolver, hostname string) (ret hostLookupOrder, dnsConf *dnsConfig) {
...
var fallbackOrder hostLookupOrder
var canUseCgo bool
if c.mustUseGoResolver(r) {
fallbackOrder = hostLookupFilesDNS
canUseCgo = false
} else if c.netCgo {
return hostLookupCgo, nil
} else if c.preferCgo {
return hostLookupCgo, nil
} else {
if bytealg.IndexByteString(hostname, '\\') != -1 || bytealg.IndexByteString(hostname, '%') != -1 {
return hostLookupCgo, nil
}
fallbackOrder = hostLookupCgo
canUseCgo = true
}
...
}