Внутри Kubernetes трафик между сервисами часто выглядит «внутренним», а потому по умолчанию считается безопасным. Это опасная модель. Pod может оказаться на другом узле, сеть может быть скомпрометирована, а ошибочно выданные сетевые права позволяют обращаться к соседнему сервису. На этом фоне mTLS — взаимная TLS-аутентификация — решает две конкретные задачи: шифрует соединение и позволяет сторонам удостовериться, с кем они установили связь. Но это не универсальный «режим безопасного Kubernetes».
Важно начать с границы ответственности. Kubernetes не включает service mesh как базовую функцию. Сетевые политики Kubernetes определяют, каким Pod разрешены соединения, но шифрование и способ его реализации зависят от CNI либо отдельного продукта. Kubernetes Security Checklist прямо рекомендует NetworkPolicy и допускает service mesh как вариант шифрования внутрикластерного трафика, если выбранный CNI этого не делает. Поэтому слова «включим mTLS» всегда должны сопровождаться названием продукта, моделью его внедрения и владельцем сертификатов.
Что mTLS меняет, а чего не меняет
При обычном TLS клиент проверяет сервер. При mTLS проверяются обе стороны: клиент предъявляет сертификат, сервер предъявляет свой. В service mesh это обычно происходит не в прикладном коде, а в прокси или другом компоненте data plane. Контрольный компонент выдаёт короткоживущие учётные данные и распространяет правила. В результате приложение payments может получить криптографически подтверждаемую идентичность вызывающего, а трафик между точками обработки становится зашифрованным.
Это полезно, но это не заменяет следующие уровни:
| Вопрос | Что отвечает |
|---|---|
| Может ли Pod установить сетевое соединение? | NetworkPolicy и её реализация CNI |
| Кто действительно подключился? | mTLS и идентичность workload |
| Разрешено ли этому субъекту вызвать именно этот метод? | прикладная или mesh-авторизация |
| Кто может создать, изменить или прочитать объект Kubernetes? | RBAC и защита API |
| Что произошло после запуска процесса? | журналирование, мониторинг и runtime detection |
Например, сервис frontend имеет разрешённый egress к orders, а orders принимает соединения только от идентичности frontend. Здесь NetworkPolicy уменьшает число возможных путей, а mTLS не позволяет любому Pod, оказавшемуся на допустимом IP-пути, выдать себя за frontend. Однако если у самого frontend есть уязвимость и он легитимно обращается к orders, mTLS не определит, что бизнес-запрос вредоносен. Нужны авторизация, валидация входа и наблюдаемость.
Не начинайте с режима strict на всём кластере
Самый частый риск внедрения — превратить сильную цель в массовый простой. В ряде mesh-реализаций есть миграционный режим, в котором приёмник временно допускает и обычный трафик, и mTLS. В Istio такой режим называется PERMISSIVE; STRICT принимает только mTLS. Это свойство Istio, а не API Kubernetes, поэтому названия и точное поведение обязательно проверяют в документации выбранного продукта.
Безопасный порядок работы выглядит так:
- Выберите один непубличный сервисный контур и зафиксируйте все его клиенты: workloads, Jobs, интеграции извне кластера, probes, gateways и администрирование.
- Определите, какая идентичность соответствует каждому workload. Нужен не просто список имён сервисов, а понятная связь «service account / namespace → допустимый сервис».
- Включите mesh в пилотном namespace и соберите наблюдаемость: сколько соединений уже mTLS, какие остаются plaintext и почему.
- Исправьте исключения: включите proxy там, где это предусмотрено моделью продукта, либо оформите контролируемый gateway для внешнего клиента. Не маскируйте проблему постоянным глобальным исключением.
- Лишь после подтверждения всех путей переведите приёмник пилотного сервиса в строгий режим. Затем проверьте доступность, трассы, ошибки TLS и автоматическую ротацию сертификатов.
На практике «сначала permissive, затем strict» — не цель сама по себе, а способ увидеть реальный legacy-трафик до блокировки. Если у выбранного решения нет такого режима, пилот должен быть ещё меньше: отдельный сервис, контролируемые клиенты и заранее подготовленный откат.
Минимальная проверка перед принуждением
До изменения режима владелец сервиса и платформа должны ответить на вопросы ниже не предположениями, а наблюдаемыми данными.
- Все ли исходящие клиенты известны, включая CronJob и отладочные утилиты?
- Все ли конечные точки на пути поддерживают модель mesh: сам workload, ingress/egress gateway, внешняя интеграция?
- Есть ли отдельный ответственный за корневое доверие, выдачу, срок жизни и отзыв сертификатов?
- Видна ли в телеметрии идентичность peer и признак шифрования, а не только HTTP-код?
- Проверяли ли ротацию сертификата в рабочем окружении или реплике production?
Проверка результата должна быть двусторонней. Позитивный тест: frontend вызывает разрешённый API orders, приложение получает ожидаемый ответ, а данные mesh показывают зашифрованное соединение и ожидаемую идентичность клиента. Негативный тест: тестовый Pod с другой service account пытается обратиться к тому же маршруту и получает отказ по политике идентичности либо по NetworkPolicy. Если виден только успешный HTTP 200, это ещё не доказательство mTLS: запрос мог пройти plaintext или обойти data plane.
Для Istio минимальная строгая политика приёмника имеет вид ниже. Это пример именно Istio, а не универсальный манифест Kubernetes; применять его стоит только в отдельном пилотном namespace после инвентаризации клиентов.
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: orders-strict
namespace: pilot
spec:
selector:
matchLabels:
app: orders
mtls:
mode: STRICT
После применения не ограничивайтесь тем, что объект создался. Проверьте, что клиент действительно использует data plane выбранного mesh, что запросы от frontend проходят, а известный plaintext-клиент перестал проходить предсказуемо. Затем отмените или скорректируйте политику в рамках заранее согласованного rollback, если отказ затронул критичный путь.
Сертификаты — не деталь установки
mTLS надёжен ровно настолько, насколько надёжны его идентичности и доверие. Требуется определить:
- кто владеет CA и имеет право менять trust bundle;
- как часто выдаются и автоматически обновляются workload-сертификаты;
- что происходит при компрометации service account, узла или корневого ключа;
- где доступны журналы выпуска и ошибок валидации;
- как проходит смена CA без одновременного отключения всех сервисов.
Нельзя переносить административный корневой сертификат кластера в mesh «для простоты» без отдельной архитектурной оценки. У разных продуктов разные механизмы доверия, хранение ключей и интеграция с внешним PKI. Это отдельная зона контроля: в ней должны быть аудит, ограниченный доступ и проверенный сценарий ротации.
Когда service mesh оправдан
Mesh уместен, когда ценность идентичности workload и шифрования выше его операционной цены: есть много внутренних сервисов, чувствительные данные, несколько команд, требования к аудитам или необходимость вводить авторизацию между сервисами единообразно. Для небольшой системы с несколькими сервисами иногда достаточно TLS в приложении или возможности CNI шифровать трафик, плюс аккуратные NetworkPolicy. Это не «хуже» и не «лучше»: нужно сравнить покрытие угроз, сложность сопровождения и ответственность за инциденты.
Итоговая архитектура должна быть слоистой. Сначала минимальные сетевые права, затем криптографическая идентичность и шифрование, затем авторизация действий и полноценная телеметрия. Если хотя бы один из этих уровней не проверен, надпись «mTLS enabled» остаётся настройкой, а не доказанной мерой защиты.
Официальные источники
- Kubernetes Security Checklist: https://kubernetes.io/docs/concepts/security/security-checklist/
- Kubernetes NetworkPolicy: https://kubernetes.io/docs/concepts/services-networking/network-policies/
- Istio Security and mTLS: https://istio.io/latest/docs/concepts/security/