Налагодження розвʼязання імен DNS
Ця сторінка надає вказівки щодо діагностування проблем DNS.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Ваш кластер повинен бути налаштований на використання надбудови CoreDNS або її попередника, kube-dns.
Версія вашого Kubernetes сервера має бути не старішою ніж v1.6.
Для перевірки версії введіть kubectl version
.
Створіть простий Pod для використання як тестове середовище
apiVersion: v1
kind: Pod
metadata:
name: dnsutils
namespace: default
spec:
containers:
- name: dnsutils
image: registry.k8s.io/e2e-test-images/agnhost:2.39
imagePullPolicy: IfNotPresent
restartPolicy: Always
Примітка:
У цьому прикладі створюється Pod у просторі іменdefault
. Розпізнавання DNS-імені для сервісів залежить від простору імен Podʼа. Для отримання додаткової інформації перегляньте DNS для Service and Pod.Використайте цей маніфест, щоб створити Pod:
kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
pod/dnsutils created
…і перевірте його статус:
kubectl get pods dnsutils
NAME READY STATUS RESTARTS AGE
dnsutils 1/1 Running 0 <some-time>
Після того, як цей Pod працює, ви можете виконати nslookup
в цьому середовищі. Якщо ви бачите щось схоже на наступне, DNS працює правильно.
kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10
Name: kubernetes.default
Address 1: 10.0.0.1
Якщо команда nslookup
не вдається, перевірте наступне:
Спочатку перевірте локальну конфігурацію DNS
Подивіться всередину файлу resolv.conf. (Див. Налаштування служби DNS та Відомі проблеми нижче для отримання додаткової інформації)
kubectl exec -ti dnsutils -- cat /etc/resolv.conf
Перевірте, що шлях пошуку та імʼя сервера налаштовані так, як показано нижче (зверніть увагу, що шлях пошуку може відрізнятися для різних постачальників хмарних послуг):
search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal
nameserver 10.0.0.10
options ndots:5
Помилки, такі як наведені нижче, вказують на проблему з CoreDNS (або kube-dns) або з повʼязаними службами:
kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10
nslookup: can't resolve 'kubernetes.default'
або
kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
nslookup: can't resolve 'kubernetes.default'
Перевірте, чи працює Pod DNS
Використайте команду kubectl get pods
, щоб перевірити, що Pod DNS працює.
kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
...
coredns-7b96bf9f76-5hsxb 1/1 Running 0 1h
coredns-7b96bf9f76-mvmmt 1/1 Running 0 1h
...
Примітка:
Значення для міткиk8s-app
— kube-dns
для розгортання як CoreDNS, так і kube-dns.Якщо ви бачите, що жоден Pod CoreDNS не працює або що Pod несправний/завершено, надбудова DNS може не бути типово розгорнута у вашому поточному середовищі та вам доведеться розгорнути його вручну.
Перевірка помилок у Podʼі DNS
Використайте команду kubectl logs
, щоб переглянути логи контейнерів DNS.
Для CoreDNS:
kubectl logs --namespace=kube-system -l k8s-app=kube-dns
Ось приклад здорових журналів CoreDNS:
.:53
2018/08/15 14:37:17 [INFO] CoreDNS-1.2.2
2018/08/15 14:37:17 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.2
linux/amd64, go1.10.3, 2e322f6
2018/08/15 14:37:17 [INFO] plugin/reload: Running configuration MD5 = 24e6c59e83ce706f07bcc82c31b1ea1c
Перегляньте, чи є будь-які підозрілі або несподівані повідомлення у логах.
Чи працює служба DNS?
Перевірте, чи працює служба DNS за допомогою команди kubectl get service
.
kubectl get svc --namespace=kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 1h
...
Примітка:
Назва служби —kube-dns
як для розгортання CoreDNS, так і для kube-dns.Якщо ви створили Service або у випадку, якщо вона повинна типово створюватися, але вона не зʼявляється, див. налагодження Service для отримання додаткової інформації.
Чи відкриті точки доступу DNS?
Ви можете перевірити, чи викриті точки доступу DNS, використовуючи команду kubectl get endpoints
.
kubectl get endpoints kube-dns --namespace=kube-system
NAME ENDPOINTS AGE
kube-dns 10.180.3.17:53,10.180.3.17:53 1h
Якщо ви не бачите точки доступу, дивіться розділ про точки доступу у документації налагодження Service.
Для додаткових прикладів DNS Kubernetes дивіться приклади dns в кластері у репозиторії Kubernetes GitHub.
Чи надходять/обробляються DNS-запити?
Ви можете перевірити, чи надходять запити до CoreDNS, додавши втулок log
до конфігурації CoreDNS (тобто файлу Corefile). Файл CoreDNS Corefile зберігається у ConfigMap з назвою coredns
. Щоб редагувати його, використовуйте команду:
kubectl -n kube-system edit configmap coredns
Потім додайте log
у розділ Corefile, як показано у прикладі нижче:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
log
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
Після збереження змін може знадобитися до хвилини або двох, щоб Kubernetes поширив ці зміни на Podʼи CoreDNS.
Далі зробіть кілька запитів і перегляньте логи, як показано у попередніх розділах цього документа. Якщо Podʼи CoreDNS отримують запити, ви повинні побачити їх в логах.
Ось приклад запиту у логах:
.:53
2018/08/15 14:37:15 [INFO] CoreDNS-1.2.0
2018/08/15 14:37:15 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.0
linux/amd64, go1.10.3, 2e322f6
2018/09/07 15:29:04 [INFO] plugin/reload: Running configuration MD5 = 162475cdf272d8aa601e6fe67a6ad42f
2018/09/07 15:29:04 [INFO] Reloading complete
172.17.0.18:41675 - [07/Sep/2018:15:29
:11 +0000] 59925 "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR qr,aa,rd,ra 106 0.000066649s
Чи має CoreDNS достатні дозволи?
CoreDNS повинен мати можливість переглядати повʼязані Service та endpoint ресурси для правильного розпізнавання імен служб.
Приклад повідомлення про помилку:
2022-03-18T07:12:15.699431183Z [INFO] 10.96.144.227:52299 - 3686 "A IN serverproxy.contoso.net.cluster.local. udp 52 false 512" SERVFAIL qr,aa,rd 145 0.000091221s
Спочатку отримайте поточну ClusterRole system:coredns
:
kubectl describe clusterrole system:coredns -n kube-system
Очікуваний вивід:
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
endpoints [] [] [list watch]
namespaces [] [] [list watch]
pods [] [] [list watch]
services [] [] [list watch]
endpointslices.discovery.k8s.io [] [] [list watch]
Якщо відсутні будь-які дозволи, відредагуйте ClusterRole, щоб додати їх:
kubectl edit clusterrole system:coredns -n kube-system
Приклад вставки дозволів для EndpointSlices:
...
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
...
Чи ви у правильному просторі імен для служби?
DNS-запити, які не вказують простір імен, обмежені простором імен Podʼа.
Якщо простір імен Podʼа та Service відрізняються, DNS-запит повинен включати простір імен Service.
Цей запит обмежений простором імен Podʼа:
kubectl exec -i -t dnsutils -- nslookup <service-name>
Цей запит вказує простір імен:
kubectl exec -i -t dnsutils -- nslookup <service-name>.<namespace>
Щоб дізнатися більше про розпізнавання імен, дивіться DNS для Service та Pod.
Відомі проблеми
Деякі дистрибутиви Linux (наприклад, Ubuntu) стандартно використовують локальний резолвер DNS (systemd-resolved). Systemd-resolved переміщує та замінює /etc/resolv.conf
на файл-заглушку, що може спричинити фатальний цикл переспрямовування при розпізнаванні імен на вихідних серверах. Це можна виправити вручну, використовуючи прапорець --resolv-conf
kubelet, щоб вказати правильний resolv.conf
(з systemd-resolved
це /run/systemd/resolve/resolv.conf
). kubeadm автоматично визначає systemd-resolved
та налаштовує відповідні прапорці kubelet.
Установки Kubernetes не налаштовують файли resolv.conf
вузлів для використання кластерного DNS стандартно, оскільки цей процес властивий для певного дистрибутиву. Це, можливо, має бути реалізовано надалі.
У Linux бібліотека libc (відома як glibc) має обмеження для записів nameserver
DNS на 3 стандартно, і Kubernetes потрібно використовувати 1 запис nameserver
. Це означає, що якщо локальна установка вже використовує 3 nameserver
, деякі з цих записів будуть втрачені. Щоб обійти це обмеження, вузол може запускати dnsmasq
, який надасть більше записів nameserver
. Ви також можете використовувати прапорець --resolv-conf
kubelet.
Якщо ви використовуєте Alpine версії 3.17 або раніше як базовий образ, DNS може працювати неправильно через проблему з дизайном Alpine. До версії musl 1.24 не включено резервне перемикання на TCP для stub-резолвера DNS, що означає, що будь-який виклик DNS понад 512 байтів завершиться невдачею. Будь ласка, оновіть свої образи до версії Alpine 3.18 або вище.
Що далі
- Дивіться Автомасштабування служби DNS в кластері.
- Читайте DNS для Service та Pod