Настройка Service Discovery в Kubernetes: CoreDNS и Headless Services

После релиза сервисы перестают находить друг друга, и ручные правки адресов тормозят выпуск. Мы настраиваем обнаружение сервисов в Kubernetes под ключ: проектируем схему, готовим конфигурации, проверяем отказоустойчивость. Результат — предсказуемая связность и меньше срочных доработок.
Часто задаваемые вопросы

Service Discovery в Kubernetes: где рвётся связность

Поды запущены, readiness-пробы зелёные, но сервис не собирается: один участник получает ошибку разрешения имени, другой стучится в адрес, которого уже нет. Service Discovery в Kubernetes ломается не целиком, а частично — часть вызовов проходит, часть висит до таймаута.

Первый класс сбоев — отказ слоя имён. CoreDNS не отвечает, когда упирается в лимиты ресурсов, теряет связь с API-сервером или остаётся в единственном экземпляре после вытеснения подов. В логах приложения это выглядит как всплеск ошибок разрешения имён, хотя сам сервис жив и отвечает по прямому адресу.

Второй класс — устаревшие адреса подов. Клиент держит ответ в кеше на время TTL, под за это время пересоздался и получил новый адрес: трафик уходит в никуда, а соединение висит до таймаута. У headless-сервисов то же самое заметнее — балансировку клиент делает сам по списку точек, который успел устареть.

Третий класс — расхождение в конфигурации: селектор не совпал с метками подов, порт в сервисе и в контейнере разошлись, проверка готовности пропускает ещё не поднявшееся приложение. Endpoints в таком случае пусты не из-за сети, а потому что сервис никого не выбрал.

Цена у всех трёх одна: неполные отказы, которые не ловятся алертами по инфраструктуре, зато видны в доле ошибок у пользователя. Ниже разбираем, как это закрывается.

Что даёт настройка: скорость выпуска и устранённые отказы

Пока адреса сервисов живут в конфигурациях приложений и переменных окружения, любое пересоздание подов превращается в ручную сверку: адреса сменились, клиенты держат устаревшие значения и продолжают ходить в никуда. Управляемое обнаружение убирает сам повод для этой работы — приложение обращается к сервису по имени, а не по конкретному адресу.

Что происходит на уровне инфраструктуры: CoreDNS отдаёт стабильные имена для обычных сервисов, а headless-режим даёт фиксированную точку входа с прямым перечислением адресов для наборов, где каждый экземпляр адресуется отдельно. При замене подов меняется только содержимое записей — имена и точки подключения остаются теми же, поэтому конфигурации приложений и балансировщиков больше не переписываются под каждый выпуск.

Ключевой эффект виден в двух метриках. Время выпуска релиза сокращается с часов до десятков минут, потому что из процесса уходит этап «обновить адреса и проверить, что ничего не забыли» — он выполнялся вручную и был самым частым источником задержек. Доля правок конфигураций, вносимых руками, падает почти до нуля: остаются только осмысленные изменения, а не реакция на смену адресов.

Отдельно уходит целый класс отказов. Раньше после планового пересоздания подов приложение отдавало ошибки соединения или отвечало частично — часть экземпляров уже поднялась, а клиенты ещё держали старые адреса. Теперь устаревшая запись истекает по времени жизни, и трафик переключается на живые экземпляры. Это напрямую влияет на доступность: пересоздание подов становится рутинной операцией, а не событием с риском деградации.

Режимы обнаружения: DNS-записи, headless-режим, внешние реестры

Обнаружение внутри кластера решает одну задачу — дать сервису найти соседа, не зашивая его адрес в конфигурацию. Способов несколько, и они не взаимозаменяемы: обычная dns-запись, headless-режим с прямым списком адресов и внешний реестр для сервисов за пределами кластера. Выбор зависит от того, кто держит балансировку — платформа или клиент.

Вариант Когда подходит Ограничения
Обычная dns-запись сервиса Много коротких запросов, клиенту не важен конкретный экземпляр Балансирует платформа; клиентский кэш DNS сглаживает перестроения с задержкой
Headless-режим Наборы с состоянием, БД, брокеры, долгие соединения Клиент сам обходит список; нужна своя балансировка на стороне клиента
Внешний реестр Сервисы вне кластера, несколько сред, единый каталог Отдельный контур со своими отказами; синхронизацию надо сопровождать
Статические адреса Аварийный контур, единичные зависимости Упавший узел не исключается автоматически, замена — ручная правка

В headless-режиме CoreDNS отдаёт по dns-запросу полный список адресов, и балансировкой занимается клиент. Это осознанный обмен: платформа перестаёт быть посредником и точкой отказа, но клиент должен уметь повторить запрос при смене состава. Поэтому на headless мы переводим только те сервисы, где нужен прямой доступ к конкретному экземпляру, а статические адреса оставляем для аварийных сценариев.

Этапы работ: аудит, схема, настройка, проверка, передача

Работы идут от разбора текущей топологии до передачи регламентов команде заказчика, без остановки боевого контура. Порядок выстроен так, что каждый этап даёт проверяемый результат и служит входом для следующего.

  1. Аудит кластера — собираем карту сервисов и неймспейсов, смотрим, как сейчас разрешаются имена, где остались ручные записи и какие сетевые политики режут DNS-трафик. Отдельно фиксируем точки отказа: одна реплика CoreDNS, отсутствие кэша, жёсткие таймауты в клиентах.
  2. Схема обнаружения — решаем, где достаточно обычного сервиса, а где нужен headless для прямого доступа к подам. Определяем зоны, правила пересылки и то, что уходит во внешний DNS.
  3. Настройка CoreDNS — правим конфигурацию под эту схему: зоны, пересылка, кэш, лимиты, пробы готовности. Реплики разносятся по узлам и зонам доступности, чтобы отказ одного не ронял разрешение имён.
  4. Проверка отказоустойчивости — гасим реплику и узел с ней, смотрим, сохраняется ли резолв и как клиенты переживают задержку ответа. Отдельно прогоняем headless-сервисы и обновление списка эндпоинтов.
  5. Наблюдаемость — выводим метрики запросов, отказов и времени ответа, задаём пороги для дежурного, чтобы деградация была видна раньше жалоб.
  6. Передача в эксплуатацию — схема, регламенты и порядок типовых операций: как подключить новый сервис, как откатить изменение, что проверять первым при сбое.

Комплект поставки: конфигурации, схемы, регламенты

Результат проекта — не только работающий кластер, но и набор артефактов, по которым ваша команда ведёт его дальше сама. Всё складывается в ваш репозиторий и передаётся с пояснениями: что за что отвечает, где меняется и как откатывается. Ниже — что именно остаётся у заказчика после сдачи.

  • Рабочие конфигурации: манифесты и ConfigMap для CoreDNS, headless-сервисов и связанных объектов — в вашей системе контроля версий, с историей изменений.
  • Схема топологии обнаружения: как сервисы находят друг друга, какие записи создаются под StatefulSet, как разрешаются имена внутри кластера и снаружи.
  • Политики доступа: RBAC-роли, NetworkPolicy и ограничения на правку зоны — кто и из каких пространств имён может читать и изменять записи.
  • Диаграмма отказоустойчивости: число реплик, распределение по узлам, поведение при потере узла или зоны.
  • Регламент эксплуатации: типовые операции — подключение сервиса, смена зоны, ротация сертификатов — с точками проверки и порядком отката.
  • Набор проверок: метрики и скрипты контроля разрешения имён, задержки ответов и доли ошибок, с порогами для дежурного.
  • Документация: описание схемы, принятых решений и известных ограничений — чтобы новый инженер входил в контур без устных пояснений.

Кейс: как убрали ручные правки адресов после релиза

Что было Платформа из нескольких десятков сервисов на Kubernetes держала связность на адресах, прописанных руками. Перед каждым релизом инженер собирал актуальный список подов и переносил адреса в конфигурации зависимых сервисов — 25-40 минут на синхронизацию и постоянный риск, что часть списка устареет между правкой и выкаткой.

Дороже обходилось внеплановое пересоздание подов: на новых узлах адреса менялись, а клиенты продолжали обращаться по старым записям. Сервис отдавал ошибки 5-8 минут, пока дежурный не находил устаревший адрес. За квартал таких разборов набралось одиннадцать, каждый — с частичной недоступностью для пользователей.

Что изменили Причина была не в числе сервисов, а в статичных адресах как способе связи. Ввели CoreDNS штатным сервером имён кластера и headless Services для сервисов с несколькими экземплярами: служба отдаёт список адресов всех живых подов, а клиент выбирает доступный. Обращения между сервисами перевели на имена, для долгоживущих соединений настроили периодическое перечитывание списка — иначе клиент держал бы старый адрес до собственного перезапуска.

Что стало Синхронизация адресов исчезла как отдельный этап: время на правки при релизе — ноль, изменения подхватываются вместе с состоянием кластера. Связность после аварийного пересоздания подов восстанавливается за 10-20 секунд вместо 5-8 минут простоя, а инцидентов из-за устаревших адресов за сопоставимый период не было ни одного. Замеры снимали по журналам отказов и времени реакции дежурного.

Что делать, если в Kubernetes уже развёрнут CoreDNS?

Развёрнутый CoreDNS — не повод перестраивать кластер: это рабочий компонент, который меняют на месте, без остановки сервисов. Главное правило — не трогать имя сервиса kube-dns и его адрес внутри кластера. Манифесты приложений обращаются именно к нему, поэтому схему обнаружения можно менять под капотом, пока внешний контракт резолвинга остаётся прежним.

Порядок изменений строится от чтения к записи. Сначала снимаем текущую конфигурацию Corefile и фиксируем, какие зоны, плагины и вышестоящие резолверы в ней задействованы, — это точка отката. Затем правим копию в ConfigMap, не применяя её к рабочему контуру, и проверяем из тестового пространства имён: резолв внутренних и внешних имён, поведение search-доменов и параметра ndots.

Отдельный шаг — headless-сервисы. Перевод обычного сервиса в headless меняет только запись в манифесте: вместо одного адреса клиент получает набор адресов подов, а имя остаётся тем же. Приложения, которые ходят по имени сервиса, продолжают работать без правок, если сохраняются прежние search-домены и порядок резолвинга.

Обновление делаем через последовательную замену подов: минимум две реплики, проверка готовности перед выводом следующего, перезагрузка конфигурации без перезапуска. На любом шаге часть подов отвечает по старой схеме, часть — по новой, и запросы не теряются.

После переключения сверяем долю ответов из кеша, число отказов SERVFAIL и полноту списков адресов у headless-сервисов. Откат — возврат прежней конфигурации и перезагрузка, по времени он сравним с прямым изменением.

Технические сомнения: кэш, таймауты, ограничения режимов

Кэширование записей — первый вопрос, который всплывает, когда сервис после переезда пода продолжает обращаться по старому адресу. У записи есть срок жизни, и клиент держит её до истечения таймаута — это не сбой кластера, а ожидаемое поведение.

Второе возражение — таймауты при недоступности узла: помогают проверки готовности, разнесение реплик по зонам и бюджет прерываний. Узел выводится из работы только после того, как его перестали опрашивать.

Кэш держит старый адрес после переноса пода — что делают?

Кэш лечить не нужно: сокращаем срок жизни записи для нестабильных сервисов, чтобы обновление списка адресов успевало за переездом. Добавляем проверку готовности на стороне клиента — он не шлёт трафик в неготовый под.

Что будет, если узел с DNS-репликами выпадет?

Ничего катастрофичного: реплики CoreDNS разнесены по узлам и зонам, клиент переспрашивает следующий адрес из списка. Часть запросов теряется только на время переключения — интервал закрываем алертами и проверками.

Headless отдаёт список адресов без балансировки — в чём ограничение?

Виртуального адреса и распределения трафика здесь нет: клиент получает адреса подов напрямую. Кластерам баз данных это и нужно, а обычному приложению балансировку придётся делать на стороне клиента.

Эти сюжеты закрываются на этапе проектирования: срок жизни записи, разнесение реплик, режим сервиса. Ниже — остальные вопросы, которые всплывают при передаче конфигураций.

Обсудим вашу задачу: с чего начнём

Чтобы оценка была предметной, а не «на глаз», начнём с описания вашей топологии: сколько кластеров и сред, как разбиты пространства имён, кто и по каким именам обращается к сервисам, что уже пробовали и какие симптомы остались. Формат не важен — текст, схема или вывод диагностических команд.

В ответ вернём не общие соображения, а разбор: где именно рвётся разрешение имён, какие изменения нужны и в каком порядке их выкатывать. Ниже — что уточним в первую очередь и что войдёт в план работ.

  • Границы задачи: разрешение имён только внутри кластера или ещё доступ из внешних сетей и соседних кластеров.
  • Вопросы по топологии: число сред, разбиение на пространства имён, свои серверы имён и зоны под вашим контролем.
  • Текущее состояние: службы без балансировщика, режим локального обращения к узлу, записи, которые правятся вручную.
  • Что уже проверяли: время ответа на запрос имени, доля отказов, поведение при перезапуске узлов и смене настроек.
  • Оценка работ: перечень правок в конфигурации, объём изменений, трудозатраты и порядок выката по средам.
  • План внедрения: этапы, точки отката и проверки того, что старые имена продолжают работать после перехода.
  • Эксплуатация после запуска: правила именования, наблюдение и оповещения, документация и передача вашей команде.

Опишите задачу в свободной форме — вернёмся с оценкой и планом внедрения. Если удобнее голосом, созвонимся с инженером и разберём вашу схему вместе.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1142