golang解析域名的步骤全纪录
最近遇到了一个问题。
我们的kube-apiserver配置了OIDC认证,OIDCissuer是添加了dnsserver记录的,但由于某些原因,我需要覆盖掉dnsserver的解析,改用hostAlias的IP地址,但是实测发现总是走了DNS解析,虽然/etc/hosts文件已经添加了自定义的hosts记录。而那些没有在dnsserver注册的域名,还是可以通过/etc/hosts解析的。
原因是,kube-apiserver的基础镜像是busybox,和centos不同,这货没有/etc/nsswitch.conf文件,所以总是优先使用DNS解析,忽略了/etc/hosts文件。
解决办法很简单,给镜像添加/etc/nsswitch.conf文件指定解析顺序即可,内容如下。
hosts:filesdns
即,files优先dns。
顺带完整的理一下linux系统里golang的域名解析。
golang有两种域名解析方法:内置Go解析器;基于cgo的系统解析器。通过环境变量GODEBUG来配置。
exportGODEBUG=netdns=go#forcepureGoresolver exportGODEBUG=netdns=cgo#forcecgoresolver
默认采用的是内置Go解析器,因为当DNS解析阻塞时,内置Go解析器只是阻塞了一个goroutine,而cgo的解析器则是阻塞了一个操作系统级别的线程。
funcinit(){netGo=true}
读取resolv.conf失败则强制使用cgo。
confVal.resolv=dnsReadConfig("/etc/resolv.conf") ifconfVal.resolv.err!=nil&&!os.IsNotExist(confVal.resolv.err)&& !os.IsPermission(confVal.resolv.err){ //Ifwecan'treadtheresolv.conffile,assumeit //hadsomethingimportantinitanddefertocgo. //libc'sresolvermightthenfailtoo,butatleast //itwasn'tourfault. confVal.forceCgoLookupHost=true }
当使用内置Go解析器时,根据解析优先级的不同,还会细分为下面四种。
const( //hostLookupCgomeansdefertocgo. hostLookupCgohostLookupOrder=iota hostLookupFilesDNS//filesfirst hostLookupDNSFiles//dnsfirst hostLookupFiles//onlyfiles hostLookupDNS//onlyDNS )
当/etc/nsswitch.conf文件不存在或者文件存在但是没有指定hosts字段时,linux下使用的是hostLookupDNSFiles,也就是说,dns解析优先hosts解析,所以就会出现开头出现的问题。
nss:=c.nss srcs:=nss.sources["hosts"] //If/etc/nsswitch.confdoesn'texistordoesn'tspecifyany //sourcesfor"hosts",assumeGo'sDNSwillworkfine. ifos.IsNotExist(nss.err)||(nss.err==nil&&len(srcs)==0){ ifc.goos=="linux"{ //glibcsaysthedefaultis"dns[!UNAVAIL=return]files" //http://www.gnu.org/software/libc/manual/html_node/Notes-on-NSS-Configuration-File.html. returnhostLookupDNSFiles } returnhostLookupFilesDNS }
通过nsswitch.conf可以指定解析顺序。代码挺简单的。
varmdnsSource,filesSource,dnsSourcebool varfirststring for_,src:=rangesrcs{ ifsrc.source=="files"||src.source=="dns"{ if!src.standardCriteria(){ returnfallbackOrder//non-standard;letlibcdealwithit. } ifsrc.source=="files"{ filesSource=true }elseifsrc.source=="dns"{ dnsSource=true } iffirst==""{ first=src.source } continue } //Somesourcewedon'tknowhowtodealwith. returnfallbackOrder } //CaseswhereGocanhandleitwithoutcgoandCthread //overhead. switch{ casefilesSource&&dnsSource: iffirst=="files"{ returnhostLookupFilesDNS }else{ returnhostLookupDNSFiles } casefilesSource: returnhostLookupFiles casednsSource: returnhostLookupDNS }
所以指定hosts:filesdns,解析策略就是hostLookupFilesDNS,即优先使用/etc/hosts。
详细的解析顺序请参见hostLookupOrder。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。