Yandex Cloud
Поиск
Связаться с намиПопробовать бесплатно
  • Истории успеха
  • Документация
  • Блог
  • Все сервисы
  • Статус работы сервисов
  • Marketplace
    • Популярные
    • Инфраструктура и сеть
    • Платформа данных
    • Искусственный интеллект
    • Безопасность
    • Инструменты DevOps
    • Бессерверные вычисления
    • Управление ресурсами
  • Все решения
    • По отраслям
    • По типу задач
    • Экономика платформы
    • Безопасность
    • Техническая поддержка
    • Каталог партнёров
    • Обучение и сертификация
    • Облако для стартапов
    • Облако для крупного бизнеса
    • Центр технологий для общества
    • Облако для интеграторов
    • Поддержка IT-бизнеса
    • Облако для фрилансеров
    • Обучение и сертификация
    • Блог
    • Документация
    • Контент-программа
    • Мероприятия и вебинары
    • Контакты, чаты и сообщества
    • Идеи
    • Калькулятор цен
    • Тарифы
    • Акции и free tier
  • Истории успеха
  • Документация
  • Блог
Проект Яндекса
© 2026 ООО «Яндекс.Облако»
Практические руководства
    • Все руководства
    • Настройка подключения к Managed Service for PostgreSQL из контейнера Serverless Containers
    • Создать ВМ с Container Optimized Image
    • Создать ВМ с Container Optimized Image и дополнительным томом для Docker-контейнера
    • Создать группу ВМ с Container Optimized Image и несколькими Docker-контейнерами
    • Создать группу ВМ с Container Optimized Image
    • Создать ВМ с Container Optimized Image и несколькими Docker-контейнерами
    • Изменить ВМ с Container Optimized Image
    • Настройка вывода информации из Docker-контейнера в серийный порт
    • Запуск Docker-образа на виртуальной машине с помощью Cloud Registry
      • Создание нового Kubernetes-проекта
      • Создание кластера Kubernetes без доступа в интернет
      • Создание кластера Kubernetes с помощью провайдера Yandex Cloud для Kubernetes Cluster API
      • Запуск рабочих нагрузок с GPU
      • Использование групп узлов c GPU без предустановленных драйверов
      • Установка Time-Slicing GPUs
      • Миграция ресурсов в другую зону доступности
      • Шифрование секретов
      • Подключение сервера BareMetal как внешнего узла к кластеру Managed Service for Kubernetes
        • Интеграция с корпоративной зоной DNS
        • Автоматическое масштабирование DNS по размеру кластера
        • Настройка NodeLocal DNS Cache
        • Проверка DNS Challenge для сертификатов Let's Encrypt®

В этой статье:

  • Необходимые платные ресурсы
  • Перед началом работы
  • Создайте инфраструктуру
  • Подготовьте окружение
  • Установите NodeLocal DNS
  • Создайте тестовое окружение
  • Проверьте работу NodeLocal DNS
  • Удалите NodeLocal DNS
  • Удалите созданные ресурсы
  1. Контейнерная инфраструктура
  2. Managed Service for Kubernetes
  3. Работа с DNS
  4. Настройка NodeLocal DNS Cache

Настройка NodeLocal DNS Yandex Managed Service for Kubernetes

Статья создана
Yandex Cloud
Улучшена
mmerihsesh
Обновлена 29 декабря 2025 г.
  • Необходимые платные ресурсы
  • Перед началом работы
    • Создайте инфраструктуру
    • Подготовьте окружение
  • Установите NodeLocal DNS
  • Создайте тестовое окружение
  • Проверьте работу NodeLocal DNS
  • Удалите NodeLocal DNS
  • Удалите созданные ресурсы

Чтобы снизить нагрузку по DNS-запросам в кластере Managed Service for Kubernetes, используйте компонент NodeLocal DNS.

Совет

Если кластер Managed Service for Kubernetes содержит более 50 узлов, используйте автоматическое масштабирование DNS.

Важно

Если в кластере Managed Service for Kubernetes используется контроллер сетевых политик Cilium, то настройка имеет свои особенности. Воспользуйтесь следующей инструкцией.

NodeLocal DNS является системным компонентом кластера Managed Service for Kubernetes, выполняющим роль локального DNS-кеша на каждом узле.

NodeLocal DNS разворачивается в кластере как DaemonSet с подами node-local-dns в пространстве имен kube-system. NodeLocal DNS настраивает iptables так, чтобы запросы подов к сервису kube-dns перенаправлялись в под node-local-dns на этом же узле (локальный кеш):

  • Если в кеше есть подходящая запись и ее срок действия не истек, ответ возвращается без обращения к основному DNS-сервису кластера.
  • Если в кеше нет записи или ее срок действия истек, запрос пересылается на основной DNS-сервис kube-dns.

Примечание

DNS-запросы перенаправляются в локальный кеш прозрачно для подов: для этого не нужно изменять файл /etc/resolv.conf на поде и перезапускать его. Отключение NodeLocal DNS тоже не требует этих действий.

Использование NodeLocal DNS в кластере Managed Service for Kubernetes имеет ряд преимуществ:

  • Уменьшение времени обработки DNS-запросов.
  • Снижение объема внутреннего сетевого трафика, что позволяет избежать ограничений по количеству соединений.
  • Снижение риска сбоев механизма connection tracking (conntrack) за счет уменьшения числа UDP-запросов к DNS-сервису.
  • Повышение устойчивости и масштабируемости кластерной DNS-подсистемы.

В этом руководстве вы установите компонент NodeLocal DNS в кластере Managed Service for Kubernetes и проверите его работу с помощью пакета сетевых утилит dnsutils. Для этого выполните следующие шаги:

  1. Установите NodeLocal DNS.
  2. Создайте тестовое окружение.
  3. Проверьте работу NodeLocal DNS.

Если созданные ресурсы вам больше не нужны, удалите их.

Необходимые платные ресурсыНеобходимые платные ресурсы

  • Мастер Managed Service for Kubernetes (см. тарифы Managed Service for Kubernetes).
  • Узлы кластера Managed Service for Kubernetes: использование вычислительных ресурсов и хранилища (см. тарифы Compute Cloud).
  • Публичные IP-адреса для узлов кластера Managed Service for Kubernetes (см. тарифы Virtual Private Cloud).

Перед началом работыПеред началом работы

Создайте инфраструктуруСоздайте инфраструктуру

Вручную
Terraform
  1. Создайте облачную сеть и подсеть.

  2. Создайте сервисный аккаунт с ролями k8s.clusters.agent и vpc.publicAdmin.

  3. Создайте группы безопасности для кластера Managed Service for Kubernetes и входящих в него групп узлов.

    Важно

    От настройки групп безопасности зависит работоспособность и доступность кластера, а также запущенных в нем сервисов и приложений.

  4. Создайте кластер Managed Service for Kubernetes и группу узлов с публичным доступом в интернет и с группами безопасности, подготовленными ранее.

  1. Если у вас еще нет Terraform, установите его.

  2. Получите данные для аутентификации. Вы можете добавить их в переменные окружения или указать далее в файле с настройками провайдера.

  3. Настройте и инициализируйте провайдер. Чтобы не создавать конфигурационный файл с настройками провайдера вручную, скачайте его.

  4. Поместите конфигурационный файл в отдельную рабочую директорию и укажите значения параметров. Если данные для аутентификации не были добавлены в переменные окружения, укажите их в конфигурационном файле.

  5. Скачайте в ту же рабочую директорию файл конфигурации кластера Managed Service for Kubernetes k8s-node-local-dns.tf. В файле описаны:

    • Сеть.

    • Подсеть.

    • Кластер Managed Service for Kubernetes.

    • Сервисный аккаунт, необходимый для работы кластера и группы узлов Managed Service for Kubernetes.

    • Группы безопасности, которые содержат необходимые правила для кластера Managed Service for Kubernetes и входящих в него групп узлов.

      Важно

      От настройки групп безопасности зависит работоспособность и доступность кластера, а также запущенных в нем сервисов и приложений.

  6. Укажите в файле конфигурации:

    • Идентификатор каталога.
    • Версии Kubernetes для кластера и групп узлов Managed Service for Kubernetes.
    • CIDR кластера Managed Service for Kubernetes.
    • Имя сервисного аккаунта кластера Managed Service for Kubernetes.
  7. Проверьте корректность файлов конфигурации Terraform с помощью команды:

    terraform validate
    

    Если в файлах конфигурации есть ошибки, Terraform на них укажет.

  8. Создайте необходимую инфраструктуру:

    1. Выполните команду для просмотра планируемых изменений:

      terraform plan
      

      Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.

    2. Если вас устраивают планируемые изменения, внесите их:

      1. Выполните команду:

        terraform apply
        
      2. Подтвердите изменение ресурсов.

      3. Дождитесь завершения операции.

    В указанном каталоге будут созданы все требуемые ресурсы. Проверить появление ресурсов и их настройки можно в консоли управления.

Подготовьте окружениеПодготовьте окружение

  1. Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите и инициализируйте его.

    По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.

  2. Установите kubectl и настройте его на работу с созданным кластером.

Установите NodeLocal DNSУстановите NodeLocal DNS

Yandex Cloud Marketplace
Вручную

Установите NodeLocal DNS с помощью Cloud Marketplace, как описано в инструкции.

  1. Узнайте IP-адрес сервиса kube-dns:

    kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}
    
  2. Создайте файл node-local-dns.yaml. В настройках DaemonSet node-local-dns укажите IP-адрес сервиса kube-dns:

    node-local-dns.yaml
    # Copyright 2018 The Kubernetes Authors.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    # Modified for Yandex Cloud Usage
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: node-local-dns
      namespace: kube-system
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: kube-dns-upstream
      namespace: kube-system
      labels:
        k8s-app: kube-dns
        kubernetes.io/name: "KubeDNSUpstream"
    spec:
      ports:
      - name: dns
        port: 53
        protocol: UDP
        targetPort: 53
      - name: dns-tcp
        port: 53
        protocol: TCP
        targetPort: 53
      selector:
        k8s-app: kube-dns
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: node-local-dns
      namespace: kube-system
    data:
      Corefile: |
        cluster.local:53 {
          errors
          cache {
            success 9984 30
            denial 9984 5
          }
          reload
          loop
          bind 169.254.20.10 <IP-адрес_сервиса_kube-dns>
          forward . __PILLAR__CLUSTER__DNS__ {
            prefer_udp
          }
          prometheus :9253
          health 169.254.20.10:8080
        }
        in-addr.arpa:53 {
          errors
          cache 30
          reload
          loop
          bind 169.254.20.10 <IP-адрес_сервиса_kube-dns>
          forward . __PILLAR__CLUSTER__DNS__ {
            prefer_udp
          }
          prometheus :9253
          }
        ip6.arpa:53 {
          errors
          cache 30
          reload
          loop
          bind 169.254.20.10 <IP-адрес_сервиса_kube-dns>
          forward . __PILLAR__CLUSTER__DNS__ {
            prefer_udp
          }
          prometheus :9253
          }
        .:53 {
          errors
          cache 30
          reload
          loop
          bind 169.254.20.10 <IP-адрес_сервиса_kube-dns>
          forward . __PILLAR__UPSTREAM__SERVERS__ {
            prefer_udp
          }
          prometheus :9253
          }
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: node-local-dns
      namespace: kube-system
      labels:
        k8s-app: node-local-dns
    spec:
      updateStrategy:
        rollingUpdate:
          maxUnavailable: 10%
      selector:
        matchLabels:
          k8s-app: node-local-dns
      template:
        metadata:
          labels:
            k8s-app: node-local-dns
          annotations:
            prometheus.io/port: "9253"
            prometheus.io/scrape: "true"
        spec:
          priorityClassName: system-node-critical
          serviceAccountName: node-local-dns
          hostNetwork: true
          dnsPolicy: Default # Don't use cluster DNS.
          tolerations:
          - key: "CriticalAddonsOnly"
            operator: "Exists"
          - effect: "NoExecute"
            operator: "Exists"
          - effect: "NoSchedule"
            operator: "Exists"
          containers:
          - name: node-cache
            image: registry.k8s.io/dns/k8s-dns-node-cache:1.17.0
            resources:
              requests:
                cpu: 25m
                memory: 5Mi
            args: [ "-localip", "169.254.20.10,<IP-адрес_сервиса_kube-dns>", "-conf", "/etc/Corefile", "-upstreamsvc", "kube-dns-upstream" ]
            securityContext:
              privileged: true
            ports:
            - containerPort: 53
              name: dns
              protocol: UDP
            - containerPort: 53
              name: dns-tcp
              protocol: TCP
            - containerPort: 9253
              name: metrics
              protocol: TCP
            livenessProbe:
              httpGet:
                host: 169.254.20.10
                path: /health
                port: 8080
              initialDelaySeconds: 60
              timeoutSeconds: 5
            volumeMounts:
            - mountPath: /run/xtables.lock
              name: xtables-lock
              readOnly: false
            - name: config-volume
              mountPath: /etc/coredns
            - name: kube-dns-config
              mountPath: /etc/kube-dns
          volumes:
          - name: xtables-lock
            hostPath:
              path: /run/xtables.lock
              type: FileOrCreate
          - name: kube-dns-config
            configMap:
              name: kube-dns
              optional: true
          - name: config-volume
            configMap:
              name: node-local-dns
              items:
                - key: Corefile
                  path: Corefile.base
    ---
    # Headless Service has no ClusterIP and returns Pod IPs via DNS.
    # Used for Prometheus service discovery of node-local-dns metrics.
    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        prometheus.io/port: "9253"
        prometheus.io/scrape: "true"
      labels:
        k8s-app: node-local-dns
      name: node-local-dns
      namespace: kube-system
    spec:
      clusterIP: None
      ports:
        - name: metrics
          port: 9253
          targetPort: 9253
      selector:
        k8s-app: node-local-dns
    

    Важно

    Приложение работает корректно только с пространством имен kube-system.

  3. Создайте ресурсы для NodeLocal DNS:

    kubectl apply -f node-local-dns.yaml
    

    Результат:

    serviceaccount/node-local-dns created
    service/kube-dns-upstream created
    configmap/node-local-dns created
    daemonset.apps/node-local-dns created
    service/node-local-dns created
    
  4. Убедитесь, что DaemonSet успешно развернут и запущен:

    kubectl get ds -l k8s-app=node-local-dns -n kube-system
    

    Результат:

    NAME            DESIRED  CURRENT  READY  UP-TO-DATE  AVAILABLE  NODE SELECTOR  AGE
    node-local-dns  3        3        3      3           3          <none>         24m
    

Создайте тестовое окружениеСоздайте тестовое окружение

Для проверки работы локального DNS в кластере Managed Service for Kubernetes будет запущен под nettool, содержащий в себе пакет сетевых утилит dnsutils.

  1. Запустите под nettool:

    kubectl run nettool --image cr.yandex/yc/demo/network-multitool -- sleep infinity
    
  2. Убедитесь, что под перешел в состояние Running:

    kubectl get pods
    
  3. Выясните, на каком узле кластера Managed Service for Kubernetes развернут под nettool:

    kubectl get pod nettool -o wide
    

    Имя узла указано в столбце NODE, например:

    NAME     READY  STATUS   RESTARTS  AGE  IP         NODE        NOMINATED NODE  READINESS GATES
    nettool  1/1    Running  0         23h  10.1.0.68  <имя_узла>  <none>          <none>
    
  4. Узнайте IP-адрес пода, на котором развернут NodeLocal DNS:

    kubectl get pod -o wide -n kube-system | grep 'node-local.*<имя_узла>'
    

    Результат:

    node-local-dns-gv68c  1/1  Running  0  26m  <IP-адрес_пода>  <имя_узла>  <none>  <none>
    

Проверьте работу NodeLocal DNSПроверьте работу NodeLocal DNS

Для проверки работы локального DNS с пода nettool будут выполнены несколько DNS-запросов. При этом будут изменяться метрики количества DNS-запросов на поде, обслуживающем NodeLocal DNS.

  1. Узнайте значение метрик для DNS-запросов до начала проверки:

    kubectl exec -ti nettool -- curl http://<IP-адрес_пода>:9253/metrics | grep coredns_dns_requests_total
    

    Результат:

    # HELP coredns_dns_requests_total Counter of DNS requests made per zone, protocol and family.
    # TYPE coredns_dns_requests_total counter
    coredns_dns_requests_total{family="1",proto="udp",server="dns://10.96.128.2:53",type="A",zone="."} 18
    coredns_dns_requests_total{family="1",proto="udp",server="dns://10.96.128.2:53",type="A",zone="cluster.local."} 18
    coredns_dns_requests_total{family="1",proto="udp",server="dns://10.96.128.2:53",type="AAAA",zone="."} 18
    coredns_dns_requests_total{family="1",proto="udp",server="dns://10.96.128.2:53",type="AAAA",zone="cluster.local."} 18
    coredns_dns_requests_total{family="1",proto="udp",server="dns://169.254.20.10:53",type="other",zone="."} 1
    coredns_dns_requests_total{family="1",proto="udp",server="dns://169.254.20.10:53",type="other",zone="cluster.local."} 1
    coredns_dns_requests_total{family="1",proto="udp",server="dns://169.254.20.10:53",type="other",zone="in-addr.arpa."} 1
    coredns_dns_requests_total{family="1",proto="udp",server="dns://169.254.20.10:53",type="other",zone="ip6.arpa."} 1
    

    Из результата следует, что NodeLocal DNS принимает DNS-запросы на двух IP-адресах:

    • Адрес, совпадающий с Cluster IP сервиса kube-dns (в данном случае 10.96.128.2:53, значение может отличаться).

      Этот адрес является основным. NodeLocal DNS настраивает iptables так, что запросы к сервису kube-dns перенаправляются на под node-local-dns на этом же узле.

    • Локальный адрес NodeLocal DNS (169.254.20.10:53).

      Этот адрес является резервным. Его можно использовать для прямого обращения к поду node-local-dns.

  2. Выполните DNS-запросы:

    kubectl exec -ti nettool -- nslookup kubernetes && \
    kubectl exec -ti nettool -- nslookup kubernetes.default && \
    kubectl exec -ti nettool -- nslookup ya.ru
    

    Результат (IP-адреса могут отличаться):

    Server:         10.96.128.2
    Address:        10.96.128.2#53
    
    Name:   kubernetes.default.svc.cluster.local
    Address: 10.96.128.1
    
    Server:         10.96.128.2
    Address:        10.96.128.2#53
    
    Name:   kubernetes.default.svc.cluster.local
    Address: 10.96.128.1
    
    Server:         10.96.128.2
    Address:        10.96.128.2#53
    
    Non-authoritative answer:
    Name:   ya.ru
    Address: 5.255.255.242
    Name:   ya.ru
    Address: 77.88.44.242
    Name:   ya.ru
    Address: 77.88.55.242
    Name:   ya.ru
    Address: 2a02:6b8::2:242
    
  3. Повторно получите значения метрик для DNS-запросов:

    kubectl exec -ti nettool -- curl http://<IP-адрес_пода>:9253/metrics | grep coredns_dns_requests_total
    

    Результат:

    # HELP coredns_dns_requests_total Counter of DNS requests made per zone, protocol and family.
    # TYPE coredns_dns_requests_total counter
    coredns_dns_requests_total{family="1",proto="udp",server="dns://10.96.128.2:53",type="A",zone="."} 27
    coredns_dns_requests_total{family="1",proto="udp",server="dns://10.96.128.2:53",type="A",zone="cluster.local."} 30
    coredns_dns_requests_total{family="1",proto="udp",server="dns://10.96.128.2:53",type="AAAA",zone="."} 25
    coredns_dns_requests_total{family="1",proto="udp",server="dns://10.96.128.2:53",type="AAAA",zone="cluster.local."} 26
    coredns_dns_requests_total{family="1",proto="udp",server="dns://169.254.20.10:53",type="other",zone="."} 1
    coredns_dns_requests_total{family="1",proto="udp",server="dns://169.254.20.10:53",type="other",zone="cluster.local."} 1
    coredns_dns_requests_total{family="1",proto="udp",server="dns://169.254.20.10:53",type="other",zone="in-addr.arpa."} 1
    coredns_dns_requests_total{family="1",proto="udp",server="dns://169.254.20.10:53",type="other",zone="ip6.arpa."} 1
    

    Из результата следует, что значения метрик увеличились для адреса сервиса kube-dns и не изменились для локального адреса NodeLocal DNS. Это означает, что поды продолжают отправлять DNS-запросы по адресу сервиса kube-dns, но теперь эти запросы обрабатываются сервисом NodeLocal DNS.

Удалите NodeLocal DNSУдалите NodeLocal DNS

Yandex Cloud Marketplace
Вручную

Удалите приложение NodeLocal DNS, как описано в инструкции.

Выполните команду:

kubectl delete -f node-local-dns.yaml

Результат:

serviceaccount "node-local-dns" deleted
service "kube-dns-upstream" deleted
configmap "node-local-dns" deleted
daemonset.apps "node-local-dns" deleted
service "node-local-dns" deleted

Удалите созданные ресурсыУдалите созданные ресурсы

Удалите ресурсы, которые вы больше не будете использовать, чтобы за них не списывалась плата:

  1. Удалите ресурсы в зависимости от способа их создания:

    Вручную
    Terraform

    Удалите кластер Managed Service for Kubernetes.

    1. В терминале перейдите в директорию с планом инфраструктуры.

      Важно

      Убедитесь, что в директории нет Terraform-манифестов с ресурсами, которые вы хотите сохранить. Terraform удаляет все ресурсы, которые были созданы с помощью манифестов в текущей директории.

    2. Удалите ресурсы:

      1. Выполните команду:

        terraform destroy
        
      2. Подтвердите удаление ресурсов и дождитесь завершения операции.

      Все ресурсы, которые были описаны в Terraform-манифестах, будут удалены.

  2. Если для доступа к кластеру Managed Service for Kubernetes или узлам использовались статические публичные IP-адреса, освободите и удалите их.

Была ли статья полезна?

Предыдущая
Автоматическое масштабирование DNS по размеру кластера
Следующая
Проверка DNS Challenge для сертификатов Let's Encrypt®
Проект Яндекса
© 2026 ООО «Яндекс.Облако»