Skip to content

Gestion des URLs

Estimated time to read: 3 minutes

Avant d'installer external-dns, il est nécessaire de créer un ServiceAccount afin de lui donner accès aux différents namespaces pour détecter les nouveaux endpoints à gérer:

kubectl apply -f external-dns/external-dns-rbac.yml

ServiceAccount créé

namespace/external-dns created
serviceaccount/external-dns created
clusterrole.rbac.authorization.k8s.io/external-dns created
clusterrolebinding.rbac.authorization.k8s.io/external-dns-viewer created

Configuration de external-dns pour CloudFlare

Vous aurez besoin de 2 infos : la clé d'API et le user email référencé par Cloudfare. Ces 2 infos sont stockés dans des variables d'environnement API_KEY & API_MAIL

Elles sont déjà configurées

On est sympa, c'est déjà fait grâce au script exécuté au début du workshop. Si vous avez changer de terminal, il faut refaire la commande suivante:

source <(curl -s -u "devoxx2024:MOT_DE_PASSE_QUON_VOUS_DONNERA" https://heracles.yodamad.fr/setup/devoxx-2024/setup.sh)

Gestion du secret pour accéder à l'API Cloudflare

Il est nécessaire de créer un secret pour stocker l'API key d'accès à Cloudflare et un autre pour le compte de connexion

kubectl -n external-dns create secret generic cloudflare-api-token --from-literal=api-key=$API_KEY
kubectl -n external-dns create secret generic cloudflare-user-mail --from-literal=user-mail=$API_MAIL

On peut vérifier que les secrets sont bien créés et disponibles

kubectl get secrets -n external-dns

Secrets créés

NAME                   TYPE     DATA   AGE
cloudflare-api-token   Opaque   1      15s
cloudflare-user-mail   Opaque   1      11s

Installation d'external-dns

Pour déployer external-dns, il suffit de créer un Deployment installant l'image officielle d'external-dns

kubectl apply -f external-dns/external-dns-cloudflare.yml

Pour comprendre le manifest:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns-cloudflare
  namespace: external-dns
  labels:
    app.kubernetes.io/instance: external-dns-cloudflare
    app.kubernetes.io/name: external-dns
    app.kubernetes.io/version: 0.14.0
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app.kubernetes.io/instance: external-dns-cloudflare
      app.kubernetes.io/name: external-dns
  template:
    metadata:
      labels:
        app.kubernetes.io/instance: external-dns-cloudflare
        app.kubernetes.io/name: external-dns
    spec:
      serviceAccountName: external-dns
      containers:
        - name: external-dns-cloudflare
          image: registry.k8s.io/external-dns/external-dns:v0.14.0
          args:
            - --source=ingress
# 🛜 On filtre sur le domaine grunty.uk
            - --domain-filter=grunty.uk
# 🚚 Gestionnaire du DNS
            - --provider=cloudflare
# 💡 Prefix pour les enregistrements TXT (et ne pas supprimer ceux du voisin)
# 🫸 C'est un hack pour le TP, cela fonctionne car on à un seul noeud
# 🫸 Dans la vrai vie on utilise un prefix spécifique au cluster
            - --txt-prefix=$(UID)-
            - --txt-owner-id=$(UID)
          env:
            - name: CF_API_TOKEN
              valueFrom:
                secretKeyRef:
# 🤫 On injecte le secret précédement créé avec la clef API
                  name: cloudflare-api-token
                  key: api-key
            - name: CF_API_EMAIL
              valueFrom:
                secretKeyRef:
# 🤫 On injecte le secret précédement créé avec le username
                  name: cloudflare-user-mail
                  key: user-mail
            - name: UID
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
Documentation officielle Cloudflare

La documentation officielle pour Cloudflare est dispo

external-dns is Running

kubectl get po -n external-dns
NAME                                     READY   STATUS    RESTARTS   AGE
external-dns-cloudflare-694f6f75-nf8n8   1/1     Running   0          2s

Vérifier les logs

On peut aussi vérifier que la connexion à Cloudflare est bien ok

kubectl logs $(kubectl get po -n external-dns | grep external-dns-cloudflare | cut -d' ' -f1) -n external-dns
...
time="2023-12-20T08:52:41Z" level=info msg="Instantiating new Kubernetes client"
time="2023-12-20T08:52:41Z" level=info msg="Using inCluster-config based on serviceaccount-token"
time="2023-12-20T08:52:41Z" level=info msg="Created Kubernetes client https://10.3.0.1:443"
...

External DNS en action

On peut voir dans les logs qu'external-dns a déjà automatiquement détecté notre Ingress précédent:

kubectl logs -f $(kubectl get po -n external-dns | grep external-dns-cloudflare | cut -d' ' -f1) -n external-dns
...
time="2023-12-20T08:52:44Z" level=info msg="Changing record." action=CREATE record=new-deployment.mvt.grunty.uk ttl=1 type=A zone=be73d3e4c087b970da9bb670130a11fc
time="2023-12-20T08:52:45Z" level=info msg="Changing record." action=CREATE record=new-deployment.mvt.grunty.uk ttl=1 type=TXT zone=be73d3e4c087b970da9bb670130a11fc
time="2023-12-20T08:52:45Z" level=info msg="Changing record." action=CREATE record=a-new-deployment.mvt.grunty.uk ttl=1 type=TXT zone=be73d3e4c087b970da9bb670130a11fc
...

On peut vérifier que notre nom de domaine est bien reconnu

dig new-deployment.$TF_VAR_OVH_CLOUD_PROJECT_KUBE_NAME.grunty.uk @ara.ns.cloudflare.com

DNS est configuré avec notre IP publique

;; ANSWER SECTION:
new-deployment.<votre_trigramme>.grunty.uk. 300 IN  A   57.128.120.31 (1)
  1. 🛜 l'IP sera différente

On a changé l'image Docker entre temps

Ne vous étonnez pas si vous ne voyez plus le magnifique cinéma ASCII du départ.

On a changé l'image Docker pour que ce que l'on affiche soit lisible lorsque l'on fait un cUrl

On peut aussi valider que le navigateur reconnait notre URL en visitant http://new-deployment.{votre_trigramme}.grunty.uk/

ou via un cURL comme à l'étape précédente

curl new-deployment.<votre_trigramme>.grunty.uk
Server address: 10.2.1.6:80
Server name: new-deployment-5998d8dbcc-kdbrk
Date: 20/Dec/2023:09:45:13 +0000
URI: /
Request ID: 82d85003846eed6c62744103d7ac2bda

C'est beaucoup plus pratique !! 🥳

Mais ... ce n'est pas très sécurisé le HTTP, le chef de brigade de la sécurité nous rappelle à l'ordre 🫣

Si on ajoute quelques mL de sécurité avec des certificats pour notre HTTPs ➡️