La version bêta de KIOWY Platform 🚀
est disponible ! En savoir +

Retour

Comment synchroniser automatiquement votre DNS externe avec Kubernetes ? 18.06.2021

Quand tout est automatisé sur un cluster Kubernetes, déployer une application devient automagique ! Et pourtant il y a une étape qui reste manuelle : la synchronisation du DNS externe.

Nous allons voir aujourd’hui comment automatiser la création de vos enregistrements DNS à partir des informations déjà présentes dans Kubernetes, tout ça sans changer le code de vos applications existantes.


Bye bye la saisie manuelle 👋

Vous vous êtes sûrement déjà retrouvé dans cette situation où alors que vous veniez tout juste de terminer votre application, de créer vos deployments et vos services, et de créer un objet Ingress afin d’exposer votre application au monde entier, vous devez ensuite mettre à jour manuellement votre DNS.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: helloworld-ingress
namespace: app-test
spec:
rules:
- host: test.kiowy.com
http:
paths:
- backend:
serviceName: helloworld-service
servicePort: 80
path: /

Alors que vous venez d’indiquer le nom de domaine de votre application (dans notre exemple test.kiowy.com), vous devez ensuite manuellement renseigner un enregistrement A dans votre DNS, après avoir trouvé l’IP de votre LoadBalancer externe. Cela peut très vite devenir une tâche fastidieuse si vous en avez plusieurs... Sans compter sur les futures modifications de votre projet qui pourront rapidement vous poser problème, comme entraîner des interruption de services.

Imaginez qu’un jour vous souhaitiez changer d’IngressController, ou migrer de cluster. L’IP externe va alors changer mais pas votre enregistrement DNS, laissant vos utilisateurs face à une belle erreur 404 ou 502.

502 Bad Gateway error with a man blaming a gateway computer

Alors comment faire pour éviter de passer toute une journée à configurer votre DNS ?

Il existe une solution : ExternalDNS. 


Welcome ExternalDNS (+ Cloudflare)


ExternalDNS est un outil qui synchronise automatiquement vos enregistrements DNS selon les informations dans votre cluster.

Afin de faire plus ample connaissance avec cet outil, nous allons donc voir comment l’installer au sein d’un cluster. 

#1 - Choisir son fournisseur DNS


ExternalDNS nécessite un fournisseur DNS exposant une API pour gérer automatiquement la zone. À l’heure actuelle, ExternalDNS (v0.7) supporte les fournisseurs suivants :

Dans cet exemple, j’ai choisi d’utiliser CloudFlare qui gère déjà la zone DNS kiowy.com


Pour commencer vous devez avoir un domaine dont la zone est gérée par CloudFlare.

Si ce n’est pas encore le cas, vous pourrez trouver toutes les informations pour vous inscrire et migrer votre nom de domaine sur CloudFlare dans cet article.

#2 - Créer un jeton d’API


Connectez-vous à votre compte et rendez-vous sur https://dash.cloudflare.com/profile/api-tokens afin de créer un jeton d’API qui permettra à ExternalDNS de s’authentifier auprès de CloudFlare.

Les privilèges minimum sont Read de la Zone et Edit du DNS. ⚠️ Attention ensuite vous devez autoriser toutes les zones. En effet, un bug empêche de restreindre un jeton à une seule zone dans la version v0.7 de ExternalDNS.


Capture d'écran de l'interface de création de Jeton d'API CloudFlare


Validez et n’oubliez pas de conserver le jeton fraîchement créé.

Nous allons le stocker dans Kubernetes sous la forme d’un Secret.

Dégainez kubectl et créez un namespace pour accueillir les objets external-dns.


$ kubectl create ns external-dns
namespace/external-dns created


NB : Vous pouvez changer de namespace avec la commande $ kubectl config set-context --current --namespace=external-dns, cela vous évitera de spécifier à chaque fois le namespace dans les commandes suivantes.


Créez ensuite votre Secret avec le jeton créé précédemment.

$ kubectl create secret generic kiowy-blog-cf-api-token --from-literal=<API TOKEN>
secret/kiowy-blog-cf-api-token created


Votre jeton est désormais fin prêt à être utilisé par ExternalDNS.


#3 - Déployer ExternalDNS


Ensuite, si RBAC est activé dans votre cluster (et j’espère que c’est le cas…), nous devons ajouter un ClusterRole permettant de lire les objets nécessaires à ExternalDNS, ainsi qu’un compte de service (ServiceAccount) et assigner ce rôle grâce au ClusterRoleBinding.


apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
namespace: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: external-dns


Enfin, nous pouvons déployer ExternalDNS dans le cluster. Pensez bien à spécifier le nom de votre secret dans la variable CF_API_TOKEN.

apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.opensource.zalan.do/teapot/external-dns:latest
args:
- --source=ingress
- --domain-filter=kiowy.com
- --provider=cloudflare
- --cloudflare-proxied # (optional) enable the proxy feature of Cloudflare (DDOS protection, CDN...)
env:
- name: CF_API_TOKEN
valueFrom:
secretKeyRef:
name: kiowy-blog-cf-api-token
key: token


Quelques explications sur les options de external-dns :

--source : indique depuis quel objet rechercher les noms de domaine. “Service” est une valeur possible également.

--domain-filter : indique à ExternalDNS de n’observer que certains domaines (ici seulement kiowy.com).

--cloudflare-proxied : permet d’activer par défaut la fonctionnalité de Proxy et CDN de CloudFlare sur les enregistrements.

Ajoutez ce déploiement à votre cluster. Dans quelques instants, ExternalDNS va commencer à surveiller les objets Ingress dans votre cluster. Par défaut, ExternalDNS ne supprime ou ne modifie pas les enregistrements déjà présents dans votre zone (pour éviter les catastrophes). ExternalDNS utilise un enregistrement TXT pour suivre les enregistrements qu’il supervise.


#4 - Déployer l’application


Pour tester, déployez un nouvel objet Ingress ou bien modifiez un déjà existant. Puis rendez-vous sur votre dashboard CloudFlare, vous devriez voir apparaître votre nouvel enregistrement :


Capture d'écran de l'interface de CloudFlare montrant un enregistrement DNS A créé automatiquement


Voilà ! Vous pouvez désormais déployer vos applications dans votre cluster et ExternalDNS synchronisera automagiquement votre DNS externe avec vos Ingresses. À vous de jouer !


Psst... Vous pouvez retrouver toutes les autres options et Ingress compatibles sur la doc d’ExternalDNS ici ⇒  https://github.com/kubernetes-sigs/external-dns


Vous avez une(des) question(s) liée(s) à la thématique abordée dans cet article ? 

Écrivez-nous à [email protected] 😉