Yandex Cloud
  • Сервисы
  • Решения
  • Почему Yandex Cloud
  • Сообщество
  • Тарифы
  • Документация
  • Связаться с нами
Подключиться
Language / Region
© 2022 ООО «Яндекс.Облако»
Yandex Managed Service for Kubernetes
  • Сопоставление с другими сервисами Yandex Cloud
  • Начало работы
  • Пошаговые инструкции
    • Все инструкции
    • Настройка групп безопасности
    • Подключение к узлу по SSH
    • Создание файла конфигурации
    • Обновление Kubernetes
    • Настройка автомасштабирования
    • Установка приложений
      • Основы работы с Cloud Marketplace
      • Установка Jaeger
      • Установка Metrics Provider
    • Сетевые сценарии
      • Обеспечение доступа к приложению, запущенному в кластере Kubernetes
      • Настройка контроллера сетевых политик Calico
      • Настройка контроллера сетевых политик Cilium
      • Настройка Node Local DNS для контроллера сетевых политик Cilium
    • Работа с постоянными томами
      • Динамическая подготовка тома
      • Статическая подготовка тома
      • Управление классами хранилищ
      • Увеличение размера тома для подов
      • Увеличение размера тома для контроллера StatefulSet
      • Подключение тома в блочном режиме
      • Интеграция с Yandex Object Storage
    • Управление кластером Kubernetes
      • Добавление учетных данных кластера Kubernetes в конфигурационный файл kubectl
      • Информация об имеющихся кластерах
      • Создание кластера Kubernetes
      • Изменение кластера Kubernetes
      • Создание пространства имен в кластере Kubernetes
      • Удаление кластера Kubernetes
    • Управление группой узлов
      • Информация об имеющихся группах узлов
      • Создание группы узлов
      • Изменение группы узлов
      • Управление метками узлов кластера Kubernetes
      • Удаление группы узлов
    • Подключение внешних узлов к кластеру
  • Практические руководства
    • Все руководства
    • Интеграция с Container Registry
    • Запуск рабочих нагрузок с GPU
    • Установка NGINX Ingress-контроллера с Let's Encrypt®
    • Настройка Application Load Balancer Ingress-контроллера
    • Резервное копирование в Object Storage
    • Горизонтальное масштабирование приложения в кластере
    • Работа со снапшотами
    • Интеграция с корпоративной зоной DNS
    • Автоматическое масштабирование DNS по размеру кластера
    • Настройка локального кеширования DNS
    • Настройка Fluent Bit для работы с Yandex Cloud Logging
    • Синхронизация с секретами Yandex Lockbox
    • Использование продуктов Yandex Cloud Marketplace
      • Использование Jaeger для трассировки запросов в Yandex Managed Service for YDB
  • Концепции
    • Взаимосвязь ресурсов сервиса
    • Релизные каналы и обновления
    • Шифрование секретов
    • Использование объектов API Kubernetes
      • Том
      • Сервис
    • Группа узлов
      • Автоматическое масштабирование группы узлов
      • Расселение подов с узла
      • Динамическое резервирование ресурсов для узла
      • Группы узлов с GPU
    • Сеть в Managed Service for Kubernetes
    • Внешние узлы кластера
    • Сетевые настройки и политики кластера
    • Автоматическое масштабирование
    • Квоты и лимиты
    • Рекомендации по использованию Managed Service for Kubernetes
  • Управление доступом
  • Правила тарификации
  • Справочник API
    • Аутентификация в API
    • gRPC (англ.)
      • Overview
      • ClusterService
      • NodeGroupService
      • VersionService
      • OperationService
    • REST (англ.)
      • Overview
      • Cluster
        • Overview
        • create
        • delete
        • get
        • list
        • listNodeGroups
        • listNodes
        • listOperations
        • start
        • stop
        • update
      • NodeGroup
        • Overview
        • create
        • delete
        • get
        • list
        • listNodes
        • listOperations
        • update
      • Version
        • Overview
        • list
  • Вопросы и ответы
    • Общие вопросы
    • Хранилище данных
    • Настройка и обновление
    • Автоматическое масштабирование
    • Ресурсы
    • Логи
    • Все вопросы на одной странице
  1. Практические руководства
  2. Настройка локального кеширования DNS

Настройка NodeLocal DNS Cache

Статья создана
Yandex.Cloud
  • Подготовьте окружение
  • Подготовьте спецификацию для Node Local DNS и запустите DaemonSet
  • Измените конфигурацию NodeLocal DNS Cache
  • Выполните DNS-запросы
  • Проверьте логи
  • Остановите DaemonSet
  • Удалите созданные ресурсы

Чтобы снизить нагрузку по DNS-запросам в кластере Kubernetes, включите NodeLocal DNS Cache. Функция доступна в кластерах Kubernetes версии 1.18 и выше.

Совет

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

По умолчанию поды отправляют запросы к сервису kube-dns. В поле nameserver в /etc/resolv.conf установлено значение ClusterIp сервиса kube-dns. Для того, чтобы установить соединение с ClusterIP, используется iptables или IP Virtual Server.

При включении NodeLocal DNS Cache в кластере разворачивается DaemonSet. На каждом узле начинает работу кеширующий агент (под node-local-dns). Поды пользователя теперь отправляют запросы к агенту на своем узле.

Если запрос в кеше агента, он возвращает прямой ответ. В ином случае создается TCP-соединение с kube-dns ClusterIP. По умолчанию кеширующий агент делает cache-miss запросы к kube-dns для зоны кластера cluster.local.

С помощью такого плана удается избежать правил DNAT, connection tracking и ограничений по количеству соединений. Подробнее о NodeLocal DNS Cache смотрите в документации.

Чтобы настроить кеширование запросов DNS, выполните следующие действия:

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

  1. Создайте ресурсы.

    Для выполнения сценария вам понадобятся облачная сеть и подсеть, а также сервисный аккаунт. Вы можете использовать существующие ресурсы или создать новые.

    Как создать ресурсы
    1. Создайте облачную сеть.
    2. Создайте в облачной сети подсеть.
    3. Создайте сервисный аккаунт с ролью editor.
  2. Создайте кластер Kubernetes и группу узлов.

    Вы можете использовать уже работающий кластер и группу узлов Kubernetes или создать новые. Убедитесь, что в поле Версия Kubernetes выбрана версия 1.18 или выше.

    Как создать кластер Kubernetes и группу узлов

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

    По умолчанию используется каталог, указанный в профиле CLI. Вы можете указать другой каталог с помощью параметра --folder-name или --folder-id.

    Создайте кластер Kubernetes:

    yc managed-kubernetes cluster create \
      --name node-local-dns \
      --service-account-name <имя сервисного аккаунта кластера> \
      --node-service-account-name <имя сервисного аккаунта групп узлов> \
      --public-ip \
      --zone ru-central1-a \
      --network-name <имя облачной сети>
    

    Результат выполнения:

    done (7m21s)
    ...
    

    Создайте группу узлов:

    yc managed-kubernetes node-group create \
      --name node-group \
      --cluster-name node-local-dns \
      --location zone=ru-central1-a \
      --network-interface subnets=<имя подсети для группы узлов>,ipv4-address=nat \
      --fixed-size 3
    

    Результат выполнения:

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

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

    kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}
    

Подготовьте спецификацию для Node Local DNS и запустите DaemonSet

  1. Создайте файл 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
      labels:
    ---
    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
      labels:
    data:
      Corefile: |
        cluster.local:53 {
          errors
          cache {
            success 9984 30
            denial 9984 5
          }
          reload
          loop
          bind 169.254.20.10 10.96.128.2
          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 10.96.128.2
          forward . __PILLAR__CLUSTER__DNS__ {
            prefer_udp
          }
          prometheus :9253
          }
        ip6.arpa:53 {
          errors
          cache 30
          reload
          loop
          bind 169.254.20.10 10.96.128.2
          forward . __PILLAR__CLUSTER__DNS__ {
            prefer_udp
          }
          prometheus :9253
          }
        .:53 {
          errors
          cache 30
          reload
          loop
          bind 169.254.20.10 10.96.128.2
          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: k8s.gcr.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
    ---
    # A headless service is a service with a service IP but instead of load-balancing it will return the IPs of our associated Pods.
    # We use this to expose metrics to Prometheus.
    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
    
  2. Создайте ресурсы для Node Local 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
    
  3. Убедитесь, что 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
    

Измените конфигурацию NodeLocal DNS Cache

Чтобы изменить конфигурацию, отредактируйте соответствующий configmap. Например, чтобы включить логи DNS-запросов для зоны cluster.local.

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

    kubectl -n kube-system edit configmap node-local-dns
    
  2. Добавьте строку log в конфигурацию зоны cluster.local:

    ...
    apiVersion: v1
    data:
    Corefile: |
    cluster.local:53 {
      log
      errors
      cache {
        success 9984 30
        denial 9984 5
      }
    ...
    
  3. Сохраните изменения.

    Ожидаемый результат выполнения команды:

    configmap/node-local-dns edited
    

Обновление конфигурации может занять несколько минут.

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

Чтобы выполнить тестовые запросы, используйте под с утилитами диагностики DNS.

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

    kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
    

    Ожидаемый результат выполнения команды:

    pod/dnsutils created
    
  2. Убедитесь, что под перешел в состояние Running:

    kubectl get pods dnsutils
    

    Ожидаемый результат выполнения команды:

    NAME      READY  STATUS   RESTARTS  AGE
    dnsutils  1/1    Running  0         26m
    
  3. Подключитесь к поду:

    kubectl exec -i -t dnsutils -- sh
    
  4. Выполните запросы:

    dig +short @169.254.20.10 www.com
    dig +short @10.96.128.2 example.com
    nslookup kubernetes.default
    

    После запуска node-local-dns правила iptables настраиваются так, что по обоим адресам (10.96.128.2:53 и 169.254.20.10:53) отвечает local DNS.

    К kube-dns можно обращаться по новому адресу, ClusterIp сервиса kube-dns-upstream. Этот адрес может понадобиться, чтобы настроить перенаправление (forwarding) запросов.

    Команды и результат их выполнения:

    # dig +short @169.254.20.10 www.com
    52.128.23.153
    # dig +short @10.96.128.2 example.com
    93.184.216.34
    # nslookup kubernetes.default
    Server:         10.96.128.2
    Address:        10.96.128.2#53
    
    Name:   kubernetes.default.svc.cluster.local
    Address: 10.96.128.1
    

Проверьте логи

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

kubectl logs --namespace=kube-system -l k8s-app=node-local-dns -f

Чтобы остановить вывод лога на экран, нажмите Ctrl + C.

Ожидаемый результат выполнения команды:

...
[INFO] 10.112.128.7:50527 - 41658 "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR qr,aa,rd 106 0.000097538s
[INFO] 10.112.128.7:44256 - 26847 "AAAA IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR qr,aa,rd 147 0.057075876s
...

Остановите DaemonSet

Чтобы выключить DaemonSet NodeLocal DNS Cache, выполните команду:

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. Удалите кластер Kubernetes.
  2. Если для доступа к кластеру или узлам использовались статические публичные IP-адреса, освободите и удалите их.

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

Language / Region
© 2022 ООО «Яндекс.Облако»
В этой статье:
  • Подготовьте окружение
  • Подготовьте спецификацию для Node Local DNS и запустите DaemonSet
  • Измените конфигурацию NodeLocal DNS Cache
  • Выполните DNS-запросы
  • Проверьте логи
  • Остановите DaemonSet
  • Удалите созданные ресурсы