Ajouter une entrée DNS custom à coredns

Sommaire

Ci-après un article pense-bête pour modifier la configuration de coredns, le serveur DNS que l'on retrouvera par défaut dans un cluster Kubernetes.

Il m'arrive parfois de devoir ajouter des entrées DNS à la main dans un cluster, pour que les applications de celui-ci puissent joindre un service non encore déclaré, ou bien pour pointer vers un service répliqué hors prod. En gros modifier le /etc/hosts de sa machine linux, mais pour l'ensemble des applis du cluster.

Ici, je souhaite que mes applis puissent joindre myapp.opsrel.io sur l'IP 74.220.17.133, on va voir comment coredns permet cela.

Pour l'exemple, j'utilise un Cluster Civo, qui me permet de provisionner des clusters facilement. Les modifications à faire sur coredns peuvent changer selon l'installation faite par votre cloud provider ou admin préféré.

Création du cluster de test

Il suffit simplement d'utiliser la CLI pour provisionner le cluster. Ici je crée un cluster de 2 nœuds avec des instances xsmall. Je récupère ensuite le fichier de configuration pour pouvoir m'y connecter (via la variable d'environnement KUBECONFIG).

1$ civo kubernetes create coredns-demo --size=g4s.kube.xsmall --nodes=2 --wait
2$ civo kubernetes config coredns-demo -s -p coredns-demo-kubeconfig
3$ export KUBECONFIG=${PWD}/coredns-demo-kubeconfig
4$ kubectl get nodes
5NAME                                                STATUS   ROLES    AGE     VERSION
6k3s-coredns-demo-4eed-ef4cb7-node-pool-eb1c-fuv8f   Ready    <none>   5m27s   v1.26.4+k3s1
7k3s-coredns-demo-4eed-ef4cb7-node-pool-eb1c-o9bkt   Ready    <none>   5m52s   v1.26.4+k3s1

Vérification de la configuration

Tout d'abord, analysons la configuration coredns. J'ai un déploiement actif, et en regardant de plus près, je vois 2 volumes utilisés pour sa configuration :

 1$ kubectl get deployments coredns -n kube-system
 2NAME      READY   UP-TO-DATE   AVAILABLE   AGE
 3coredns   1/1     1            1           3h25m
 4
 5$ kubectl describe deployments coredns -n kube-system
 6Name:                   coredns
 7Namespace:              kube-system
 8[..]
 9Pod Template:
10  [...]
11  Containers:
12   coredns:
13    [...]
14    Mounts:
15      /etc/coredns from config-volume (ro)
16      /etc/coredns/custom from custom-config-volume (ro)
17  Volumes:
18   config-volume:
19    Type:      ConfigMap (a volume populated by a ConfigMap)
20    Name:      coredns
21    Optional:  false
22   custom-config-volume:
23    Type:                       ConfigMap (a volume populated by a ConfigMap)
24    Name:                       coredns-custom
25    Optional:                   true
26[...]

Listons ces ConfigMaps :

1$ kubectl get configmap -n kube-system
2NAME                                 DATA   AGE
3[...]
4coredns                              2      3h28m
5[...]

Seule la ConfigMap par défaut est là, coredns-custom n'existe pas, il faudra donc la créer pour rajouter les infos. Dans la configuration par défaut, on retrouvera la Corefile ainsi que les NodeHosts dans le cas de Civo.

Création d'une entrée custom statique

Pour rajouter une entrée statique, on ne va surtout pas toucher à la configuration de base, qui pourrait se faire écraser lors d'un redéploiement. Si l'on regarde la ConfigMap coredns, on voit que la Corefile importe les fichiers présents dans /etc/coredns/custom/*.server (qui correspond au point de montage de la ConfigMap custom):

1$ kubectl get configmaps coredns -n kube-system -o yaml
2apiVersion: v1
3data:
4  Corefile: |
5    [...]
6    import /etc/coredns/custom/*.server
7[...]

Reste à créer la ConfigMap coredns-custom avec les entrées DNS souhaitées :

 1# Fichier coredns-custom.yaml
 2apiVersion: v1
 3kind: ConfigMap
 4metadata:
 5  name: coredns-custom
 6  namespace: kube-system
 7data:
 8  opsrel.server: |-
 9    # Include specific server zone
10    opsrel.io. {
11      errors
12      forward . /etc/resolv.conf
13      hosts {
14        74.220.17.133 myapp.opsrel.io.
15        fallthrough
16      }
17    }    
1$ kubectl apply -f coredns-custom.yaml -n kube-system

On redémarre coredns pour la prise en compte :

1$ kubectl rollout restart deployment coredns -n kube-system
2deployment.apps/coredns restarted

Validation des modifications

Maintenant, testons sur un pod simple que la résolution fonctionne :

1$ kubectl run debug --image=nginx
2$ kubectl exec -it debug  -- /bin/bash
3root@debug:/# apt-get update && apt-get install bind9-dnsutils -y
4root@debug:/# nslookup myapp.opsrel.io
5Server:         10.43.0.10
6Address:        10.43.0.10#53
7
8Name:   myapp.opsrel.io
9Address: 74.220.17.133

Je vérifie que j'ai pas tout cassé :

 1root@debug:/# nslookup opsrel.io
 2Server:         10.43.0.10
 3Address:        10.43.0.10#53
 4
 5Non-authoritative answer:
 6Name:   opsrel.io
 7Address: 213.186.33.5
 8
 9root@debug:/# nslookup metrics-server
10Server:         10.43.0.10
11Address:        10.43.0.10#53
12
13Name:   metrics-server.kube-system.svc.cluster.local
14Address: 10.43.123.103
15
16root@debug:/# nslookup www.debian.org 
17Server:         10.43.0.10
18Address:        10.43.0.10#53
19
20Non-authoritative answer:
21Name:   www.debian.org
22Address: 130.89.148.77
23Name:   www.debian.org
24Address: 2001:67c:2564:a119::77

Super ! J'ai mon entrée DNS statique qui fonctionne, je vais pouvoir continuer mes tests !