kube-dns配置注意及問(wèn)題排查
基礎(chǔ)的k8s集群可以通過(guò)flannel的網(wǎng)絡(luò)ip地址工作,但要擴(kuò)展addons的service,都要通過(guò)域名來(lái)連通,因?yàn)楦鱾€(gè)鏡像的配置文件中是不可能把ip寫死在文件中的,但域名是可以不變的。因此,一個(gè)k8s集群中kube-dns的配置是必要的。
下面介紹配置kube-dns,需要注意的地方,驗(yàn)證及問(wèn)題排查過(guò)程。
在/etc/resolv.conf文件中配置短域補(bǔ)齊,比如cluster.local,這里必須要與skydns-rc.yaml.sed文件中的domain參數(shù)一致。
1、看kube-dns的pod內(nèi)3個(gè)容器是否全部running
kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
2、如果全部running,看日志是否有異常
可以通過(guò)命令,也可以通過(guò)kube dashboard。
3、若日志無(wú)明顯異常,驗(yàn)證healthz是否能夠解析完整域和短域
完整域
kubectl exec -n kube-system -ti kube-dns-v20-xxxxx -c healthz -- nslookup kube-dns.kube-system.svc.cluster.local
短域
kubectl exec -n kube-system -ti kube-dns-v20-xxxxx -c healthz -- nslookup kube-dns
4、如果完整域可以解析,短域不可以解析
查看/etc/resolv.conf文件,是否補(bǔ)齊cluster.local
kubectl exec -n kube-system -ti kube-dns-v20-xxxxx -c healthz cat /etc/resolv.conf
一般文件內(nèi)容為:
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 172.17.26.52 #kube-dns service clusterIp
options ndots:5
這個(gè)是從宿主機(jī)的/etc/resolv.conf文件中繼承的。
這些都可以通過(guò)官網(wǎng)doc可以查看到Troubleshooting Tips
5、在node上的修改
修改/etc/kubernetes/kubelet文件:
KUBELET_ARGS="--cluster-dns=172.17.26.52 --cluster-domain=cluster.local --log_dir=/var/log/kubernetes"
修改之后要重啟kubelet
systemctl restart kubelet
修改宿主機(jī)的/etc/resolv.conf:
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 172.17.26.52 #kube-dns service clusterIp
5、遇到的問(wèn)題,這里也比較關(guān)鍵
<1>、手動(dòng)指定的clusterIp不能解析
在實(shí)際操作中,由于kube-dns的特殊性,需要手動(dòng)指定kube-dns service的clusterIp(在各種“教程”中全都在說(shuō)手動(dòng)指定,他們竟然都沒(méi)遇到問(wèn)題),然后創(chuàng)建svc,結(jié)果使用healthz的nslookup驗(yàn)證時(shí)卻不能解析。
幸好suzhen經(jīng)驗(yàn)豐富,嘗試把clusterIp注釋掉,讓k8s自動(dòng)為kube-dns分配一個(gè)ip。然后再手動(dòng)指定這個(gè)ip,重新創(chuàng)建svc?;蛘咧苯幽眠@個(gè)ip用就可以了。
按道理說(shuō)指定的clusterIp在k8s限定的范圍之內(nèi)都是可以的,但是不知道隨機(jī)指定了一個(gè)ip就不行。。。就這么不巧。。。具體原因目前還不清楚。
<2>、命令可解析,healthz自帶的參數(shù)不能解析
這個(gè)問(wèn)題也是非常詭異的,把healthz的cmd參數(shù)單獨(dú)拿出來(lái)用命令解析可以,但是它自己卻不能解析,命令一模一樣,完全沒(méi)道理。。。
命令:
kubectl exec -n kube-system -ti kube-dns-v20-xxxxx -c healthz -- nslookup kubernetes.default.svc.cluster.local 127.0.0.1
日志:
can't resolve "kubernetes.default.svc.cluster.local"
healthz是負(fù)責(zé)dns的健康的,根據(jù)創(chuàng)建rc時(shí)的yaml文件,healthz容器定時(shí)向kubedns容器查詢
kubernetes.default.svc.cluster.local 127.0.0.1及kubernetes.default.svc.cluster.lcoal 127.0.0.1:10053,
即(因?yàn)檫@個(gè)奇怪的問(wèn)題把原args都注釋了,暫時(shí)這樣解決了):
- name: healthz
image: gcr.io/google_containers/exechealthz-amd64:1.2
...
args:
#- --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null
- --cmd=ping 127.0.0.1
#- --url=/healthz-dnsmasq
#- --cmd=nslookup kubernetes.default.svc.cluster.lcoal 127.0.0.1:10053 >/dev/null
#- --url=/healthz-kubedns
#- --port=8080
#- --quiet
如果一段時(shí)間healthz一直解析不過(guò),就會(huì)發(fā)送一個(gè)terminated信號(hào)給kubedns,這時(shí)即使kubedns本身正常(可以通過(guò)kubedns直接執(zhí)行nslookup進(jìn)行解析驗(yàn)證),也會(huì)自毀,此時(shí)該pod就會(huì)變的不正常。
<3>、BTW
官網(wǎng)太簡(jiǎn)單,網(wǎng)上教程太雜,經(jīng)驗(yàn)很重要,謹(jǐn)慎。
附skydns-rc.yaml.sed修改的地方:
spec:
#nodeName: k8s-nod5
containers:
- name: kubedns
image: gcr.io/google_containers/kubedns-amd64:1.8
...
args:
# command = "/kube-dns"
- --domain=cluster.local.
- --dns-port=10053
- --kube-master-url=http://100.101.69.252:8080
...
- name: healthz
image: gcr.io/google_containers/exechealthz-amd64:1.2
...
args:
#- --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null
- --cmd=ping 127.0.0.1
#- --url=/healthz-dnsmasq
#- --cmd=nslookup kubernetes.default.svc.cluster.lcoal 127.0.0.1:10053 >/dev/null
#- --url=/healthz-kubedns
#- --port=8080
#- --quiet