Часть подов продолжает обращаться к старому IP после смены записи DNS. Какой механизм объясняет такое поведение?
Такое поведение обычно объясняется кэшированием DNS-ответа. Рекурсивный DNS-резолвер, операционная система или само приложение сохраняют старый IP на время, заданное TTL, поэтому разные поды могут временно получать разные результаты.
DNS-кэширование появилось как способ снизить задержку разрешения имён и нагрузку на авторитетные DNS-серверы. Без кэша каждый запрос к имени проходил бы до сервера, владеющего соответствующей DNS-зоной.
TTL позволяет владельцу зоны указать, как долго промежуточные системы могут считать ответ актуальным. Это компромисс между скоростью и количеством DNS-запросов с одной стороны и быстротой распространения изменений с другой.
При изменении IP-адреса часть клиентов уже видит новый адрес, а часть продолжает использовать старый. В результате трафик может распределяться между старой и новой инфраструктурой, а при отключении старого адреса часть запросов начнёт завершаться ошибками.
Снижение TTL непосредственно перед изменением не гарантирует мгновенное обновление: прежний ответ уже мог быть закэширован на старое время. Кроме того, DNS-кэш может существовать одновременно на нескольких уровнях — у рекурсивного резолвера, на узле, в библиотеке и внутри приложения.
Когда клиент запрашивает имя, рекурсивный резолвер сначала проверяет собственный кэш. Если там есть действительный ответ, он возвращает его без обращения к авторитетному серверу. Время жизни записи уменьшается по мере хранения; после истечения TTL резолвер должен получить свежий ответ.
В Kubernetes поды обычно используют кластерный DNS-резолвер. Однако сам процесс приложения может дополнительно кэшировать результат, а уже установленное TCP-соединение продолжит использовать прежний IP независимо от последующего DNS-разрешения.
TTL задаёт допустимое время кэширования, но не является механизмом принудительной очистки всех кэшей. Поэтому переключение адресов проектируют с учётом периода сосуществования старой и новой инфраструктуры: старый адрес некоторое время оставляют работоспособным, а приложения делают устойчивыми к повторному разрешению имени и временным ошибкам.
Слишком маленький TTL ускоряет распространение изменений, но увеличивает число DNS-запросов, нагрузку на резолверы и зависимость от доступности DNS. Слишком большой TTL уменьшает эту нагрузку, зато усложняет аварийное переключение и миграции.
Для критичных переключений полезно заранее уменьшить TTL, проверить фактическое поведение клиентов и резолверов, обеспечить перекрытие старой и новой точек доступа и только затем отключать старый адрес. Важно также различать DNS-балансировку и балансировку уже установленных соединений: изменение записи не переводит существующие соединения автоматически.
Компания переносила API на новый балансировщик и изменила DNS-запись с адреса старого балансировщика на новый. Часть подов быстро получила новый адрес, но некоторые экземпляры продолжали отправлять запросы по старому, поскольку корпоративный резолвер и клиентская библиотека ещё использовали кэшированные ответы.
Рассматривались два варианта. Немедленно отключить старый балансировщик было быстро, но рискованно: это привело бы к ошибкам у клиентов со старым кэшем. Оставить оба адреса навсегда было безопаснее для переключения, но усложняло эксплуатацию и контроль трафика.
Выбрали поэтапный переход: заранее снизили TTL, сохранили старый балансировщик доступным на период, превышающий возможное время кэширования, настроили мониторинг запросов к старому адресу и затем удалили его после прекращения трафика. Это позволило избежать массовых ошибок, хотя переключение заняло дольше, чем простая замена записи.
Нет. TTL относится к конкретному кэшу, который получил DNS-ответ. Другие уровни могут иметь собственные правила кэширования, а приложение может игнорировать TTL или хранить результат дольше. Поэтому TTL определяет нормативный срок для стандартного DNS-кэширования, но не обеспечивает глобальную синхронность.
DNS влияет прежде всего на установление новых соединений. Уже открытое соединение не переопрашивает DNS при каждом запросе и продолжает использовать прежний адрес, пока не будет закрыто или разорвано. Поэтому при миграции нужно учитывать таймауты соединений, пулы HTTP-соединений и keep-alive.
Новый TTL применяется к ответам, полученным после изменения. Резолвер, который получил старый ответ с большим TTL, продолжит использовать его до окончания первоначального срока. Поэтому TTL уменьшают заранее, а не только в момент смены адреса; при аварийной смене приходится учитывать уже существующие старые кэши.