В чем суть проблемы. В базовой инсталяции кластера запустим тестовый под
kubectl run test-coredns -t -i --rm --image centosadmin/utils -- bash
tcpdump -neli eth0 port 53
В другой консоли:
kubectl exec -it test-coredns -- bash
curl ya.ru
Возвращаемся в консоль с tcpdump:
19:35:13.236710 a6:14:ac:ef:cd:7d > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 91: 10.244.31.1.39006 > 10.96.0.10.53: 53058+ A? ya.ru.default.svc.cluster.local. (49)
19:35:13.236843 a6:14:ac:ef:cd:7d > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 91: 10.244.31.1.39006 > 10.96.0.10.53: 53306+ AAAA? ya.ru.default.svc.cluster.local. (49)
19:35:13.237767 a6:14:ac:ef:cd:7d > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 83: 10.244.31.1.37179 > 10.96.0.10.53: 54238+ A? ya.ru.svc.cluster.local. (41)
19:35:13.237810 a6:14:ac:ef:cd:7d > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 83: 10.244.31.1.37179 > 10.96.0.10.53: 54541+ AAAA?
19:35:13.238249 a6:14:ac:ef:cd:7d > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 79: 10.244.31.1.58835 > 10.96.0.10.53: 11867+ A? ya.ru.cluster.local. (37)
19:35:13.238287 a6:14:ac:ef:cd:7d > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 79: 10.244.31.1.58835 > 10.96.0.10.53: 12098+ AAAA? ya.ru.cluster.local. (37)
19:35:13.238848 a6:14:ac:ef:cd:7d > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 65: 10.244.31.1.38399 > 10.96.0.10.53: 29445+ A? ya.ru. (23)
19:35:13.238880 a6:14:ac:ef:cd:7d > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 65: 10.244.31.1.38399 > 10.96.0.10.53: 29657+ AAAA? ya.ru. (23)
Из лога видим, что было отправлено 8 запросов к coreDNS. Проблема 8 запросов в CoreDNS возникает из-а того, что при разрешении DNS-запросов в k8s они могут дублироваться до 8 раз. Это связано с особенностями параметра
ndots, который определяет, сколько точек должно быть в имени перед добавлением суффиксов поиска. Запросы могут отправляться с различными комбинациями суффиксов (например .svc.cluster.local), что приводит к множественным попыткам резолва. Эту проблема решает плагин autopath в CoreDNS.Редактируем конфиг мапу:
kubectl edit configmap -n kube-system coredns
В открывшемся файле меняем pods insecure на pods verified и дописываем под словом ready:
autopath @kubernetes
В итоге должно получиться что-то вроде:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
autopath @kubernetes
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods verified
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
После применения повторяем тест:
19:39:20.657634 7e:a9:bf:07:8a:1b > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 91: 10.244.152.3.46411 > 10.96.0.10.53: 55892+ A? ya.ru.default.svc.cluster.local. (49)
19:39:20.657762 7e:a9:bf:07:8a:1b > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 91: 10.244.152.3.46411 > 10.96.0.10.53: 56213+ AAAA? ya.ru.default.svc.cluster.local. (49)
Также в решение данной проблемы помогает установка NodeLocal DNS. Он снижает нагрузку на CoreDNS, создавая локальный кеш DNS на каждой ноде. Ну и никто не мешает использовать комбинированное решение.
#kubernetes