VK Cloud logo
Обновлена 15 апреля 2024 г. в 08:50

Установка и использование ExternalDNS

ExternalDNS позволяет автоматизировать управление DNS-записями при работе с ресурсами Ingress или Service. Если эти ресурсы настроены согласно требованиям ExternalDNS, то они будут доступны по доменному имени сразу после создания.

ExternalDNS интегрируется с сервисом DNS в VK Cloud с помощью плагина. Далее будет показано, как установить ExternalDNS в кластер, и как использовать этот инструмент с ресурсами Ingress и Service.

Подготовительные шаги

  1. Создайте DNS-зону, с которой будет работать ExternalDNS, если этого еще не сделано.

    Для примера далее используется зона example.com.

  2. Создайте кластер Cloud Containers самой актуальной версии, который имеет внешний IP-адрес и доступен из интернета.

    Прочие параметры кластера выберите на свое усмотрение.

  3. Убедитесь, что вы можете подключиться к кластеру с помощью kubectl.

    Для подключения используйте файл конфигурации кластера (kubeconfig), загруженный из личного кабинета VK Cloud.

  4. Установите Helm версии 3.0.0 или выше, если утилита еще не установлена.

    Выберите для установки версию Helm, которая совместима с кластером.

  5. Задайте переменную среды окружения, указывающую на kubeconfig для кластера. Это упростит работу с утилитами kubectl и helm при установке ExternalDNS.

    Путь к вашему файлу kubeconfig может отличаться от примера ниже.

    export KUBECONFIG="/home/user/.kube/kubernetes-cluster-1234_kubeconfig.yaml"

1. Подготовьте пользователя для ExternalDNS

ExternalDNS будет использовать реквизиты этого пользователя VK Cloud, чтобы взаимодействовать с API VK Cloud и управлять ресурсными записями DNS.

Подготовьте пользователя и получите все необходимые реквизиты:

  1. Выберите существующего пользователя или пригласите в проект нового пользователя.

    Требования к пользователю:

    • Должен быть активирован доступ по API.

    • Должна быть назначена одна из следующих ролей, чтобы ExternalDNS мог оперировать ресурсными записями в рамках DNS-зоны:

      • Администратор сети (минимально необходимая роль).
      • Администратор проекта.
      • Суперадминистратор.
      • Владелец проекта.
  2. Получите реквизиты, нужные для доступа к API VK Cloud:

    1. Перейдите в личный кабинет VK Cloud, используя реквизиты пользователя, выделенного для ExternalDNS.

    2. Нажмите на имя пользователя в шапке страницы и выберите Настройки проекта.

    3. Перейдите на вкладку Доступ по API и запишите значения следующих параметров:

      • Project ID (Project ID для OpenStack);
      • User Domain Name (имя домена пользователя);
      • Username (имя пользователя);
      • Region Name (название региона);
      • Auth URL (URL для аутентификации).
  3. Запишите пароль этого пользователя: он также необходим для доступа к API.

2. Установите ExternalDNS

  1. Создайте пространство имен, в которое будет установлен ExternalDNS:

    kubectl create ns external-dns
  2. Создайте в этом пространстве имен секрет, который содержит в себе реквизиты для доступа к API VK Cloud, полученные при подготовке пользователя:

    kubectl -n external-dns create secret generic vkcs-auth \  --from-literal=ProjectID="<Project ID>" \  --from-literal=UserDomainName="<User Domain Name>" \  --from-literal=Username="<Username>" \  --from-literal=RegionName="<Region Name>" \  --from-literal=AuthURL="<Auth URL>" \  --from-literal=Password="<пароль пользователя>"
  3. Добавьте Helm-репозиторий Bitnami:

    helm repo add bitnami https://charts.bitnami.com/bitnami
  4. Создайте файл, который содержит в себе значения (values), нужные для установки ExternalDNS с помощью Helm:

    На поведение Helm-чарта (chart) ExternalDNS влияет множество значений. В созданном файле задан минимальный набор значений, достаточный для начала работы с ExternalDNS. Ниже описаны наиболее важные значения, которые влияют на работу ExternalDNS с DNS VK Cloud. Описания значений, которые не относятся к плагину VK Cloud (все значения, кроме sidecars[]), приведены в README.md для чарта.

    Плагин для ExternalDNS, который обеспечивает интеграцию с DNS VK Cloud, имеет множество настроек, влияющих на поведение плагина. Настройки задаются с помощью переменных среды окружения в sidecars[].env. В созданном файле заданы только обязательные настройки. При необходимости вы можете задать дополнительные настройки для плагина, добавив соответствующие переменные среды окружения.

  5. Установите ExternalDNS:

    helm -n external-dns install external-dns-vkcs bitnami/external-dns -f external-dns-vkcs-values.yaml
  6. Убедитесь, что Helm-чарт был успешно развернут:

    helm -n external-dns list && kubectl -n external-dns get all

3. Проверьте работу External DNS

Далее будет развернуто несколько демо-приложений, основанных на примере Cafe от NGINX. Эти приложения будут опубликованы (сделаны доступными из интернета) с использованием Service и Ingress, настроенных на работу с ExternalDNS.

3.1. Опубликуйте приложение, используя сервис типа LoadBalancer

  1. Создайте манифест для приложения tea:

  2. Примените этот манифест в кластере для развертывания приложения:

    kubectl apply -f tea-app.yaml
  3. Проверьте, что приложение было успешно развернуто в виде ReplicaSet из трех реплик:

    kubectl get rs,pod -l app==tea
  4. Создайте манифест tea-service.yaml для сервиса Kubernetes (Service).

    Этот сервис будет использован для того, чтобы опубликовать развернутое приложение. Приложение будет доступно по доменному имени tea.example.com.

    Чтобы ExternalDNS создал ресурсные записи для сервиса:

    • Для сервиса должна быть задана аннотация external-dns.alpha.kubernetes.io/hostname.
    • Сервис должен иметь тип LoadBalancer.

    Укажите аннотацию external-dns.alpha.kubernetes.io/ttl, если нужно задать нестандартный TTL для ресурсных записей (по умолчанию: 86400 секунд, 24 часа).

    apiVersion: v1kind: Servicemetadata:  annotations:    external-dns.alpha.kubernetes.io/hostname: "tea.example.com"    external-dns.alpha.kubernetes.io/ttl: "3600"  name: tea-svc  labels:    app: teaspec:  type: LoadBalancer  ports:  - port: 80    targetPort: 8080    protocol: TCP    name: http  selector:    app: tea

    Здесь:

    • Указана обязательная аннотация external-dns.alpha.kubernetes.io/hostname: доменное имя, которое нужно использовать для сервиса.

    • Указана опциональная аннотация external-dns.alpha.kubernetes.io/ttl: TTL в секундах для ресурсной записи, которая будет создана ExternalDNS.

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

  5. Примените этот манифест в кластере для создания сервиса:

    kubectl apply -f tea-service.yaml
  6. Проверьте статус сервиса:

    kubectl get svc tea-svc

    Дождитесь, когда сервису будет назначен публичный IP-адрес балансировщика. Создание балансировщика может занять длительное время.

  7. Убедитесь, что ExternalDNS создал необходимые ресурсные записи:

    1. Получите список ресурсных записей для зоны example.com.

    2. Найдите в списке записи, созданные ExternalDNS:

      • Одну A-запись tea.example.com.

      • Две TXT-записи externaldns-tea.example.com и externaldns-a-tea.example.com.

        Эти TXT-записи — служебные и используются ExternalDNS для отслеживания состояния созданной для сервиса tea-svc A-записи.

      Если нужных ресурсных записей нет, подождите еще несколько минут. ExternalDNS начнет создание ресурсных записей после того, как сервису будет назначен IP-адрес. На это потребуется некоторое время.

  8. Проверьте, что приложение доступно по доменному имени. Для этого перейдите в браузере по адресу http://tea.example.com.

    Должна открыться страница с ответом от приложения вида:

    Server address: 10.100.184.219:8080Server name: tea-XXXXXXXXX-AAAAADate: 09/Feb/2024:10:09:51 +0000URI: /Request ID: <уникальный идентификатор запроса>

    Успешное взаимодействие с приложением по этому адресу свидетельствует о корректной работе ExternalDNS c сервисом типа LoadBalancer.

3.2. Опубликуйте приложение, используя Ingress

  1. Установите в кластер аддон Ingress NGINX самой актуальной версии.

    Выполните стандартную установку. Не изменяйте никакие параметры, только отредактируйте код настройки аддона:

    1. Убедитесь, что аннотация service.beta.kubernetes.io/openstack-internal-load-balancer имеет значение false:

      controller:  ...  service:    annotations: {"loadbalancer.openstack.org/proxy-protocol": "true", "service.beta.kubernetes.io/openstack-internal-load-balancer": "false"}    ...

      Это необходимо, чтобы для Ingress-контроллера был создан балансировщик нагрузки с публичным IP-адресом. Тогда приложение, использующее Ingress, будет доступно из интернета.

    2. Задайте для поля controller.publishService.enabled значение true:

      controller:  ...  publishService:    enabled: true    pathOverride: ""    ...

      Это необходимо, чтобы ресурсу Ingress был назначен публичный IP-адрес Ingress-контроллера. Это позволит ExternalDNS создать корректные ресурсные записи для Ingress.

    Дождитесь завершения установки аддона. Этот процесс может занять длительное время.

  2. Создайте манифест для приложения coffee:

  3. Создайте манифест для сервиса Kubernetes, который будет использоваться приложением.

    Здесь для сервиса задан тип ClusterIP, его достаточно, поскольку приложение будет опубликовано с помощью Ingress. Такой сервис доступен только изнутри кластера и не имеет выделенного балансировщика нагрузки в отличие от сервиса, созданного ранее.

  4. Примените эти манифесты в кластере для создания всех необходимых ресурсов:

    kubectl apply -f coffee-app.yaml -f coffee-service.yaml
  5. Проверьте, что приложение было успешно развернуто в виде ReplicaSet из двух реплик вместе с соответствующим сервисом:

    kubectl get rs,pod,svc -l app==coffee
  6. Создайте манифест cafe-ingress.yaml для ресурса Ingress.

    Этот ресурс Ingress будет использован для того, чтобы опубликовать развернутое приложение. Приложение будет доступно на домене cafe.example.com по URL http://cafe.example.com/coffee.

    Чтобы ExternalDNS создал ресурсные записи для сервиса, не нужно указывать никаких дополнительных значений в манифесте: достаточно наличия Ingress-контроллера, настроенного нужным образом. Значения доменных имен будут взяты из полей host для правил Ingress spec.rules[].

    Укажите аннотацию external-dns.alpha.kubernetes.io/ttl, если нужно задать нестандартный TTL для ресурсных записей (по умолчанию: 86400 секунд, 24 часа).

    apiVersion: networking.k8s.io/v1kind: Ingressmetadata:  name: cafe-ingress  annotations:    external-dns.alpha.kubernetes.io/ttl: "3600"spec:  ingressClassName: nginx  rules:  - host: cafe.example.com    http:      paths:      - path: /coffee        pathType: Prefix        backend:          service:            name: coffee-svc            port:              number: 80

    Здесь:

    • Указана опциональная аннотация external-dns.alpha.kubernetes.io/ttl: TTL в секундах для ресурсных записей, которые будут созданы ExternalDNS.
    • Указан хост cafe.example.com для правила Ingress. Поскольку указан только один хост, то будет создана одна ресурсная запись для этого доменного имени.
    • Согласно правилу Ingress, приложение coffee, которое находится за сервисом coffee-svc, будет доступно по URL http://cafe.example.com/coffee.
  7. Примените этот манифест в кластере для создания ресурса:

    kubectl apply -f cafe-ingress.yaml
  8. Проверьте статус Ingress:

    kubectl get ingress cafe-ingress

    Дождитесь, когда ресурсу Ingress будет назначен публичный IP-адрес. Этот адрес будет совпадать с адресом Ingress-контроллера.

  9. Убедитесь, что ExternalDNS создал необходимые ресурсные записи:

    1. Получите список ресурсных записей для зоны example.com.

    2. Найдите в списке записи, созданные ExternalDNS:

      • Одну CNAME-запись cafe.example.com.

      • Две TXT-записи externaldns-cafe.example.com и externaldns-cname-cafe.example.com.

        Эти TXT-записи — служебные и используются ExternalDNS для отслеживания состояния созданной для Ingress cafe-ingress CNAME-записи.

      Если нужных ресурсных записей нет, подождите еще несколько минут. ExternalDNS начнет создание ресурсных записей после того, как ресурсу Ingress будет назначен IP-адрес. На это потребуется некоторое время.

  10. Проверьте, что приложение доступно по доменному имени. Для этого перейдите в браузере по адресу http://cafe.example.com/coffee.

    Должна открыться страница с ответом от приложения вида:

    Server address: 10.100.184.220:8080Server name: coffee-YYYYYYYYY-DDDDDDate: 09/Feb/2024:13:07:11 +0000URI: /coffeeRequest ID: <уникальный идентификатор запроса>

    Успешное взаимодействие с приложением по этому адресу свидетельствует о корректной работе ExternalDNS c ресурсом Ingress.

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

  1. Если созданные ресурсы Kubernetes, предназначенные для проверки работоспособности ExternalDNS, вам больше не нужны, удалите их:

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

      kubectl delete -f cafe-ingress.yaml -f coffee-service.yaml -f coffee-app.yaml

      Удаление связанного с сервисом балансировщика нагрузки может занять длительное время.

    2. Удалите все ресурсы, связанные с приложением coffee:

      kubectl delete -f tea-service.yaml -f tea-app.yaml
    3. Удалите аддон Ingress NGINX.

      Удаление аддона и связанных с ним ресурсов может занять длительное время.

    4. Удалите ресурсные записи, созданные ExternalDNS.

      Это необходимо сделать, если вы не изменяли файл external-dns-vkcs-values.yaml при установке ExternalDNS: тогда ExternalDNS использует политику upsert-only и не удаляет ресурсные записи из DNS-зоны при удалении ресурсов Kubernetes. Если вы изменили этот файл и выбрали политику sync, то эти записи будут удалены автоматически.

      Перечень ресурсных записей:

      • A-запись tea.example.com.
      • TXT-записи externaldns-tea.example.com и externaldns-a-tea.example.com.
      • CNAME-запись cafe.example.com.
      • TXT-записи externaldns-cafe.example.com и externaldns-cname-cafe.example.com.
  2. Если ExternalDNS вам больше не нужен, удалите его:

    1. Удалите Helm-чарт с ExternalDNS:

      helm -n external-dns uninstall external-dns-vkcs
    2. Удалите пространство имен external-dns.

      kubectl delete ns external-dns
  3. Работающий кластер Cloud Containers тарифицируется и потребляет вычислительные ресурсы. Если он вам больше не нужен:

  4. Удалите DNS-зону example.com, если она вам больше не нужна.