Налагодження розвʼязання імен 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/jessie-dnsutils:1.3
    command:
      - sleep
      - "infinity"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always

Використайте цей маніфест, щоб створити 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
...

Якщо ви бачите, що жоден 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
...

Якщо ви створили 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.confsystemd-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 або вище.

Що далі

Змінено June 20, 2024 at 12:44 PM PST: Sync changest from andygol/k8s-website (36d05bc8a1)