ADG Оставить заявку
Блог DevOps 4 мин чтения

Istio 1.2 в тестовом кластере: mTLS закрыл давнюю задачу по east-west трафику

Развернули Istio 1.2 на тестовом кластере: упрощённая установка через Helm, улучшенный Mixer, mTLS в STRICT-режиме без правок в приложении.

Контекст момента

Istio 1.2 вышел в июне 2019 с улучшенной производительностью и упрощённой установкой через Helm

Istio 1.2 вышел в середине июня - тихо, без большого анонса, но с рядом изменений, которые нас интересовали. Мы развернули его на тестовом кластере и потратили несколько дней на то, чтобы разобраться, что реально изменилось по сравнению с 1.0, с которым работали с осени прошлого года.

Главный практический результат: mTLS между сервисами в STRICT-режиме заработал без единого изменения в коде приложений. Это была задача, которая числилась в бэклоге с осени, и каждый раз откладывалась из-за опасений нарваться на edge cases при обновлении. В итоге оказалось, что опасались зря - процесс прошёл чище, чем мы ожидали.

Что изменилось в 1.2

Два изменения бросились в глаза сразу.

Установка через Helm стала управляемее. В 1.0 Helm-чарт был монолитным и при установке плохо поддавался выборочной настройке - приходилось либо брать всё, либо копаться в шаблонах. В 1.2 профили установки (default, minimal, sds, remote) позволяют с самого начала выбрать что именно вы хотите в кластере. Для тестового стенда поставили default, убрали Kiali и Jaeger - не нужны на этом этапе.

Mixer стал заметно меньше болеть. В 1.0 у нас был открытый вопрос по Mixer под нагрузкой - каждый вызов синхронно ходил за policy-check-ом, и при пиках это давало заметную добавку к latency. В 1.2 улучшили агрессивность кэширования на стороне Envoy, и по первым тестам поведение под нагрузкой действительно другое. Не утверждаем что проблема решена - нужно смотреть в продакшне - но на тестовом трафике разница есть.

Из изменений, которые влияют на операционку: улучшена работа sidecar-инжектора при rolling update. Раньше была ситуация когда новые поды в Deployment поднимались с обновлённым sidecar-ом, а старые ещё жили с предыдущей версией - в этот момент mTLS мог вести себя непредсказуемо если cert-ы между версиями чуть разошлись. В 1.2 переходный период проходит чище.

mTLS: задача наконец закрыта

С Istio 1.0 в продакшне mTLS у нас работал в PERMISSIVE-режиме: сервисы могли общаться как по TLS, так и plain HTTP. Это позволяло не трогать сервисы при добавлении в mesh, но означало что шифрование east-west трафика было опциональным, а не гарантированным.

Задача включить STRICT-режим - чтобы любое незашифрованное соединение отклонялось на входе в sidecar - висела в бэклоге с осени. Откладывали из-за нескольких опасений:

  • healthcheck-и от kubelet идут plain HTTP напрямую к контейнеру, минуя sidecar. При STRICT-режиме это не проблема самого mTLS (kubelet не в mesh), но нужно убедиться что exec-probe или отдельный healthcheck-порт вне перехвата iptables настроен везде.
  • legacy-компоненты с JDBC-драйверами и прямыми TCP-соединениями - нужно было убедиться что они либо тоже в mesh, либо явно выведены из него через ServiceEntry.
  • CI-задачи которые ходят в API изнутри кластера без sidecar.

На тестовом кластере прошлись по всем трём. Healthcheck-и переключили на exec-probe или отдельный non-intercepted порт. Legacy-компоненты оказались проще чем думали - часть ещё в 1.0 получила sidecar и уже жила в mesh. CI-задачи пока вынесли в exception через Policy с peers[].mtls.mode: PERMISSIVE только для их namespace - компромисс, но не на боевом контуре.

После этого применили MeshPolicy с mtls: {} и глобальный DestinationRule с tls.mode: ISTIO_MUTUAL. Весь east-west трафик пошёл по шифрованному каналу с взаимной аутентификацией через SPIFFE-сертификаты от Citadel. Разработчики со своей стороны не изменили ни строчки.

Мелкое, но важное

На managed-контуре с несколькими клиентскими кластерами есть нюанс с именованием сервисов. Istio использует FQDN из ServiceEntry для маршрутизации - если в DestinationRule указан хост без namespace-суффикса, поведение может отличаться от ожидаемого при cross-namespace трафике. В 1.0 на это мы напоролись в gRPC-сервисах - там заголовки трейсинга не прокидывались именно из-за того, что маршрутизация ломалась молча. В 1.2 поведение то же, просто теперь мы про это знаем заранее и пишем svc.namespace.svc.cluster.local везде где хост не в том же namespace.

Ещё один момент с VirtualService и timeout: если таймаут задан и в DestinationRule, и в VirtualService - приоритет у VirtualService. Звучит логично, но когда они расходятся и это не задокументировано в манифесте - это источник тихих сюрпризов при дебаге.

Где мы сейчас

Тестовый кластер работает с Istio 1.2 и STRICT mTLS уже полторы недели. Пока стабильно. Задача перевода боевого контура остаётся на следующий шаг - хочется ещё понаблюдать за Mixer под пиковым трафиком перед тем как принимать решение.

Основной вывод: mTLS без правок в приложении работает, и это та ценность Istio которая оправдывает операционный overhead от самого mesh. Весь east-west трафик теперь шифруется - не «если кто-то подключил библиотеку», а гарантированно на уровне инфраструктуры. Это другой разговор с командой безопасности.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.