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

Istio 1.0: наконец в продакшн - mTLS по всему кластеру без правок в коде

С выходом Istio 1.0 перевели service mesh в продакшн: mTLS между всеми сервисами кластера, единая точка управления политиками трафика без правок в коде.

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

Istio 1.0 GA (31 июля 2018) - первый релиз с официальным production-ready статусом, стабильное API, поддержка мультикластерных конфигураций

31 июля вышел Istio 1.0 - и команда наконец-то объявила релиз production-ready. Мы следили за Istio с версии 0.8, когда ставили его на тестовый кластер и смотрели на mTLS и Kiali. Тогда в продакшн не потащили - Mixer под нагрузкой вызывал вопросы, и вообще нулевая мажорная версия в продакшне это спорное удовольствие. С 1.0 аргументов откладывать почти не осталось.

Перевод на managed-инфраструктуре - рабочий кластер Kubernetes, около десятка сервисов, HTTP и gRPC между ними. Задача была конкретная: mTLS между всеми сервисами кластера и единая точка управления политиками трафика - без изменений в коде приложений.

Что изменилось между 0.8 и 1.0

API стабилизировалось. Это звучит скучно, но на практике означает что манифесты, написанные под 1.0, не поедут при следующем патч-релизе. В 0.8 такой уверенности не было.

Из заметного по существу: улучшилась работа sidecar-инжектора - меньше случаев когда под поднимается, а sidecar ещё не готов и первые запросы падают. Стала стабильнее интеграция с Citadel: ротация сертификатов работает автоматически и без перезапуска подов. Документация подтянулась - стало меньше примеров с устаревшим API, которые в 0.8 встречались регулярно.

Mixer остался Mixer-ом. Архитектурно ничего не поменялось: каждый запрос через Envoy по-прежнему синхронно ходит в Mixer за policy-check-ом. Это известное узкое место, и в 1.0 оно никуда не делось. Спасает кэширование на стороне Envoy - включается в конфиге, существенно снижает количество реальных обращений к Mixer.

Установка и обновление

С тестового 0.8 мигрировали через полный переустанов - upgrade-пути между минорными версиями у Istio пока болезненные. Снесли старый namespace istio-system, задеплоили 1.0 через Helm-чарт, пересоздали поды в рабочих namespace. Downtime был - около десяти минут пока новые sidecar-ы не поднялись и mTLS не восстановился.

Автоинжектор сайдкаров работает через MutatingWebhookConfiguration. В 1.0 он стал надёжнее, но важный момент: если namespace получает аннотацию istio-injection: enabled уже после того как поды запущены - они не получат sidecar автоматически, нужен рестарт. Это не баг, это просто надо знать заранее и включать аннотацию до деплоя, а не после.

mTLS: строгий режим по всему кластеру

Основная цель - STRICT mTLS между всеми сервисами - достигается двумя манифестами:

MeshPolicy с mtls: {} включает mTLS в режиме STRICT глобально. После применения сервисы без sidecar теряют возможность принимать входящий трафик от сервисов со sidecar - Envoy отклоняет незашифрованные соединения.

DestinationRule с trafficPolicy.tls.mode: ISTIO_MUTUAL говорит Envoy на стороне клиента: при обращении к любому сервису использовать взаимный TLS с SPIFFE-сертификатами, которые выдал Citadel.

После применения обоих манифестов - весь межсервисный трафик внутри кластера идёт по шифрованному каналу с взаимной аутентификацией. В логах Envoy виден TLS handshake, в сертификатах - идентификаторы вида spiffe://cluster.local/ns/default/sa/svc-name. Разработчики со своей стороны не изменили ни строчки.

Один важный нюанс с которым столкнулись: healthcheck-и от kubelet идут не через sidecar, они plain HTTP напрямую к контейнеру. Если приложение само не слушает на нужном порту без sidecar - это всплывает именно при STRICT-режиме, когда хочется быть уверенным что весь трафик идёт через mesh. Надёжнее не полагаться на HTTP-probe, а использовать exec-probe или вынести healthcheck на отдельный порт вне перехвата iptables. Мы переключили на exec.

Наблюдаемость: Jaeger и Kiali в комплекте

В 1.0 Jaeger для распределённой трассировки и Kiali для графа трафика устанавливаются из того же Helm-чарта - не нужно искать отдельно. Включаются через values при установке.

Kiali с тех пор как мы его смотрели в 0.8 подрос: стало проще фильтровать по namespace, граф трафика обновляется быстрее. Jaeger интегрирован с Envoy через заголовки x-b3-traceid - это требует что приложение прокидывает эти заголовки дальше при обращении к другим сервисам. Если приложение их дропает - трейс разрывается. Пришлось добавить проброс заголовков в нескольких сервисах, это единственное изменение в коде которое потребовалось.

Как выглядит архитектура теперь

Раньше у нас была честная «мы думаем что знаем как сервисы общаются» ситуация. Теперь:

  • каждый межсервисный вызов аутентифицирован и зашифрован - без отдельных библиотек в каждом сервисе
  • политики трафика (таймауты, ретраи, circuit breaker) настраиваются в DestinationRule без деплоя приложения
  • Kiali показывает реальный граф трафика, а не нарисованный вручную
  • Jaeger даёт трейс запроса сквозь цепочку сервисов

Это не значит что стало легче жить в операционном смысле - Istio добавляет слой абстракции и соответствующий overhead при отладке. Когда что-то не так, сначала непонятно: это приложение, это Envoy, это Pilot не доставил конфиг, или это Citadel не обновил сертификат. Нужно знать куда смотреть.

Но архитектурная картина стала прозрачнее: есть одно место где определены политики безопасности сети, и это не раскиданные по репозиториям библиотеки.

Что пока вызывает вопросы

Mixer под высокой нагрузкой - по-прежнему открытый вопрос. На текущем трафике кэширование справляется, но запаса уверенности нет. Мониторим latency на входе в Envoy и на выходе из Mixer отдельно.

Control plane recovery - если Pilot недоступен, Envoy продолжает работать с последней известной конфигурацией. Это хорошо, но сколько эта конфигурация остаётся актуальной при активном деплое - вопрос который надо проверять, а не просто верить документации.

В целом: после нескольких недель в продакшне ничего критичного не случилось. Для нас это хороший знак.

Контакт

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

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