GH GambleHub

Service Discovery и DNS

Service Discovery и DNS

1) Зачем это нужно

В распределенных системах узлы появляются и исчезают, а клиенты должны находить рабочие экземпляры сервиса быстро и надежно. DNS — универсальный слой имен; service discovery — стратегия сопоставления имени сервиса реальным эндпойнтам с учетом здоровья, веса и политики маршрутизации.

Ключевые цели:
  • стабильные имена вместо эфемерных адресов,
  • точный, но не шумный апдейт (баланс между свежестью и TTL),
  • деградация без полного падения (failover/health-check),
  • минимум «догадок» на клиенте: таймауты, ретраи, кэш-политики.

2) Модели service discovery

2.1 Клиентская (client-side)

Клиент сам разрешает имя в набор эндпойнтов и балансирует (round-robin, EWMA, хеш по ключу). Источник — DNS (A/AAAA/SRV), сервис-реестр (Consul/Eureka), статический список.

Плюсы: меньше центральных SPOF, гибкие алгоритмы.
Минусы: неоднородность клиентов, сложнее обновлять логику.

2.2 Серверная (server-side)

Клиент идет на front/LB (L4/L7, gateway/ingress). Балансировка и health-checking — на стороне прокси/балансировщика.

Плюсы: единое место политики, наблюдаемость.
Минусы: нужен высокодоступный периметр (N+1, multi-AZ).

2.3 Гибрид

DNS дает набор точек входа (региональные LB), дальше — балансировка на L7/mesh.

3) DNS: основы, записи и TTL

3.1 Базовые типы

A/AAAA — IPv4/IPv6 адреса.
CNAME — алиас на другое имя (не на apex).
SRV — `_service._proto.name` → хост/порт/вес/приоритет (для gRPC/LDAP/SIP и пр.).
TXT/HTTP/HTTPS — метаданные/указатели (в т.ч. для HTTP-discovery).
NS/SOA — делегирование и атрибуты зоны.

3.2 TTL и кэш-каскад

Кэш есть у: резолвера ОС, локального stub-резолвера, узлов (NodeLocal DNS/CoreDNS), провайдера, промежуточных рекурсоров и у клиента библиотеки. Фактическая свежесть = min(TTL, политика клиента). Негативный кэш (NXDOMAIN) тоже кэшируется по `SOA.MINIMUM`/`TTL`.

Рекомендации:
  • Прод — TTL 30–120s для динамичных записей, 300–600s для стабильных.
  • Для переключений (фейловер) готовьте пониженный TTL заранее, а не «во время пожара».
  • Учитывайте sticky-кэш библиотек (Java/Go/Node) — при необходимости настраивайте TTL резолвера внутри рантайма.

4) Политики DNS-балансировки и отказоустойчивости

Weighted RR — веса на A/AAAA/SRV.
Failover — первичный/вторичный наборы (health-check снаружи).
Geo/Latency — ответ на «ближайшую» POP/регион.
Anycast — один IP в разных POP (BGP); устойчиво к региональным сбоям.
Split-horizon — разные ответы внутри VPC/он-прем и в интернете.
GSLB — глобальный балансировщик с health-проверками и политиками (latency, гео, capacity).

5) Health-checks и свежесть

DNS сам по себе «тупой»: он не знает здоровья бэкендов. Поэтому:
  • Либо внешний health-checker управляет записями/весами (GSLB, Route53/Traffic-policy, external-dns + пробы).
  • Либо клиент/mesh делает активный outlier-ejection и retry из множества эндпойнтов.

6) Kubernetes: discovery из коробки

Сервисные имена: `svc.namespace.svc.cluster.local`.
ClusterIP: стабильный виртуальный IP + kube-proxy/ebpf.
Headless Service (`clusterIP: None`): отдает A-записи на pod’ы (или их поддомен), SRV для портов.
EndpointSlice: масштабируемый список эндпойнтов (замена Endpoints).
CoreDNS: DNS-резолвер кластера; плагины rewrite/template/forward/cache; `kube-dns` зону.
NodeLocal DNSCache: локальный кэш на узле → меньше latency и перехват проблем апстрим-резолвера.

Пример: 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

Клиент может резолвить `_grpc._tcp.payments.prod.svc.cluster.local` (SRV) и получить хост/порт/веса.

CoreDNS (фрагмент ConfigMap)

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 (идеи):
  • DaemonSet с локальным резолвером на `169.254.20.10`; kubelet указывает эту точку.
  • Снижает p99 name-resolution и защищает от «флапа» апстрим-DNS.

7) Service discovery вне K8s

Consul: агент, health-checks, сервис-каталог, DNS-интерфейс (`.consul`), KV для конфигов.
Eureka/ZooKeeper/etcd: реестры для JVM/legacy; часто в связке с sidecar/шлюзом.
Envoy/Istio: EDS/xDS (Endpoint Discovery) и SDS (секреты); сервисы объявляются через control-plane.

8) Безопасность DNS

DNSSEC: защита целостности записей (подпись зон). Критично для публичных доменов.
DoT/DoH: шифрование канала к рекурсору (внутренние политики, совместимость).
ACL и split-horizon: приватная зона — только из VPC/VPN.
Защита от кеш-отравления: рандомизация портов/ID, короткие TTL для динамики.
Политики на egress: разрешайте DNS только на доверенные резолверы, журналируйте.

9) Поведение клиентов и ретраи

Уважайте TTL: не кэшируйте бесконечно, не «беспределите» частыми резолвами (шторм к рекурсору).
Happy Eyeballs (IPv4/IPv6), параллельные коннекты к нескольким A/AAAA уменьшают tail.
Ретраи только при идемпотентных запросах; джиттер, ограничение budget ретраев.

Тонкая настройка резолвера рантайма:
  • 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/DNS-переключения: практика

Снизьте TTL с 300→60 за 24–48 часов до планового переключения.
Держите канареечный набор эндпойнтов с малым весом для валидации.
Применяйте weighted + health-check вместо ручного массового апдейта A-записей.
Для статики/edge — Anycast; для API — Geo/Latency + быстрый L7-фейловер.

11) Наблюдаемость и SLO для имени

Метрики:
  • Rate/latency DNS-запросов, cache hit-ratio, ошибки по типам (SERVFAIL/NXDOMAIN).
  • Доля запросов с stale-ответами (если используете stale-cache).
  • Успех пользовательских операций при сменах записей (бизнес-SLI).
  • p95/p99 resolve-time в приложениях.
Диагностика:
  • Расслойте путь: клиент → локальный кэш → нодовый кэш → кластерный резолвер → рекурсор провайдера.
  • Отслеживайте всплески NXDOMAIN (ошибки имен/опечатки) и SERVFAIL (проблемы рекурсора/ресурс-лимиты).

12) Примеры конфигураций

CoreDNS: rewrite и stub-зона

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 (форс локального резолвера)

ini
[Resolve]
DNS=169. 254. 20. 10
FallbackDNS=1. 1. 1. 1 8. 8. 8. 8
Domains=~cluster. local ~internal
DNSSEC=yes

Envoy: динамический DNS-refresh

yaml dns_refresh_rate: 5s dns_failure_refresh_rate:
base_interval: 2s max_interval: 30s respect_dns_ttl: true

external-dns (поддержка публичной зоны)

yaml args:
- --source=service
- --source=ingress
- --domain-filter=example. com
- --policy=upsert-only
- --txt-owner-id=cluster-prod

13) Чек-лист внедрения (0–30 дней)

0–7 дней

Каталог имен сервисов, выбор модели (client-/server-side/гибрид).
Базовые TTL, включить NodeLocal DNSCache, дашборды DNS-метрик.
Запрет «жестких IP» в конфиге/коде.

8–20 дней

Headless-сервисы + SRV для gRPC; EndpointSlice включен.
GSLB/weighted для внешних; health-checks и канарейка.
Настроены таймауты/ретраи клиентов и бюджет ретраев.

21–30 дней

Split-horizon и приватные зоны; DoT/DoH по политике.
Тест переключений (по TTL) и фейловера; пост-анализ.
Политики mesh/EDS, outlier-ejection включены.

14) Анти-паттерны

TTL = 0 в проде → шторм к рекурсорам, непредсказуемые задержки.
Хардкод IP/портов, отсутствие CNAME/алиасов для уровней.
Смена записей «вручную» без health-checks и канареек.
Один глобальный резолвер без кэша на узлах (узкое место).
Игнорирование негативного кэша (всплески NXDOMAIN).
Попытки «лечить» отказ БД через DNS вместо уровня данных/фейловера.

15) Метрики зрелости

100% сервисов используют имена; нулевые случаи hard-IP.
CoreDNS/NodeLocal в проде, cache hit-ratio > 90% на узлах.
GSLB с health-checks, документированные TTL и runbook переключений.
SRV/EndpointSlice для stateful/gRPC, p99 resolve-time в приложениях ≤ 20–30 мс.
Алерты по SERVFAIL/NXDOMAIN и деградации cache hit-ratio.
Проверки в CI: запрет `:latest` и hard-IP в чартах/конфигах.

16) Заключение

Service discovery — это договор о стабильном имени и дисциплина кэша. Стройте гибридную модель: DNS дает быстрый и простой вход, L7/mesh — здоровье и умные политики. Поддерживайте разумные TTL, кэш на узлах, headless-сервисы и SRV там, где нужно, используйте GSLB/Anycast для границ регионов, следите за NXDOMAIN/SERVFAIL и p99 resolve-time. Тогда ваше имя будет таким же надежным активом, как и сам сервис.

Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

Нажимая кнопку, вы соглашаетесь на обработку данных.