Installation et configuration¶
Ce chapitre couvre le déploiement de CoreDNS dans deux contextes : en standalone sur un serveur (via Podman) et comme cluster DNS Kubernetes.
Déploiement standalone avec Podman¶
Prerequis¶
| Composant | Version minimum | Vérification |
|---|---|---|
| Podman | 4.0+ | podman --version |
| Réseau | Port 53/UDP+TCP disponible | ss -ulnp \| grep :53 |
| Stockage | 100 Mo pour les fichiers de zone | df -h |
Structure des fichiers¶
/opt/coredns/
├── config/
│ └── Corefile # Configuration principale
└── zones/
├── db.internal.company.io # Zone racine interne
├── db.production.internal # Zone production
├── db.enterprise.internal # Zone entreprise
└── db.build.internal # Zone chaine logicielle
Configuration du Corefile¶
Le Corefile est le fichier de configuration central de CoreDNS. Chaque bloc définit une zone et les plugins a appliquer :
# /opt/coredns/config/Corefile
# Zone interne principale (autoritatif)
internal.company.io {
file /etc/coredns/zones/db.internal.company.io
log
errors
prometheus :9153
health :8080
ready :8181
cache 3600
}
# Zone production
production.internal.company.io {
file /etc/coredns/zones/db.production.internal
log
errors
cache 300
}
# Zone entreprise
enterprise.internal.company.io {
file /etc/coredns/zones/db.enterprise.internal
log
errors
cache 300
}
# Zone chaine logicielle
build.internal.company.io {
file /etc/coredns/zones/db.build.internal
log
errors
cache 300
}
# Tout le reste : forward vers DNS publics
. {
forward . 1.1.1.1 8.8.8.8 {
tls_servername cloudflare-dns.com
health_check 30s
}
log
errors
prometheus :9153
cache 600
}
Fichier de zone exemple¶
; /opt/coredns/zones/db.production.internal
$ORIGIN production.internal.company.io.
$TTL 300
@ IN SOA ns1.internal.company.io. admin.company.io. (
2026041601 ; Serial (YYYYMMDDNN)
3600 ; Refresh (1h)
900 ; Retry (15min)
604800 ; Expire (7 jours)
300 ; Negative cache TTL (5min)
)
; Serveurs de noms
IN NS ns1.internal.company.io.
IN NS ns2.internal.company.io.
; Services de production
app-api IN A 10.30.1.10
app-api IN AAAA fd00:30::1:10
app-frontend IN A 10.30.1.11
db-master IN A 10.30.2.10
db-replica IN A 10.30.2.11
cache-redis IN A 10.30.3.10
mq-rabbit IN A 10.30.3.20
; Alias
api IN CNAME app-api.production.internal.company.io.
frontend IN CNAME app-frontend.production.internal.company.io.
; Service discovery SRV
_http._tcp.app-api IN SRV 10 100 8080 app-api.production.internal.company.io.
_amqp._tcp.mq IN SRV 10 100 5672 mq-rabbit.production.internal.company.io.
Lancement avec Podman¶
# Telecharger l'image CoreDNS
podman pull docker.io/coredns/coredns:1.12
# Lancer le conteneur
podman run -d \
--name coredns \
--restart=always \
-p 53:53/udp \
-p 53:53/tcp \
-p 9153:9153/tcp \
-p 8080:8080/tcp \
-v /opt/coredns/config/Corefile:/etc/coredns/Corefile:ro,Z \
-v /opt/coredns/zones:/etc/coredns/zones:ro,Z \
docker.io/coredns/coredns:1.12 \
-conf /etc/coredns/Corefile
Vérification¶
# Verifier que le conteneur tourne
podman ps --filter name=coredns
# Tester la resolution d'un nom interne
dig @127.0.0.1 app-api.production.internal.company.io A +short
# Attendu : 10.30.1.10
# Tester la resolution d'un nom externe (forward)
dig @127.0.0.1 google.com A +short
# Verifier les metriques Prometheus
curl -s http://127.0.0.1:9153/metrics | head -20
# Verifier le health check
curl -s http://127.0.0.1:8080/health
# Attendu : OK
Service systemd¶
Pour que CoreDNS demarre automatiquement :
# Generer le fichier systemd
podman generate systemd --name coredns --new --files
# Installer le service (rootless)
mkdir -p ~/.config/systemd/user/
mv container-coredns.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now container-coredns.service
systemctl --user status container-coredns.service
# Permettre le demarrage sans session active
loginctl enable-linger $(whoami)
Port 53 et rootless
Le port 53 est un port privilegie (\<1024). En mode rootless, il faut soit utiliser sysctl net.ipv4.ip_unprivileged_port_start=53, soit mapper vers un port non privilegie (ex: 5353) et rediriger avec iptables/nftables.
Déploiement Kubernetes (cluster DNS)¶
CoreDNS est déployé par defaut dans les clusters Kubernetes. Cette section couvre la personnalisation.
ConfigMap CoreDNS¶
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
# Zones internes : forward vers le DNS interne standalone
forward internal.company.io 10.30.2.10 10.30.2.11 {
policy round_robin
health_check 10s
}
# Tout le reste : forward vers DNS publics
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
Application de la configuration¶
# Editer la ConfigMap
kubectl edit configmap coredns -n kube-system
# Ou appliquer depuis un fichier
kubectl apply -f coredns-configmap.yaml
# CoreDNS recharge automatiquement grace au plugin "reload"
# Verifier les logs pour confirmer
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=20
Zones personnalisees dans Kubernetes¶
Pour servir des zones internes directement depuis le CoreDNS du cluster :
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns-custom
namespace: kube-system
data:
custom.server: |
production.internal.company.io:53 {
file /etc/coredns/custom/db.production.internal
errors
cache 300
}
db.production.internal: |
$ORIGIN production.internal.company.io.
$TTL 300
@ IN SOA ns1.internal.company.io. admin.company.io. (
2026041601 3600 900 604800 300 )
IN NS ns1.internal.company.io.
app-api IN A 10.30.1.10
db-master IN A 10.30.2.10
CoreDNS cluster vs standalone
Dans une architecture avec un DNS standalone existant, preferez le forward depuis le CoreDNS Kubernetes vers le DNS standalone (première approche ci-dessus). Cela evite de dupliquer les zones et centralise la gestion des enregistrements.
Health checks et readiness¶
# Verifier que CoreDNS repond dans le cluster
kubectl run dns-test --rm -it --image=busybox:1.36 --restart=Never -- \
nslookup kubernetes.default.svc.cluster.local
# Verifier la resolution d'une zone interne
kubectl run dns-test --rm -it --image=busybox:1.36 --restart=Never -- \
nslookup app-api.production.internal.company.io
# Verifier les metriques CoreDNS
kubectl port-forward -n kube-system svc/kube-dns 9153:9153 &
curl -s http://127.0.0.1:9153/metrics | grep coredns_dns_requests_total
Recharger les zones sans redemarrage¶
CoreDNS supporte le rechargement a chaud des zones :
# Dans le Corefile, le plugin "reload" surveille les changements
production.internal.company.io {
file /etc/coredns/zones/db.production.internal
reload 30s # Verifier les changements toutes les 30 secondes
log
errors
cache 300
}
Pour forcer un rechargement immédiat, incrementer le serial dans le fichier de zone et CoreDNS detectera le changement au prochain cycle de reload.
Upstream forwarding securise¶
Pour forwarder vers les DNS publics en DNS-over-TLS :
. {
forward . tls://1.1.1.1 tls://1.0.0.1 {
tls_servername cloudflare-dns.com
health_check 30s
}
cache 600
}
Choix du resolver upstream
Pour un DNS interne d'entreprise, le forward vers les DNS publics devrait passer par un resolver intermédiaire controlable (ex: Unbound local) plutôt que directement vers Cloudflare ou Google. Cela permet de journaliser et filtrer les requêtes sortantes.