какую роль выполняет proxy у каждой поды приложения
Service mesh для микросервисов. Часть III. Более глубокий взгляд на Istio
Перевод статьи подготовлен специально для студентов курса «Инфраструктурная платформа на основе Kubernetes».
Это третья статья из серии публикаций, посвященных Kubernetes и технологии service mesh (также известной как «сеть микросервисов» и «mesh-сеть микросервисов»). В предыдущей статье мы изучили основы работы с Istio и выяснили, как этот инструмент помогает настраивать и администрировать сложные облачные архитектуры. Так, с его помощью можно сконфигурировать mesh-сеть микросервисов и получить некоторые возможности централизации в распределенной микросервисной среде. Сегодня мы более подробно изучим функции Istio, чтобы по достоинству оценить преимущества технологии service mesh.
Istio — мощный, но достаточно сложный инструмент. Построить масштабируемую mesh-сеть микросервисов, способную выдерживать серьезные нагрузки, может быть непросто. Надеемся, после прочтения этой статьи вы будете лучше понимать, в чем заключается сложность mesh-сетей и какие средства помогают грамотно их конфигурировать. Хотя в большинстве случаев вам не придется вручную настраивать sidecar-прокси или настраивать сетевые взаимодействия, научившись выполнять эти действия, вы поймете, как функционирует service mesh. Это очень непростая тема. Чем глубже вы знаете возможности инструментов, тем лучше.
Поэтому сегодня мы подробно изучим четыре основных компонента Istio и их функции: управление трафиком (Envoy), плоскость управления (Pilot), компонент телеметрии (Mixer) и компонент безопасности (Citadel). Мы последовательно рассмотрим каждый из них и их роль в mesh-сети микросервисов.
Envoy
Вероятно, вы уже читали о sidecar-прокси в нашей последней публикации об Istio и знаете, что они добавляются к каждому определению сервиса и развертываются в одном поде с самим сервисом. Для нас термины Envoy и sidecar — фактически синонимы, хотя sidecar-прокси могут работать с различными подключаемыми модулями.
Sidecar-прокси работают как основные сетевые шлюзы для трафика конкретных сервисов, определенных вами: прокси принимает входящий трафик, направленный тому или иному сервису, и маршрутизирует его в соответствии с правилами и политиками, заданными в общей конфигурации.
Sidecar-прокси нужны для обработки данных управления, поступающих из двух источников. Первый из них — пользователь, а точнее, конфигурация, развернутая им в mesh-сети. Информация о ее модификациях, например об изменении параметров балансировки нагрузки, добавлении новых узлов, сервисов и данных сетевой маршрутизации, передается компоненту Pilot, который выступает в качестве основного источника сведений о состоянии приложения. Sidecar-прокси периодически сверяются с Pilot, получают актуальные данные конфигурации и вносят необходимые изменения в локальные правила.
Вторым источником данных управления являются приложения, к которым подключены sidecar-прокси. Envoy выполняет функцию балансировщика нагрузки, постоянно контролируя состояние подключенных к нему экземпляров и направляя запросы для проверки их активности. Компонент отслеживает основные индикаторы, такие как время отклика, и убеждается в том, что запросы обрабатываются. Envoy удаляет плохие экземпляры из пула, чтобы поврежденные развертывания или ошибки серверов не привели к отказу всего сервиса.
Какие еще преимущества дают sidecar-прокси? Помимо встроенных возможностей балансировки нагрузки и проверки состояния экземпляров, они позволяют настраивать трафик так, чтобы можно было получить представление о работе приложения. Так, тестирование новых версий с существенными изменениями кода на этапе разработки не всегда помогает сформировать подробную картину. В таких случаях полезно направить небольшой объем рабочего трафика в экземпляр, выполняющий новый код, чтобы понаблюдать за его поведением в реальных условиях.
Envoy позволяет создавать конфигурации, которые распределяют нагрузку между различными версиями. Например, можно начать с перенаправления всего 5 % трафика новым экземплярам. Как только данные модифицированной конфигурации будут переданы компоненту Pilot, изменится балансировка нагрузки в sidecar-прокси. Первоначально новый сервис будет получать небольшой объем трафика, а вы сможете собирать и обрабатывать экспериментальные данные. Затем можно будет постепенно увеличивать объем с 5 до 100 % и при необходимости уменьшать его, пока вы не будете уверены, что новая версия исправно работает.
Конфигурирование sidecar-прокси
Как выглядит такая конфигурация на практике? Для перенаправления трафика в различные целевые расположения необходимо задать параметр weight в конфигурации сервиса, например, так:
У нас есть один хост, hello1, с двумя версиями целевого расположения — v1 и v2. Сначала мы назначаем 75 % трафика для v1, а оставшиеся 25 % — для v2. После внедрения конфигурации можно проверить статус, выждав предварительно заданное время, и снова изменить параметры.
Таким образом, Envoy предоставляет отличные возможности для управления трафиком, направленным в конкретные целевые расположения. Если для вашего приложения характерны всплески трафика, которые перегружают оборудование, можно внедрить задержки с помощью параметра fault :
Pilot
Основной компонент, взаимодействующий с Envoy, — это Pilot, который осуществляет централизованное управление всеми экземплярами Envoy в mesh-сети. Pilot выступает в роли единого источника данных о состоянии среды. Это локальное хранилище всех правил для сервисов и их взаимодействий. Здесь же находятся сведения о выполняемых операциях. Pilot часто отождествляют с плоскостью управления Istio, так как он отвечает за администрирование и конфигурирование всех прокси Envoy (хотя технически другие компоненты, такие как Citadel, тоже относятся к плоскости управления).
Безусловно, Pilot играет важную роль в понимании принципов работы service mesh. Но на практике большинство операций, связанных с этим компонентом, выполняют прокси Envoy. Они периодически сверяются с Pilot, чтобы получать данные последних конфигураций, и регулярно обновляются. Любое изменение конфигурации mesh-сети подразумевает взаимодействие с плоскостью управления. Такое разделение задач — ключевой принцип Istio: прокси Envoy взаимодействуют с Pilot для создания сервисов, из которых строится приложение. Знание взаимосвязей между компонентами service mesh играет решающую роль в понимании сути этой технологии.
В первой статье мы говорили о преимуществах абстракции сети микросервисов, которая позволяет использовать высокоуровневые команды для определения взаимодействий между сервисами. Технология преобразовывает эти команды в точные конфигурации для сервисов, которые ей подконтрольны. Pilot — это компонент, отвечающий за эти ключевые функции. В качестве входных данных он получает правила обнаружения сервисов и генерирует определенные действия, которые выполняются прокси Envoy (или любыми другими sidecar-прокси, совместимыми с API Envoy).
Тест-драйв компонента Pilot
Лучший способ больше узнать об экземплярах Pilot в mesh-сети — ознакомиться с данными о статусе sidecar-прокси. Список сервисов и идентификатор Pilot, который их контролирует, можно получить, выполнив следующую команду:
Отобразится перечень сервисов и их идентификаторов с соответствующим идентификатором Pilot и текущим статусом синхронизации. Sidecar-прокси со статусом Synced или Synced (100 %) обновлены и получили последние конфигурации от компонента Pilot. Статус Not Sent означает, что конфигурация не менялась в последнее время, поэтому синхронизировать нечего. А статус Stale означает, что sidecar-прокси не реагирует на изменения.
На выходе вы получите следующее:
Обратите внимание, что вид выходных данных команд статуса прокси различается в разных версиях Istio (в частности, в версиях 1.0.5, 1.1.2 и в последней версии 1.1.7). Так, в более ранних версиях Istio выходные данные содержали полный объект JSON, но начиная с версии 1.1.7 они выглядят так, как показано выше. Вы можете столкнуться с другими форматами выходных данных.
Pilot покажет форматированные различия между изменениями конфигурации и текущим состоянием сервиса. Так вы сможете отследить, какие изменения еще не были внедрены в сервис и подтверждены.
Mixer
Как и Pilot, Mixer — это компонент Istio, который работает с трафиком и применяет настраиваемые правила. Основное отличие состоит в том, что Mixer работает на уровне всей mesh-сети и позволяет применять глобальные правила. Это значит, что его можно использовать для сбора телеметрии по всему приложению или настройки глобальных ограничений на использование тех или иных сервисов.
Теперь давайте разберемся, чем отличается работа Envoy и Mixer. Само название sidecar-прокси предполагает, что Envoy добавляется к каждому сервису, развернутому в приложении, и работает с трафиком, направленным в этот сервис. Mixer же функционирует на уровне всего приложения и применяет правила, заданные для среды в целом.
Как это работает? Правила могут быть самыми разными: от простой регистрации запросов с метками времени и IP-адресами до применения сложных квот и белых списков для более надежной защиты. Именно Mixer обеспечивает централизацию, свойственную монолитным приложениям. Хотите настроить выставление счетов на основе количества запросов, отправляемых пользователем, в SaaS-приложении? Это можно сделать с помощью Mixer. Необходимо включить регистрацию событий во внешних сервисах при каждом обращении пользователя к конфиденциальной информации? Снова Mixer.
Еще одна полезная возможность этого компонента — интеграция со сторонними подключаемыми модулями. Основной источник централизованной информации о приложении должен быть совместим с инструментами для визуализации операций или просмотра журналов. Mixer позволяет добавлять эти возможности в Kubernetes и удобно отображать собираемую информацию, часто в режиме реального времени. Одна такая платформа для мониторинга событий (Prometheus) уже интегрирована.
Подобные инструменты существенно облегчат вам жизнь. Mixer предоставляет данные mesh-сети, которые ранее были недоступны для микросервисных развертываний. А поскольку самостоятельно извлекать сведения об их активности непросто, на помощь придут различные специализированные инструменты.
Использование Mixer
Istio поставляется с несколькими политиками Mixer, готовыми для развертывания. Чтобы начать сбор данных телеметрии, нужно просто применить файл YAML с конфигурацией:
После этого входящий трафик будет регистрироваться и отправляться в центральный экземпляр Mixer. Если сервис активен, вы сразу же будете видеть результаты. В противном случае можно искусственно направить трафик в сервис.
Prometheus, встроенный инструмент для запроса журналов в Istio, — простейший способ просматривать трафик. Настройте переадресацию портов Prometheus:
Теперь Prometheus будет выполняться через порт 9090 локального компьютера — можно запрашивать журналы из этого расположения.
Citadel
Помимо масштабируемости, обеспечиваемой Envoy, и обширных сведений, предоставляемых Mixer, одним из преимуществ облачной mesh-архитектуры является безопасность. В Istio для этого используется Citadel — основной защитный компонент. Он помогает управлять ключами и сертификатами, которые являются неотъемлемой частью современных развертываний микросервисов.
Управление безопасностью развертывания микросервисов — не самая простая задача при переходе на сервисную архитектуру. Вам придется администрировать множество отдельных, постоянно меняющихся, самоподписанных сертификатов (в случае использования взаимной аутентификации TLS) или отказаться от шифрования и надеяться на лучшее.
Citadel берет значительную часть работы на себя. Этот компонент автоматически осуществляет создание и хранение ключей на основе определений сервисов и администрирует их с помощью встроенной инфраструктуры управления секретными ключами Kubernetes. Постоянно взаимодействуя с Kubernetes, Citadel гарантирует, что каждому новому сервису будет назначен сертификат, а каждый новый прокси Envoy будет доверять сертификату, развернутому с таким новым сервисом.
Иными словами, больше нет оснований для отказа от использования взаимной аутентификации TLS, которая сегодня считается наилучшим вариантом для сервисной архитектуры. Каждый сервис получает подтверждение TLS при обмене данными с другими сервисами, поэтому, даже если злоумышленник сможет просматривать сетевой трафик, данные будут зашифрованы и надежно защищены.
Разумеется, поддержка самоподписанных сертификатов и взаимной аутентификации TLS — лишь некоторые возможности Citadel. Компонент может взаимодействовать со сторонними центрами сертификации и использовать альтернативные сертификаты, если вы уже внедрили меры безопасности на их основе. Также он позволяет в случае необходимости применять более строгие политики, например взаимную аутентификацию TLS по протоколу HTTPS. Как видите, Citadel предоставляет очень гибкие возможности защиты.
Использование Citadel
Хотя функции безопасности этого компонента достаточно сложны, приступить к работе с Citadel совсем несложно. Как и в случае Mixer, основная часть работы выполняется автоматически. Чтобы запустить процесс, необходимо лишь активировать правильную конфигурацию.
Например, для включения глобальной взаимной аутентификации TLS нужно изменить политику аутентификации mesh-сети. Это можно сделать с помощью kubectl, применив следующую команду:
Но это еще не все. Сервисы получили команду принимать входящий трафик с использованием TLS, но они не настроены для отправки исходящих запросов через TLS, поэтому в данный момент обмен данными невозможен. Чтобы применять TLS и для исходящих запросов, настройте правила сетевого взаимодействия:
Затем проверьте работу сервисов. Теперь они могут обмениваться данными друг с другом, но для этого используется зашифрованный трафик. Благодаря всего двум командам ваш трафик надежно защищен, а сеть находится в безопасности.
Заключение
Теперь вы гораздо лучше осведомлены о возможностях Istio и о том, как они связаны с преимуществами service mesh в целом. Четкое распределение задач — одна из сильных сторон этого инструмента. Все компоненты, такие как sidecar-прокси в Envoy или система управления ключами Citadel, являются изолированными и самостоятельными.
Мы советуем вам выделить немного времени на изучение принципов их функционирования. Поэкспериментируйте с одним или двумя компонентами в пробном приложении или проработайте один из наших примеров. Так вы лучше поймете возможности технологии service mesh.
Разумеется, одному разработчику будет сложно разобраться во всех нюансах работы Istio. Технологии непрерывно развиваются, каждый день добавляются новые возможности, а старые претерпевают изменения — если самостоятельно их отслеживать, придется уделять этому все свое время. Поэтому мы собрали наглядные примеры, чтобы помочь вам разобраться в скрытых процессах. А упомянутые вспомогательные инструменты позволят грамотно выстроить работу с Istio.
Эксперименты с kube-proxy и недоступностью узла в Kubernetes
Прим. перев.: В этой статье, написанной техническим консультантом и сертифицированным администратором Kubernetes из Великобритании — Daniele Polencic, — наглядно показывается и рассказывается о том, какую роль играет kube-proxy в доставке пользовательских запросов до подов и что происходит, когда на одном из узлов кластера возникают проблемы.
Код приложений, развёрнутых в Kubernetes, запускается на одном или более рабочих узлов. Узел может располагаться как на физической или виртуальной машине, так и в AWS EC2 или Google Compute Engine, а наличие множества таких площадок означает возможность эффективного запуска и масштабирования приложения. Например, если кластер состоит из трёх узлов и вы решаете отмасштабировать приложение на четыре реплики, Kubernetes равномерно распределит их среди узлов следующим образом:
Такая архитектура хорошо справляется и с падениями. Если один узел окажется недоступным, приложение продолжит работать на двух других. А в это время Kubernetes переназначит четвёртую реплику на другой (доступный) узел.
Более того, даже если все узлы окажутся изолированными, они всё равно смогут обслуживать запросы. Например, уменьшим число реплик приложения до двух:
Поскольку каждый узел может обслуживать приложение, как же третий (Node 3) узнает, что на нём не запущено приложение и ему следует перенаправить трафик на один из других узлов?
Но откуда kube-proxy знает, где расположены все поды?
А вот знает обо всём главный (master) узел, который отвечает за создание списка всех правил маршрутизации. А kube-proxy проверяет эти правила и приводит их в действие. В простом сценарии, описанном выше, список правил сводится к следующему:
Но что происходит, когда kube-proxy падает?
И что, если список правил пропадёт?
Что происходит, когда нет правил, куда направлять трафик?
У Manabu Sakai были такие же вопросы. И он решил разобраться.
Предположим, у вас кластер из двух узлов в GCP:
И вы разворачиваете приложение Manabu:
Это простое приложение, которое выводит на веб-странице имя хоста текущего пода.
Масштабируем его (Deployment) до десяти реплик:
Десять реплик равномерно распределяются по двум узлам (node1 и node2):
Создаётся Service для балансировки нагрузки от запросов по десяти репликам:
Во внешний мир он пробрасывается через NodePort и доступен по порту 30000. Другими словами, у каждого узла открывается порт 30000 для внешнего интернета и начинает принимать входящий трафик.
Но как трафик маршрутизируется с порта 30000 до пода?
Попробуйте отправить запрос на порт 30000 одного из узлов:
Если повторно запрашивать тот же URL, иногда будет появляться такой же ответ, а иногда он будет меняться. Причина — kube-proxy работает как балансировщик нагрузки, проверяет маршрутизацию и распределяет трафик по десяти подам.
Что интересно, совершенно всё равно, к какому узлу вы обращаетесь: ответ будет приходить с любого пода — даже с тех, которые размещены на других узлах (не тех, к которым вы обратились).
Для окончательной конфигурации потребуется задействовать внешний балансировщик нагрузки, который распределит трафик по узлам (на порт 30000). Так и получается финальная схема прохождения запросов:
То есть балансировщик нагрузки перенаправляет входящий трафик из интернета на один из двух узлов. Внесём ясность во всю эту схему — резюмируем принцип её работы:
Настало время всё сломать
Теперь, когда мы знаем, как всё взаимодействует, давайте вернёмся к изначальному вопросу. Что случится, если мы изменим правила маршрутизации? Будет ли по-прежнему работать кластер? Будут ли поды обслуживать запросы?
Давайте удалять правила маршрутизации, а в отдельном терминале — мониторить приложение на время ответов и пропущенные запросы. Для последнего достаточно написать цикл, который будет каждую секунду выводить текущее время и делать запрос к приложению:
На выходе мы получим столбцы со временем и текстом ответа от пода:
Итак, давайте удалять правила маршрутизации с узла, но сначала разберёмся, как это делать.
kube-proxy может работать в трёх режимах: userspace, iptables и ipvs. Режимом по умолчанию со времён Kubernetes 1.2 является iptables. (Прим. перев.: Последний режим, ipvs, появился в релизе K8s 1.8 и получил статус бета-версии в 1.9.)
Если всё прошло по плану, вы увидите нечто подобное:
Как легко заметить, с момента сбрасывания правил iptables до следующего ответа потребовалось около 27 секунд (с 10:14:43 до 10:15:10).
Что произошло за это время? Почему всё снова стало хорошо после 27 секунд? Может быть, это просто совпадение?
Давайте сбросим правила ещё раз:
Теперь видна пауза в 29 секунд, с 11:29:56 до 11:30:25. Но кластер снова вернулся к работе.
Почему для ответа требуется 30 секунд? На узел приходят запросы даже без таблицы маршрутизации?
Можно посмотреть на то, что происходит на узле на протяжении этих 30 секунд. В другом терминале запустите цикл, который делает запросы к приложению каждую секунду, но на сей раз — обращайтесь к узлу, а не балансировщику нагрузки.
И снова сбросьте правила iptables. Получится такой лог:
Неудивительно, что подключения к узлу заканчиваются таймаутом после сброса правил. Но интересно, что curl ждёт ответа по 10 секунд.
А что, если в предыдущем примере балансировщик нагрузки ждёт новых подключений? Это бы объяснило 30-секундную задержку, однако останется непонятным, почему узел готов принимать соединения после достаточно продолжительного ожидания.
Так почему же трафик снова идёт через 30 секунд? Кто восстанавливает правила iptables?
Перед тем, как сбрасывать правила iptables, можно их посмотреть:
Сбросьте правила и продолжайте выполнять эту команду — вы увидите, что правила восстанавливаются за несколько секунд.
Итак, резюмируем, как Kubernetes и kube-proxy восстанавливаются, если кто-то испортил правила iptables на узле:
На узле есть агент — kubelet, — и именно он отвечает за запуск kube-proxy как статичного пода на каждом узле. Документация по статичным подам предполагает, что kubelet проверяет содержимое определённого каталога и создаёт все ресурсы из него.
Примечание: В целях упрощения здесь приведено неполное содержимое файла.
Выводы
Сброс правил iptables равносилен тому, чтобы сделать узел недоступным. Трафик по-прежнему отправляется на узел, однако он не способен пробросить его дальше (т.е. на под). Kubernetes может восстанавливаться после такой проблемы с помощью отслеживания правил маршрутизации и их обновления при необходимости.
Большая благодарность Manabu Sakai за публикацию в блоге, которая во многом вдохновила на этот текст, а также Valentin Ouvrard за изучение вопроса пробрасывания правил iptables с мастера на другие узлы.
Istio: обзор и запуск service mesh в Kubernetes
Istio- одна из реализацией концепии Service Mesh, позволяющая реализовать Service Discovery, Load Balancing, контроль над трафиком, canary rollouts и blue-green deployments, мониторить трафик между приложениями.
Мы будем использовать Istio в AWS Elastic Kubernetes Service для мониторинга трафика, в роли API gateway, разграничения трафика и, возможно, для реализации различных deployment strategies.
В этом посте рассмотрим что такое Service mesh вообще, общую архитектуру и компоненты Istio, его установку и настройку тестового приложения.
Перед тем, как рассматривать Istio – давайте разберёмся, что такое Service Mesh.
Service Mesh
По сути, это менеджер прокси-сервисов, таких как NGINX, HAProxy или Envoy, система, работающая на Layer 7 модели OSI и позволяющая динамически управлять трафиком и настраивать коммуникацию между приложениями.
Service mesh занимается обнаружением новых сервисов/приложений, балансировкой нагрузки, аутентификацией и шифрованием трафика.
Для контроля трафика в service mesh для каждого приложения, или в случае с Kubernetes – для каждого пода, запускается прокси-сервис называемый sidecar, и эти sidecar-сервисы проксируют и управляют трафиком.
Вместе эти sidecar-контейнеры представляют собой Data Plane.
Для их конфигурирования и управления существует другая группа процессов или сервисов, называемых Control Plane. Они занимаются обнаружением новых приложений, обеспечивают управление ключами шифрования, сбором метрик и т.д.
Схематично сервис меш можно отобразить так:
Среди Service mesh решений можно выделить:
Архитектура Istio
Итак, Istio как service mesh состоит из двух основных частей – Data plane и Control plane:
В целом схема Istio выглядит так:
Control Plane
Istio включает в себя четыре основных компонента:
Data Plane
Состоит из sidecar-контейнеров, которые в Kubernetes запускаются внутри подов через kube-inject, см. Installing the Sidecar.
Контейнеры являются инстансами Envoy-прокси, которые позволяют:
Модель сети Istio
Перед тем, как приступать к запуску и настройке приложения и Istio – кратко рассмотрим ресурсы, которые участвуют в управлении трафиком.
При установке Istio создаёт ресурс Ingress Gateway (и Egress Gateway, если было определено при установке) – новый объект в Kubernetes, который описывается в Kubernetes CRD при установке Istio.
В AWS при настройках по-умолчанию Ingress Gateway создаёт AWS Classic LoadBalancer, т.к. Ingress Gateway является Kubernetes-объектом Ingress с типом LoadBalancer.
“За” Ingress Gateway создаётся ресурс Gateway, который также описывается в Kubernetes CRD во время установки Istio и описывает хосты и порты, на которые будет отправляться трафик через этот Gateway.
Далее следует ещё один ресурс – VirtualService, который описывает маршрутизацию трафика, прошёдшего через Gateway, и отправляет его на Kubernetes Services следуя заданным Destination rules.
Ingress Gateway состоит из двух компонентов – Kubernetes Pod с инстансом Envoy, который управляет входящим трафиком, и Kubernetes Ingress, который принимает подключения.
В свою очередь Gateway и VirtualService управляют конфигурацией Envoy, который является Ingress Gateway controller.
Т.е. в целом схема прохождения пакета выглядит так:
Запуск Istio в Kubernetes
Istio поддерживает различные Deployment models. В нашем случае используется один EKS-кластер, а поды в нём работают в общей VPC сети.
Установить Istio можно разными способами – с помощью istioctl из манифест-файлов, из Helm-чарта, либо с помощью Ansible.
Также, стоит обратить внимание на Mutual TLS (mTLS) – см. Permissive mode. Если кратко, то по-умолчанию Istio устанавливается в Permissive mode, что позволяет уже существующим приложениям продолжать коммуникацию используя plaintext-трафик. При этом новые подключения через Envoy-контейнеры, sidecars, уже будут выполняться с TLS-шированием.
Пока выполним установку руками, а на Дев и Прод кластера Кубера скорее всего будем инсталить через Helm.
Генерируем kubeconfig для нового тестового кластера (для AWS EKS, если используется Minikube – он при старте сгенерирует конфиг сам):
Устанавливаем Istio с профилем default:
Проверяем версию ещё раз:
Далее задеплоим тестовое приложение, и настроим роутинг через Istio Ingress Gateway.
Тестовое приложение
Не будем использовать Bookinfo приложение из Istio Gettings Started, а напишем свой велосипед создадим свой Namespace, Deployment с одним подом с NGINX, и к нему Service – эмулируем миграцию уже имеющихся у нас приложений под управление Istio.
Кроме того, сейчас специально не будем настраваить добавление sidecar-контейнеров в приложение – вернёмся к этому вопросу чуть позже.
Манифест сейчас выглядит так: