Kubernetes створює DNS-записи для Service та Podʼів. Ви можете звертатися до Service за допомогою стійких імен DNS замість IP-адрес.
Kubernetes публікує інформацію про Podʼи та Serviceʼи, яка використовується для налаштування DNS. Kubelet конфігурує DNS Podʼів так, щоб запущені контейнери могли знаходити Service за іменем, а не за IP.
Service, визначеним у кластері, призначаються імена DNS. Типово список пошуку DNS клієнта Pod включає власний простір імен Pod та стандартний домен кластера.
DNS-запит може повертати різні результати залежно від простору імен Podʼа, який його створив. DNS-запити, які не вказують простір імен, обмежені простором імен Podʼа. Для доступу до Service в інших просторах імен, вказуйте його в DNS-запиті.
Наприклад, розгляньте Pod в просторі імен test. Service data перебуває в просторі імен prod.
Запит для data не повертає результатів, оскільки використовує простір імен Podʼа test.
Запит для data.prod повертає бажаний результат, оскільки вказує простір імен.
DNS-запити можуть бути розширені за допомогою /etc/resolv.conf Podʼа. Kubelet налаштовує цей файл для кожного Podʼа. Наприклад, запит лише для data може бути розширений до data.test.svc.cluster.local. Значення опції search використовуються для розширення запитів. Щоб дізнатися більше про DNS-запити, див. сторінку довідки resolv.conf.
nameserver 10.32.0.10
search <namespace>.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
Отже, узагальнюючи, Pod у просторі імен test може успішно знаходити як data.prod, так і data.prod.svc.cluster.local.
Для яких обʼєктів створюються DNS-записи?
У наступних розділах детально розглядаються підтримувані типи записів DNS та структура, яка їх підтримує. Будь-яка інша структура, імена чи запити, які випадково працюють, вважаються реалізаційними деталями та можуть змінюватися без попередження. Для отримання більш актуальної специфікації див. Виявлення Serviceʼів на основі DNS у Kubernetes.
"Звичайні" (не headless) Serviceʼи отримують DNS-запис A та/або AAAA, залежно від IP-сімейства або сімейств Serviceʼів, з імʼям у вигляді my-svc.my-namespace.svc.cluster-domain.example. Це розгортається в кластерний IP Serviceʼу.
Headless Services
(без кластерного IP) теж отримують DNS-записи A та/або AAAA, з імʼям у вигляді my-svc.my-namespace.svc.cluster-domain.example. На відміну від звичайних Serviceʼів, це розгортається в набір IP-адрес всіх Podʼів, вибраних Serviceʼом. Очікується, що клієнти будуть використовувати цей набір або використовувати стандартний round-robin вибір із набору.
Записи SRV створюються для іменованих портів, які є частиною звичайних або headless сервісів. Для кожного іменованого порту запис SRV має вигляд _port-name._port-protocol.my-svc.my-namespace.svc.cluster-domain.example. Для звичайного Serviceʼу це розгортається в номер порту та доменне імʼя: my-svc.my-namespace.svc.cluster-domain.example. Для headless Serviceʼу це розгортається в кілька відповідей, по одній для кожного Podʼа, які підтримує Service, і містить номер порту та доменне імʼя Podʼа у вигляді hostname.my-svc.my-namespace.svc.cluster-domain.example.
_port-name._port-protocol.my-svc.my-namespace.svc.cluster-domain.example.my-svc.my-namespace.svc.cluster-domain.example.Версії Kube-DNS, до впровадження специфікації DNS, мали наступне DNS-подання:
<pod-IPv4-address>.<namespace>.pod.<cluster-domain>
Наприклад, якщо Pod в просторі імен default має IP-адресу 172.17.0.3, а доменне імʼя вашого кластера — cluster.local, то у Podʼа буде DNS-імʼя:
172-17-0-3.default.pod.cluster.local
Деякі кластерні механізми DNS, такі як CoreDNS, також надають записи A для:
<pod-ipv4-address>.<service-name>.<my-namespace>.svc.<cluster-domain.example>
Наприклад, якщо Pod у просторі імен cafe має IP-адресу 172.17.0.3, є точкою доступу до Service на імʼя barista, а доменне імʼя вашого кластера — cluster.local, то Pod матиме такий запис DNS A, в межах Service.
172-17-0-3.barista.cafe.svc.cluster.local
Наразі, при створенні Podʼа, його імʼя (як його видно зсередини Podʼа) визначається як значення metadata.name Podʼа.
У специфікації Podʼа є необовʼязкове поле hostname, яке можна використовувати для вказівки відмінного від імʼя Podʼа імені хосту. Коли вказано, воно має пріоритет над іменем Podʼа та стає імʼям хосту Podʼа (знову ж таки, в спостереженнях зсередини Podʼа). Наприклад, якщо у Podʼа вказано spec.hostname зі значенням "my-host", то у Podʼа буде імʼя хосту "my-host".
Специфікація Podʼа також має необовʼязкове поле subdomain, яке може використовуватися для вказівки того, що Pod є частиною підгрупи простору імен. Наприклад, Pod з spec.hostname встановленим на "foo", та spec.subdomain встановленим на "bar", у просторі імен "my-namespace", матиме імʼя хосту "foo" та повністю визначене доменне імʼя (FQDN) "foo.bar.my-namespace.svc.cluster.local" (знову ж таки, в спостереженнях зсередини Podʼа).
Якщо існує headless Service в тому ж просторі імен, що і Pod, із тим самим імʼям, що і піддомен, DNS-сервер кластера також поверне записи A та/або AAAA для повної доменної назви Podʼа.
Приклад:
apiVersion: v1
kind: Service
metadata:
name: busybox-subdomain
spec:
selector:
name: busybox
clusterIP: None
ports:
- name: foo # імʼя не є обовʼязковим для Serviceʼів з одним портом
port: 1234
---
apiVersion: v1
kind: Pod
metadata:
name: busybox1
labels:
name: busybox
spec:
hostname: busybox-1
subdomain: busybox-subdomain
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
name: busybox
---
apiVersion: v1
kind: Pod
metadata:
name: busybox2
labels:
name: busybox
spec:
hostname: busybox-2
subdomain: busybox-subdomain
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
name: busybox
У вище наведеному Прикладі, із Service "busybox-subdomain" та Podʼами, які встановлюють spec.subdomain на "busybox-subdomain", перший Pod побачить своє власне FQDN як "busybox-1.busybox-subdomain.my-namespace.svc.cluster-domain.example". DNS повертає записи A та/або AAAA під цим іменем, що вказують на IP-адресу Podʼа. Обидва Podʼа "busybox1" та "busybox2" матимуть свої власні записи адрес.
EndpointSlice може визначати DNS-hostname для будь-якої адреси endpoint, разом з його IP.
hostname. Pod без hostname, але з subdomain, створить запис A або AAAA лише для headless Service (busybox-subdomain.my-namespace.svc.cluster-domain.example), що вказує на IP-адреси Podʼів. Крім того, Pod повинен бути готовий, щоб мати запис, якщо не встановлено publishNotReadyAddresses=True для Service.Kubernetes v1.22 [stable]
Коли Pod налаштовано так, що він має повне доменне імʼя (FQDN), його імʼя хосту — це коротке імʼя хосту. Наприклад, якщо у вас є Pod із повним доменним імʼям busybox-1.busybox-subdomain.my-namespace.svc.cluster-domain.example, то стандартно команда hostname в цьому Podʼі повертає busybox-1, а команда hostname --fqdn повертає FQDN.
Коли ви встановлюєте setHostnameAsFQDN: true у специфікації Podʼа, kubelet записує FQDN Podʼа в імʼя хосту для простору імен цього Podʼа. У цьому випадку як hostname, так і hostname --fqdn повертають FQDN Podʼа.
У Linux поле hostname ядра (поле nodename структури struct utsname) обмежено 64 символами.
Якщо Pod активує цю функцію і його FQDN довше за 64 символи, запуск буде неуспішним. Pod залишиться у статусі Pending (ContainerCreating, як це бачить kubectl), генеруючи події помилок, такі як "Не вдалося побудувати FQDN з імені хосту Podʼа та домену кластера, FQDN long-FQDN занадто довгий (максимально 64 символи, запитано 70)". Один зі способів поліпшення досвіду користувача у цьому сценарії — створення контролера admission webhook для контролю розміру FQDN при створенні користувачами обʼєктів верхнього рівня, наприклад, Deployment.
Політику DNS можна встановлювати для кожного Podʼа окремо. Наразі Kubernetes підтримує наступні політики DNS, вказані у полі dnsPolicy в специфікації Podʼа:
Default": Pod успадковує конфігурацію розпізнавання імені від вузла, на якому працюють Podʼи. Деталі можна переглянути у відповідному описі.ClusterFirst": Будь-який DNS-запит, який не відповідає налаштованому суфіксу домену кластера, такому як "www.kubernetes.io", пересилається на вихідний DNS-сервер DNS-сервером. Адміністратори кластера можуть мати додаткові налаштовані піддомени та вихідні DNS-сервери. Деталі щодо обробки DNS-запитів у цих випадках можна знайти відповідному дописі.ClusterFirstWithHostNet": Для Podʼів, які працюють із hostNetwork, ви повинні явно встановити для них політику DNS "ClusterFirstWithHostNet". В іншому випадку Podʼи, що працюють із hostNetwork та "ClusterFirst", будуть використовувати поведінку політики "Default".None": Це дозволяє Podʼу ігнорувати налаштування DNS з оточення Kubernetes. Всі налаштування DNS повинні надаватися за допомогою поля dnsConfig у специфікації Podʼа. Деталі дивіться у підрозділі DNS-конфігурація Podʼа нижче.dnsPolicy не вказано явно, то використовується "ClusterFirst".Наведений нижче приклад показує Pod із встановленою політикою DNS "ClusterFirstWithHostNet", оскільки у нього встановлено hostNetwork в true.
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Always
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
Kubernetes v1.14 [stable]
Конфігурація DNS для Podʼа дозволяє користувачам мати більше контролю над налаштуваннями DNS для конкретного Podʼа.
Поле dnsConfig є необовʼязковим і може використовуватися з будь-якими налаштуваннями dnsPolicy. Однак, коли поле dnsPolicy Podʼа встановлено в "None", поле dnsConfig повинно бути вказано.
Нижче наведені значення, які користувач може вказати у полі dnsConfig:
nameservers: список IP-адрес, які будуть використовуватися як DNS-сервери для Podʼа. Можна вказати не більше 3 IP-адрес, але коли політика DNS Podʼа встановлена на "None", список повинен містити принаймні одну IP-адресу, інакше ця властивість є необовʼязковою. Зазначені сервери будуть обʼєднані з базовими серверами, згенерованими з вказаною політикою DNS, з вилученням дубльованих адрес.searches: список доменів пошуку DNS для пошуку імен в хостах у Podʼі. Ця властивість є необовʼязковою. При вказанні, вказаний список буде обʼєднаний з базовими доменами пошуку, згенерованими з вибраної політики DNS. Дубльовані доменні імена вилучаються. Kubernetes дозволяє до 32 доменів пошуку.options: необовʼязковий список обʼєктів, де кожний обʼєкт може мати властивість name (обовʼязкова) і властивість value (необовʼязкова). Зміст цієї властивості буде обʼєднаний з параметрами, згенерованими з вказаної політики DNS. Дубльовані елементи вилучаються.Тут наведено приклад Podʼа з власними налаштуваннями DNS:
apiVersion: v1
kind: Pod
metadata:
namespace: default
name: dns-example
spec:
containers:
- name: test
image: nginx
dnsPolicy: "None"
dnsConfig:
nameservers:
- 192.0.2.1 # тут адреса для прикладу
searches:
- ns1.svc.cluster-domain.example
- my.dns.search.suffix
options:
- name: ndots
value: "2"
- name: edns0
Коли створюється Pod, контейнер test отримує наступний зміст у своєму файлі /etc/resolv.conf:
nameserver 192.0.2.1
search ns1.svc.cluster-domain.example my.dns.search.suffix
options ndots:2 edns0
Для налаштування IPv6 шляху пошуку та сервера імен слід встановити:
kubectl exec -it dns-example -- cat /etc/resolv.conf
Вивід буде подібний до наступного:
nameserver 2001:db8:30::a
search default.svc.cluster-domain.example svc.cluster-domain.example cluster-domain.example
options ndots:5
Kubernetes 1.28 [stable]
Kubernetes сам по собі не обмежує конфігурацію DNS до тих пір, поки довжина списку доменів пошуку не перевищить 32 або загальна довжина всіх доменів пошуку не перевищить 2048. Це обмеження стосується файлу конфігурації резолвера вузла, конфігурації DNS Podʼа та обʼєднаної конфігурації DNS відповідно.
Деякі середовища виконання контейнерів раніших версій можуть мати власні обмеження щодо кількості доменів пошуку DNS. Залежно від середовища виконання контейнерів, Podʼи з великою кількістю доменів пошуку DNS можуть залишатися в стані очікування.
Відомо, що containerd версії 1.5.5 або раніше та CRI-O версії 1.21 або раніше мають цю проблему.
. розглядаються як повністю кваліфіковані та пропускають розгортання FQDN.Resolve-DNSName для отримання імені.mydns.svc.cluster.local). Windows може розгортати FQDN, служби або мережеве імʼя, яке може бути розгорнуто за допомогою цього єдиного суфікса. Наприклад, Pod, створений у просторі імен default, матиме суфікс DNS default.svc.cluster.local. Всередині Windows імʼя Podʼа можна розгортати як kubernetes.default.svc.cluster.local, так і kubernetes, але не в частково кваліфіковані імена (kubernetes.default або kubernetes.default.svc).Для керівництва щодо адміністрування конфігурацій DNS дивіться Налаштування служби DNS.