Top.Mail.Ru

Облако

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

Что такое ExternalDNS

ExternalDNS автоматически создаёт и удаляет DNS-записи в EdgeCenter DNS, когда вы создаёте или удаляете сервисы (Service LoadBalancer) и ресурсы Ingress в кластере Kubernetes. Работает как контроллер внутри кластера совместно с webhook-компонентом в одном поде.

Требования

Перед началом установки убедитесь, что выполнены следующие условия:

  • kubectl установлен и настроен для подключения к вашему кластеру MKaaS (см. «Подключиться к кластеру Managed Kubernetes»)
  • Helm 3.x установлен
  • У вашей учётной записи есть права на создание пространств имён (namespace), секретов (Secret) и развёртываний (Deployment) в кластере
  • Кластер Managed Kubernetes создан и доступен

Шаг 1. Получите API-токен EdgeCenter

ExternalDNS использует EdgeCenter DNS API для управления записями. Для этого нужен постоянный API-токен.

  1. Войдите в личный кабинет EdgeCenter.
  2. Перейдите в раздел Профиль → API-токены.
  3. Создайте новый токен.
  4. Сохраните токен — он понадобится при установке.

Шаг 2. Убедитесь, что DNS сервис подключен и DNS-зона существует

ExternalDNS управляет только теми зонами, которые уже существуют в вашем аккаунте EdgeCenter DNS. Новые зоны он не создаёт.

  1. Перейдите в личный кабинет EdgeCenter → DNS.
  2. Подключите DNS сервис, если он еще не подключен.
  3. Убедитесь, что нужная зона (например, example.com) добавлена.
  4. Если зоны нет — создайте её через Личный кабинет, API или Terraform.

1. Namespace и секрет 

kubectl create ns external-dns
kubectl create secret generic external-dns-webhook-secrets \ --namespace external-dns \ --from-literal=api-token=ВАШ_ТОКЕН

2. Helm-репозиторий

helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
helm repo update

3. Файл конфигурации
Создайте external-dns-ec-values.yaml. Замените cloud.example.com на вашу зону, my-cluster-id — на уникальный идентификатор кластера.

resources:
  requests: { cpu: 50m, memory: 64Mi }
  limits:   { cpu: 200m, memory: 256Mi }

webhook:
  enabled: true
  securityContext:
    runAsUser: 65532
    runAsGroup: 65532
    runAsNonRoot: true

provider:
  name: webhook
  webhook:
    image:
      repository: ghcr.io/edge-center/external-dns-ec-webhook
      tag: v1.0.0
      pullPolicy: IfNotPresent
    env:
      - name: EC_API_URL
        value: "https://api.edgecenter.ru/dns"
      - name: EC_API_TOKEN
        valueFrom:
          secretKeyRef:
            name: external-dns-webhook-secrets
            key: api-token
      - name: EC_DRY_RUN
        value: "false"
      - name: EC_WEBHOOK_SERVER_ADDR
        value: ":8080"
    service:
      port: 8080

extraArgs:
  - "--webhook-provider-url=http://localhost:8080"

annotationFilter: "external-dns/edgecenter in (true)"
domainFilters:
  - "cloud.example.com"
sources:
  - service
  - ingress
policy: sync
txtOwnerId: "my-cluster-id"
logLevel: info
interval: 30s
registry: txt
metrics:
  enabled: true

Примечание: txtOwnerId должен быть уникальным для каждого кластера. Одинаковые значения приведут к конфликтам записей.

4. Установка

helm upgrade --install external-dns external-dns/external-dns \
  --version 1.19.0 \
  --namespace external-dns \
  --create-namespace \
  -f external-dns-ec-values.yaml

5. Проверка

kubectl -n external-dns get all
kubectl -n external-dns logs -l app.kubernetes.io/name=external-dns -c external-dns --tail=50

Под должен быть в статусе Running с двумя контейнерами.

Добавьте аннотации к сервису или ресурсу Ingress, чтобы ExternalDNS создал DNS-запись.

Как формируются записи

ExternalDNS берёт два элемента из манифестов Kubernetes.

Имя записи (hostname):

  • Аннотация `external-dns.alpha.kubernetes.io/hostname` для Service (LoadBalancer).
  • Поле `spec.rules[].host` для Ingress.

Целевой адрес (target):

  • Поле `status.loadBalancer.ingress` — заполняется автоматически после назначения адреса облачным провайдером.

Тип записи:

  • A-запись (если target — IP) или CNAME (если target — hostname).

Внутренний и внешний LoadBalancer

ExternalDNS не различает внутренний (internal) и внешний (external) LoadBalancer. Он использует данные, которые уже отражены в статусе Kubernetes. Для LoadBalancer-сервиса это обычно значения из `spec.externalIPs`, а если их нет, то из `status.loadBalancer.ingress[].ip` или `hostname`. Он одинаково читает поле `status.loadBalancer.ingress` в обоих случаях.

Тип балансировщика:

Внешний (по умолчанию): публичный IP (например, `185.12.34.56`). A-запись доступна из интернета. Основной сценарий.
Внутренний (internal): приватный IP (например, `10.0.1.15`). A-запись резолвится публично, но подключиться можно только из внутренней сети (VPC/VPN).

Service LoadBalancer

apiVersion: v1
kind: Service
metadata:
  name: my-app
  annotations:
    external-dns/edgecenter: "true"
    external-dns.alpha.kubernetes.io/hostname: my-app.cloud.example.com
spec:
  type: LoadBalancer
  selector: { app: my-app }
  ports:
    - port: 80
      targetPort: 8080

Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    external-dns/edgecenter: "true"
spec:
  ingressClassName: nginx
  rules:
    - host: my-app.cloud.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service: { name: my-app, port: { number: 80 } }

Дополнительные аннотации
TTL записи: external-dns.alpha.kubernetes.io/ttl: "300"

Диагностика

Если записи не появляются, проверьте по порядку:

Аннотация external-dns/edgecenter: "true" присутствует.
Домен совпадает с domainFilters.
DNS-зона существует в аккаунте EdgeCenter.
Логи ExternalDNS:

kubectl -n external-dns logs -l app.kubernetes.io/name=external-dns -c external-dns --tail=100

Логи Webhook:

kubectl -n external-dns logs -l app.kubernetes.io/name=external-dns -c webhook --tail=50

Проверка DNS:

dig my-app.cloud.example.com

Удаление

helm delete -n external-dns external-dns
kubectl delete secret external-dns-webhook-secrets -n external-dns
kubectl delete ns external-dns

См. также
ExternalDNS: https://github.com/kubernetes-sigs/external-dns
EdgeCenter webhook: https://github.com/Edge-Center/external-dns-ec-webhook
EdgeCenter DNS API: https://api.edgecenter.ru/docs/dns

Мы используем cookie, чтобы сайт стал лучше для вас.