Автоматическое управление DNS-записями в Kubernetes с помощью ExternalDNS
Cloud Server | Комментировать запись
При развертывании веб-приложений в Kubernetes сервисы и Ingresses обычно применяются для того, чтобы открыть доступ к приложению по домену за пределами кластера. Это включает ручную настройку не только Ingress, но и DNS-записей провайдера, а этот процесс может быть трудоемким и подверженным ошибкам. Более того, по мере роста вашего приложения этот процесс может стать гораздо сложнее; при изменении внешнего IP-адреса необходимо соответствующим образом обновить записи DNS.
Чтобы устранить эту проблему, команда Kubernetes sig-network создала инструмент ExternalDNS, целью которого является автоматическое управление внешними записями DNS из кластера Kubernetes. После развертывания ExternalDNS работает в фоновом режиме и почти не требует дополнительной настройки. Каждый раз, когда создается или изменяется сервис или Ingress, ExternalDNS сразу обновляет записи.
В этом мануале вы научитесь устанавливать ExternalDNS в свой кластер Kubernetes через Helm и настраивать поддержку DNS-провайдера. Позже мы развернем образец веб-приложения с Ingress и попробуем использовать ExternalDNS, чтобы направить его на ваш домен. В результате у вас будет автоматизированная система управления записями DNS для сервисов и Ingress-ов.
Требования
- Кластер Kubernetes с настроенным kubectl по умолчанию.
- Менеджер пакетов Helm на вашем локальном компьютере и Tiller в кластере. Для этого выполните шаги 1 и 2 мануала Установка программного обеспечения в кластер Kubernetes с помощью пакетного менеджера Helm.
- Nginx Ingress Controller в кластере, установленный с помощью Helm (чтобы использовать ExternalDNS и ресурсы Ingress). Следуйте этому мануалу. Вам необходимо установить для свойства publishService значение true, как описано в разделе 2.
- Ключ API (токен личного доступа) с разрешениями на чтение и запись.
- Полностью зарегистрированное доменное имя. В этом мануале будет использоваться условный домен echo.example.com.
1: Установка ExternalDNS с помощью Helm
Сначала нужно установить ExternalDNS в свой кластер с помощью Helm и настроить его для взаимодействия с сервисом DNS вашего провайдера.
Чтобы переопределить некоторые параметры по умолчанию для чарта ExternalDNS, вам необходимо создать файл values.yaml, который вы передадите в Helm во время установки. На компьютере, который вы используете для доступа к кластеру, создайте файл:
nano externaldns-values.yaml
Добавьте в него следующие строки:
rbac:
create: true
provider: your-provider
your-provider:
apiToken: your_api_token
interval: "1m"
policy: sync # or upsert-only
# domainFilters: [ 'example.com' ]
В первом блоке включается создание манифеста RBAC (управление доступом на основе ролей), которое обязательно должно быть включено в кластерах Kubernetes с поддержкой RBAC. В следующей строке устанавливается DNS-провайдер. Затем в следующем блоке вам нужно указать свой API токен провайдера, заменив your_api_token.
Следующая строка устанавливает интервал, с которым ExternalDNS будет запрашивать изменения в Ingress-ах и сервисах. Вы можете установить меньшее значение, чтобы быстрее распространять изменения в DNS.
Параметр policy определяет, что может делать ExternalDNS: только вставлять записи DNS (upsert-only) или создавать и удалять их по мере необходимости (sync). К счастью, начиная с версии 0.3, ExternalDNS поддерживает собственность, создавая сопровождающие записи TXT , в которых он хранит информацию о доменах и ограничивает их область действия.
Параметр domainFilters используется для ограничения доменов, которыми может управлять ExternalDNS. Вы можете раскомментировать его и ввести свои домены в виде массива строк, но это не обязательно.
Когда вы закончите редактирование, сохраните и закройте файл.
Теперь установите ExternalDNS в кластер, выполнив следующую команду:
helm install stable/external-dns --name external-dns -f externaldns-values.yaml
Вывод команды будет выглядеть примерно так:
NAME: external-dns
LAST DEPLOYED: ...
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
external-dns-69c545655f-xqjjf 0/1 ContainerCreating 0 0s
==> v1/Secret
NAME TYPE DATA AGE
external-dns Opaque 1 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
external-dns ClusterIP 10.245.47.69 <none> 7979/TCP 0s
==> v1/ServiceAccount
NAME SECRETS AGE
external-dns 1 0s
==> v1beta1/ClusterRole
NAME AGE
external-dns 0s
==> v1beta1/ClusterRoleBinding
NAME AGE
external-dns 0s
==> v1beta1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
external-dns 0/1 1 0 0s
NOTES:
...
Вы можете проверить создание ExternalDNS при помощи команды:
kubectl --namespace=default get pods -l "app=external-dns,release=external-dns" -w
NAME READY STATUS RESTARTS AGE
external-dns-69bfcf8ccb-7j4hp 0/1 ContainerCreating 0 3s
Вы установили ExternalDNS в свой кластер Kubernetes. Далее мы развернем образец веб-приложения и откроем к нему доступ с помощью Nginx Ingress, а потом ExternalDNS автоматически направит домен на соответствующий балансировщик нагрузки.
2: Развертывание веб-приложения и настройка доступа к нему
В этом разделе мы развернем в кластере фиктивное веб-приложение, а затем откроем его с помощью Ingress. Затем мы подготовим ExternalDNS к автоматической настройке DNS-записей. В итоге у вас будут DNS записи для вашего домена, указывающие на балансировщик нагрузки Ingress.
В качестве тестового веб-приложениея мы используем http-echo от Hashicorp. Это in-memory веб-сервер, который возвращает отправленное вами сообщение. Хранить его манифесты Kubernetes можно в файле echo.yaml. Создайте его и откройте в редакторе:
nano echo.yaml
Добавьте следующие строки в этот файл:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: echo-ingress
spec:
rules:
- host: echo.example.com
http:
paths:
- backend:
serviceName: echo
servicePort: 80
---
apiVersion: v1
kind: Service
metadata:
name: echo
spec:
ports:
- port: 80
targetPort: 5678
selector:
app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo
spec:
selector:
matchLabels:
app: echo
replicas: 3
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: hashicorp/http-echo
args:
- "-text=Echo!"
ports:
- containerPort: 5678
В этой конфигурации вы определяете развертывание, Ingress и сервис. Развертывание состоит из трех реплик приложения http-echo с переданным пользовательским сообщением (Echo!). Сервис разрешает доступ к модулям в Развертывании через порт 80. Ingress открывает доступ к сервису по вашему домену.
Замените echo.example.com своим доменом, затем сохраните и закройте файл.
Теперь вам не нужно вручную настраивать DNS-записи для домена. ExternalDNS сделает это автоматически, как только вы примените конфигурацию к Kubernetes.
Чтобы применить конфигурацию, выполните следующую команду:
kubectl create -f echo.yaml
Вы увидите следующий вывод:
ingress.extensions/echo-ingress created
service/echo created
deployment.apps/echo created
Вам нужно будет немного подождать, пока ExternalDNS заметит изменения и создаст соответствующие записи. Настройка interval в чарте Helm определяет продолжительность времени, в течение которого вам нужно ожидать создания записи DNS. В values.yaml интервал по умолчанию – 1 минута.
Откройте панель управления своего облачного провайдера и убедитесь, что у вас появилась запись TXT.
По истечении указанного промежутка времени используйте curl:
curl echo.example.com
Если все правильно, вы увидите следующий вывод:
Echo!
Это сообщение подтверждает, что вы настроили ExternalDNS и создали необходимые DNS-записи для работы балансировщика нагрузки контроллера Ingress. Если вы видите сообщение об ошибке, подождите еще немного. Также можно попробовать получить доступ к своему домену через браузер, где вы должны увидеть это сообщение.
Вы протестировали ExternalDNS, развернув образец приложения через Ingress. Вы также можете найти новые записи DNS в панели управления хостинга.
3: Открытие доступа к приложению через сервис (опционально)
В этом дополнительном разделе вместо Ingress мы используем сервис с ExternalDNS. ExternalDNS позволяет открывать DNS-серверам доступ к разным ресурсам Kubernetes. Использование сервисов аналогично процессу Ingress-а, нужно только немного отладить конфигурацию для этого ресурса.
Примечание: После выполнения этого раздела только что созданные вами DNS записи будут удалены.
Поскольку вы будете настраивать сервис, содержащийся в echo.yaml, вам больше не понадобится echo-ingress. Удалите его:
kubectl delete ing echo-ingress
ingress.extensions/echo-ingress deleted
ExternalDNS удалит существующие записи DNS, созданные на предыдущем этапе. В оставшейся части мануала вы можете использовать тот же домен, который вы использовали ранее.
Далее откройте файл echo.yaml для редактирования:
nano echo.yaml
Замените текущее содержимое этого файла следующими строками:
apiVersion: v1
kind: Service
metadata:
name: echo
annotations:
external-dns.alpha.kubernetes.io/hostname: echo.example.com
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 5678
selector:
app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo
spec:
selector:
matchLabels:
app: echo
replicas: 3
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: hashicorp/http-echo
args:
- "-text=Echo!"
ports:
- containerPort: 5678
Вы удалили Ingress из предыдущей настройки и изменили тип сервиса на LoadBalancer. Кроме того, вы добавили аннотацию, указав доменное имя для ExternalDNS.
Примените изменения к кластеру, выполнив следующую команду:
kubectl apply -f echo.yaml
В выводе появится:
service/echo configured
deployment.apps/echo configured
Вы можете наблюдать, как к балансировщику нагрузки сервиса появляется доступ, запустив команду:
kubectl get svc echo -w
Вы увидите похожий вывод:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
echo LoadBalancer 10.245.81.235 <pending> 80:31814/TCP 8s
...
Как и прежде, вам нужно будет немного подождать, пока создадутся и распространятся записи DNS. Как только это будет сделано, запустите curl на указанный вами домен:
curl echo.example.com
Вывод будет таким же, как на предыдущем этапе:
Echo!
Если вы получили ошибку, подождите немного дольше или попробуйте другой домен. Поскольку в клиентских системах записи DNS кэшируются, для фактического распространения изменений может потребоваться больше времени.
Итак, вы создали сервис типа LoadBalancer и направили ее на свое доменное имя, используя ExternalDNS.
Заключение
ExternalDNS работает в фоновом режиме и упрощает работу в кластере. Ваш кластер Kubernetes только что стал основным доверенным источником надежных данных о доменах. Вам больше не придется обновлять DNS-записи вручную.
Tags: DNS, ExternalDNS, Helm, Ingress, Kubernetes, NGINX, Tiller