Service Discovery и DNS
Service Discovery и DNS
1) Pourquoi est-ce nécessaire
Dans les systèmes distribués, les nœuds apparaissent et disparaissent, et les clients doivent trouver des instances de travail du service rapidement et en toute sécurité. DNS - couche universelle de noms ; service discovery est une stratégie de mise en correspondance du nom du service avec les endpoints réels en tenant compte de la santé, du poids et de la politique de routage.
Objectifs clés :- noms stables au lieu d'adresses éphémères,
- une mise à jour précise mais non bruyante (équilibre entre fraîcheur et TTL),
- dégradation sans chute totale (failover/health-check),
- minimum de « suppositions » sur le client : timeouts, retraits, politiques de cache.
2) Modèles de service discovery
2. 1 Client (client-side)
Le client lui-même autorise le nom dans le jeu d'endpoints et équilibre (round-robin, EWMA, hachage par clé). La source est DNS (A/AAAA/SRV), service-registre (Consul/Eureka), liste statique.
Avantages : Moins de SPOF central, algorithmes flexibles.
Inconvénients : hétérogénéité des clients, plus difficile de mettre à jour la logique.
2. 2 serveur (server-side)
Le client passe sur front/LB (L4/L7, gateway/ingress). Équilibrage et santé-checking - côté proxy/équilibreur.
Avantages : un lieu de politique unique, l'observabilité.
Inconvénients : besoin d'un périmètre très accessible (N + 1, multi-AZ).
2. 3 Hybride
DNS donne un ensemble de points d'entrée (LB régionaux), puis l'équilibre par L7/mesh.
3) DNS : bases, enregistrements et TTL
3. 1 Types de base
A/AAAA - Adresses IPv4/IPv6.
CNAME est alias sur un autre nom (pas sur apex).
SRV — `_service._proto. name '→ hôte/port/poids/priorité (pour gRPC/LDAP/SIP, etc.).
TXT/HTTP/HTTPS - métadonnées/pointeurs (y compris pour HTTP-discovery).
NS/SOA - Délégation et attributs de zone.
3. 2 TTL et cascade cache
Le cache a : résolver OS, stub-resolver local, nœuds (NodeLocal DNS/CoreDNS), fournisseur, récursifs intermédiaires et client de bibliothèque. Fraîcheur réelle = min (TTL, politique client). Le cache négatif (NXDOMAIN) est également mis en cache par 'SOA'. MINIMUM`/`TTL`.
Recommandations :- Prod - TTL 30-120s pour les enregistrements dynamiques, 300-600s pour les enregistrements stables.
- Pour les commutations (faussaire), préparer la TTL réduite à l'avance, et non « pendant l'incendie ».
- Tenez compte du cache sticky des bibliothèques (Java/Go/Node) - configurez le résolver TTL à l'intérieur du rantame si nécessaire.
4) Politiques d'équilibrage DNS et de tolérance aux pannes
Weighted RR - poids sur A/AAAA/SRV.
Failover - kits primaires/secondaires (health-check à l'extérieur).
Geo/Latency est la réponse à la RR/région « proche ».
Anycast - une IP dans différents POP (BGP) ; résistant aux perturbations régionales.
Split-horizon - différentes réponses à l'intérieur de VPC/on-est et sur Internet.
La GSLB est un équilibreur mondial avec des contrôles et des politiques de santé (latitude, géo, capacity).
5) La santé et la fraîcheur
Le DNS lui-même est « stupide » : il ne connaît pas la santé des backends. C'est pourquoi :- Soit un vérificateur de santé externe gère les enregistrements/poids (GSLB, Route53/Traffic-policy, external-dns + échantillons).
- Soit le client/mesh fait l'outlier-ejection active et retry à partir de nombreux endpoints.
6) Kubernetes : découverte de l'emballage
Noms de service : 'svc. namespace. svc. cluster. local`.
ClusterIP : IP virtuel stable + kube-proxy/ebpf.
Headless Service ('clusterIP : None') : donne les enregistrements A aux pod's (ou leurs sous-domaines), SRV pour les ports.
EndpointSlice : liste évolutive des endpoints (remplacement des endpoints).
CoreDNS : Résolver DNS du cluster ; plugins rewrite/template/forward/cache ; 'kube-dns' zone.
NodeLocal DNSCache : cache local sur le nœud → moins de latency et intercepte les problèmes d'apstream-resolver.
Exemple : Headless + SRV
yaml apiVersion: v1 kind: Service metadata: { name: payments, namespace: prod }
spec:
clusterIP: None selector: { app: payments }
ports:
- name: grpc port: 50051 targetPort: 50051
Le client peut résonner '_ grpc. _ tcp. payments. prod. svc. cluster. local '(SRV) et obtenir l'hôte/port/poids.
CoreDNS (fragment BouMap)
yaml apiVersion: v1 kind: ConfigMap metadata: { name: coredns, namespace: kube-system }
data:
Corefile:
.:53 {
errors health ready cache 30 loop forward. /etc/resolv. conf prometheus:9153 reload
}
NodeLocal DNS (idées) :
- DaemonSet avec résolver local sur '169. 254. 20. 10`; kubelet indique ce point.
- Réduit p99 name-resolution et protège contre « flap » apstream-DNS.
7) Service discovery вне K8s
Consul : agent, health-checks, service-annuaire, interface DNS ('.consul'), KV pour configues.
Eureka/ZooKeeper/etcd : registres pour JVM/legacy ; souvent en liaison avec un sidecar/passerelle.
Envoy/Istio : EDS/xDS (Endpoint Discovery) et SDS (secrets) ; les services sont déclarés via control-plane.
8) Sécurité DNS
DNSSEC : protection de l'intégrité des enregistrements (signature des zones). Critique pour les domaines publics.
DoT/DoH : chiffrement du canal vers le récurseur (politiques internes, interopérabilité).
ACL et split-horizon : zone privée - uniquement à partir de VPC/VPN.
Protection contre l'empoisonnement au cache : randomisation des ports/ID, TTL court pour dynamique.
Politiques sur egress : résolvez uniquement DNS sur des résolveurs de confiance, journalisez.
9) Comportement des clients et retraits
Respecter la TTL : ne pas mettre en cache indéfiniment, ne pas « se désintéresser » avec des résolves fréquentes (tempête vers le récurseur).
Happy Eyeballs (IPv4/IPv6), connexions parallèles à plusieurs A/AAAA réduisent le tail.
Retrai uniquement sur les demandes idempotentes ; jitter, limitation du budget des retraits.
- Java: `networkaddress. cache. ttl`, `networkaddress. cache. negative. ttl`.
- Go: `GODEBUG=netdns=go`/`cgo`, `Resolver. PreferGo`, `DialTimeout`.
- Node: `dns. setDefaultResultOrder('ipv4first')`, `lookup` с `all:true`.
10) GSLB/commutation DNS : pratique
Réduisez le TTL de 300→60 24 à 48 heures avant le changement planifié.
Tenez un ensemble canarien d'endpoints de faible poids pour la validation.
Appliquez weighted + health-check au lieu de l'update de masse manuelle des enregistrements A.
Pour statique/edge - Anycast ; pour l'API - Geo/Latency + rapide L7-feelover.
11) Observabilité et SLO pour le nom
Métriques :- Requêtes DNS rate/latency, cache hit-ratio, erreurs par type (SERVFAIL/NXDOMAIN).
- Proportion de demandes avec des réponses stales (si vous utilisez stale-cache).
- Succès des opérations utilisateur lors des changements d'enregistrement (SLI).
- p95/p99 resolve-time dans les applications.
- Dissociez le chemin : le client → le cache local → le cache nodal → le résolver de cluster → le récurseur du fournisseur.
- Surveillez les surtensions NXDOMAIN (erreurs de noms/erreurs typographiques) et SERVFAIL (problèmes récursifs/ressources-limites).
12) Exemples de configurations
CoreDNS : rewrite et stub-zone
yaml
.:53 {
log errors cache 60 rewrite name suffix. svc. cluster. local. svc. cluster. local forward. 10. 0. 0. 2 10. 0. 0. 3
}
example. internal:53 {
file /zones/example. internal. signed dnssec
}
systemd-resolved (force de résolver locale)
ini
[Resolve]
DNS=169. 254. 20. 10
FallbackDNS=1. 1. 1. 1 8. 8. 8. 8
Domains=~cluster. local ~internal
DNSSEC=yes
Envoy : dynamique DNS-refresh
yaml dns_refresh_rate: 5s dns_failure_refresh_rate:
base_interval: 2s max_interval: 30s respect_dns_ttl: true
external-dns (prise en charge de l'espace public)
yaml args:
- --source=service
- --source=ingress
- --domain-filter=example. com
- --policy=upsert-only
- --txt-owner-id=cluster-prod
13) Chèque de mise en œuvre (0-30 jours)
0-7 jours
Répertoire des noms des services, sélection du modèle (client/server-side/hybride).
TTL de base, activer NodeLocal DNSCache, dashboards de métriques DNS.
Interdiction des "IP durs'dans le config/code.
8-20 jours
Services headless + SRV pour gRPC ; EndpointSlice est inclus.
GSLB/weighted pour l'extérieur ; checks de santé et canaris.
Les délais/retraits des clients et le budget des retraits ont été configurés.
21-30 jours
Split-horizon et zones privées ; DoT/DoH sur la politique.
Test des commutations (par TTL) et du faussaire ; post-analyse.
Stratégies mesh/EDS, outlier-ejection incluses.
14) Anti-modèles
TTL = 0 dans la vente → tempête aux récursifs, retards imprévisibles.
IP/ports hardcode, pas de CNAME/alias pour les niveaux.
Changez les entrées « manuellement » sans checks de santé et canaries.
Un résolver global sans cache sur les nœuds (goulot d'étranglement).
Ignorer le cache négatif (surtensions NXDOMAIN).
Tentatives de « traiter » une défaillance OBD via DNS au lieu de la couche de données/faussaire.
15) Métriques de maturité
100 % des services utilisent des noms ; zéro cas hard-IP.
CoreDNS/NodeLocal dans la vente, cache hit-ratio> 90 % sur les nœuds.
GSLB avec des tests de santé documentés par TTL et runbook de commutation.
SRV/EndpointSlice pour stateful/gRPC, p99 resolve-time dans les applications ≤ 20-30 ms.
Alerte par SERVFAIL/NXDOMAIN et dégradation cache hit-ratio.
Contrôles à CI : interdiction de ': latest' et hard-IP dans les charts/configs.
16) Conclusion
Service discovery est un contrat de nom stable et une discipline de cache. Construisez un modèle hybride : DNS donne une entrée rapide et facile, L7/mesh - santé et politiques intelligentes. Prenez en charge les TTL raisonnables, le cache sur les nœuds, les services headless et SRV là où vous voulez, utilisez GSLB/Anycast pour les limites des régions, surveillez NXDOMAIN/SERVFAIL et p99 resolve-time. Votre nom sera alors un atout aussi fiable que le service lui-même.