- 博客/
Coredns 出现间断性无法正常解析域名问题
Table of Contents
问题描述:#
Kubernetes 节点中,有一台节点
使用 coredns 进行解析某个域名
时,出现间断性无法正常解析问题,而解析另外一个域名时不会出现解析问题。
再次重复一下问题重点:
且在集群中的某台节点中出现,且使用某个域名时出现
环境说明:#
- 操作系统: CentOS Linux release 7.9.2009
- Kubernetes 集群: v1.17.4 (集群使用 rancher
自定义添加集群
一键部署) - Dashboard: Rancher-v2.3.5
- Linux Kernel: 5.10.3-1.el7.elrepo.x86_64
- Coredns : Coredns:1.6.5 + Node-local-dns
工具说明#
测试时使用的容器: praqma/network-multitool:latest
测试时使用的dns 测试工具 : coredns-tools.go
程序出自
Blog
package main import ( "context" "flag" "fmt" "net" "sync/atomic" "time" ) var host string var connections int var duration int64 var limit int64 var timeoutCount int64 func main() { // os.Args = append(os.Args, "-host", "www.baidu.com", "-c", "200", "-d", "30", "-l", "5000") flag.StringVar(&host, "host", "", "Resolve host") flag.IntVar(&connections, "c", 100, "Connections") flag.Int64Var(&duration, "d", 0, "Duration(s)") flag.Int64Var(&limit, "l", 0, "Limit(ms)") flag.Parse() var count int64 = 0 var errCount int64 = 0 pool := make(chan interface{}, connections) exit := make(chan bool) var ( min int64 = 0 max int64 = 0 sum int64 = 0 ) go func() { time.Sleep(time.Second * time.Duration(duration)) exit <- true }() endD: for { select { case pool <- nil: go func() { defer func() { <-pool }() resolver := &net.Resolver{} now := time.Now() _, err := resolver.LookupIPAddr(context.Background(), host) use := time.Since(now).Nanoseconds() / int64(time.Millisecond) if min == 0 || use < min { min = use } if use > max { max = use } sum += use if limit > 0 && use >= limit { timeoutCount++ } atomic.AddInt64(&count, 1) if err != nil { fmt.Println(err.Error()) atomic.AddInt64(&errCount, 1) } }() case <-exit: break endD } } fmt.Printf("request count:%d\nerror count:%d\n", count, errCount) fmt.Printf("request time:min(%dms) max(%dms) avg(%dms) timeout(%dn)\n", min, max, sum/count, timeoutCount) }
工具编译
export CGO_ENABLED=0 export GOOS=linux export GOARCH=amd64 go build coredns-tools.go
使用文件分享工具: nginx
配置文件如下所示:
cat /usr/local/etc/nginx/nginx.conf # 且截取部分配置 server { listen 188; server_name _; charset utf-8; location / { root /Users/zun/Downloads; autoindex on; autoindex_exact_size off; autoindex_localtime on; } } nginx # 启动
问题表现#
./coredns-tools-linux -host sim-gtw.dt.com -c 200 -d 30 -l 5000
我们可以看到, 我们使用dns测试程序进行测试时,测试结果接近有
61%
的解析失败率,而解析其他域名时解析是正常的
排查结果#
排查到结果与 Coredns 使用到的
上层DNS
有关; 如下如截图所示中,使用同一个域名解析出来的地址, 一个是外网地址一个是内网地址,由此推断出解析域名时分别使用了不同dns server进行解析的。
为了验证我们刚才的推断,我们在coredns 的 configmap 中开启 hosts 插件,并将相关域名写入其中。类似于主机中的 hosts文件,hosts文件优先于dns server,当拿到地址解析后客户端将不再继续请求上层dns server。
排查步骤如下:#
步骤一:#
kubectl edit cm coredns -n kube-system # 编辑 coredns configmap 添加 hosts插件配置 (配置如下)
hosts {
192.168.1.105 dt.com
192.168.1.106 sim-gtw.dt.com
fallthrough
}
步骤二:#
修改完成后 等待 coredns pod 重新读取配置或手动删除 coredns 与之相关的
pod
进行重载
kubectl get pod -n kube-system |grep coredns|awk '{print $1}'|xargs -I {} kubectl delete pod {} --force -n kube-system
修改后的结果展示:#
重载配置完成后 我们再测试一下结果#
wget http://192.168.121.110:188/coredns-tools-linux \
&& chmod a+x coredns-tools-linux \
&& ./coredns-tools-linux -host sim-gtw.dt.com -c 200 -d 30 -l 5000
可以看到, 此时我们再进行测试时,域名解析已不再提示报错了。但是最大延迟显示还是显示有5s左右,这个和我们正在使用的kube-proxy策略有关,默认策略使用的是
iptables 模式
,如后期优化可进行更改为性能更高的ipvs模式
及部署 node-local-dns 服务来减少解析延迟,我这里无法更改 kubelet的启动参数中 dns的地址,貌似 node-local-dns 没有太多效果 。
解决问题#
我们通过上面的测试验证了间断性域名解析失效,是由于上层dns造成;解决方法也非常简单,只需要更改 coredns 使其使用正确的上层dns即可。
更改 coredns 配置#
同样我们需要更改一下 coredns 的 configmap 文件
kubectl edit cm coredns -n kube-system
更改后的 配置展示
apiVersion: v1
data:
Corefile: |-
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 600
}
prometheus :9153
forward . 192.168.1.112 192.168.121.112
cache 600
loop
reload
loadbalance
}
....
# 省略部分配置
适当的增减了 cache 时间与 ttl 时间
更改node-local-cahce 配置#
kubectl edit cm node-local-dns -n kube-system # 编辑 node-local-dns 修改参数
更改后的配置展示:
ip6.arpa:53 {
errors
cache 30
reload
reload
loop
bind 169.254.20.10 10.43.0.10
forward . __PILLAR__CLUSTER__DNS__ {
force_tcp
}
prometheus :9253
}
.:53 {
errors
cache 30
reload
loop
bind 169.254.20.10 10.43.0.10
forward . __PILLAR__CLUSTER__DNS__ {
force_tcp
}
prometheus :9253
}
....
# 省略部分配置
更改完成后,继续等待 coredns 相关pod重载配置。 或手动重载。
kubectl get pod -n kube-system |grep coredns|awk '{print $1}'|xargs -I {} kubectl delete pod {} --force -n kube-system
参考文档及博客:#
部署 Nodelocaldns 解决 Coredns 域名解析延迟
总结:#
原生的coredns功能方面还是存在某些不完善及兼容性的问题,不过我们可以使用第三方扩展来进行解决。目前coredns主要出现问题的地方在于: 内核的版本、网络插件兼容、5s超时问题,而五秒超时问题我们可以通过升级内核版本及部署 node-local-dns 应用在每个节点中增加缓存解决。