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 в конфигурации сервиса, например, так:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
   name: helloworld
spec:
   hosts:
      - hello1
   http:
      - route:
         - destination:
            host: hello1
            subset: v1
            weight: 75
         - destination:
            host: hello1
            subset: v2
            weight: 25
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
   name: helloworld
spec:
   host: hello1
   subsets:
      - name: v1
      labels:
         version: v1
      - name: v2
      labels:
         version: v2


У нас есть один хост, hello1, с двумя версиями целевого расположения — v1 и v2. Сначала мы назначаем 75 % трафика для v1, а оставшиеся 25 % — для v2. После внедрения конфигурации можно проверить статус, выждав предварительно заданное время, и снова изменить параметры.

Таким образом, Envoy предоставляет отличные возможности для управления трафиком, направленным в конкретные целевые расположения. Если для вашего приложения характерны всплески трафика, которые перегружают оборудование, можно внедрить задержки с помощью параметра fault:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
   name: helloworld
spec:
   hosts:
      - hello1
   http:
      - fault:
         delay:
            percent: 10
            fixedDelay: 3s
   route:
      - destination:
         host: hello1


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, который их контролирует, можно получить, выполнив следующую команду:

istioctl proxy-status


Отобразится перечень сервисов и их идентификаторов с соответствующим идентификатором Pilot и текущим статусом синхронизации. Sidecar-прокси со статусом Synced или Synced (100 %) обновлены и получили последние конфигурации от компонента Pilot. Статус Not Sent означает, что конфигурация не менялась в последнее время, поэтому синхронизировать нечего. А статус Stale означает, что sidecar-прокси не реагирует на изменения.



При возникновении проблем с синхронизацией можно указать идентификатор конкретного сервиса в команде статуса прокси и просмотреть сведения об ошибках синхронизации между Pilot и sidecar. Например, если представленный выше список сервисов включает идентификатор hello-world-v2–5aa3f7abd-ppz2n.default, можно выполнить команду:

istioctl proxy-status hello-world-v2-686a3b641-4r52s.default


На выходе вы получите следующее:
Clusters Match
Listeners Match
Routes Match (RDS last loaded at Fri, 24 May 2019 20:22:14 UTC)


Обратите внимание, что вид выходных данных команд статуса прокси различается в разных версиях 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 с конфигурацией:

kubectl apply -f samples/bookinfo/telemetry/metrics.yaml

После этого входящий трафик будет регистрироваться и отправляться в центральный экземпляр Mixer. Если сервис активен, вы сразу же будете видеть результаты. В противном случае можно искусственно направить трафик в сервис.

Prometheus, встроенный инструмент для запроса журналов в Istio, — простейший способ просматривать трафик. Настройте переадресацию портов Prometheus:

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 &


Теперь 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, применив следующую команду:

kubectl apply -f - <<EOF
apiVersion: "authentication.istio.io/v1alpha1"
kind: "MeshPolicy"
metadata:
   name: "default"
spec:
   peers:
      - mtls: {}
EOF


Но это еще не все. Сервисы получили команду принимать входящий трафик с использованием TLS, но они не настроены для отправки исходящих запросов через TLS, поэтому в данный момент обмен данными невозможен. Чтобы применять TLS и для исходящих запросов, настройте правила сетевого взаимодействия:

kubectl apply -f - <<EOF
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
   name: "default"
   namespace: "istio-system"
spec:
   host: "*.local"
   trafficPolicy:
      tls:
         mode: ISTIO_MUTUAL
EOF


Затем проверьте работу сервисов. Теперь они могут обмениваться данными друг с другом, но для этого используется зашифрованный трафик. Благодаря всего двум командам ваш трафик надежно защищен, а сеть находится в безопасности.

Заключение


Теперь вы гораздо лучше осведомлены о возможностях Istio и о том, как они связаны с преимуществами service mesh в целом. Четкое распределение задач — одна из сильных сторон этого инструмента. Все компоненты, такие как sidecar-прокси в Envoy или система управления ключами Citadel, являются изолированными и самостоятельными.

Мы советуем вам выделить немного времени на изучение принципов их функционирования. Поэкспериментируйте с одним или двумя компонентами в пробном приложении или проработайте один из наших примеров. Так вы лучше поймете возможности технологии service mesh.

Разумеется, одному разработчику будет сложно разобраться во всех нюансах работы Istio. Технологии непрерывно развиваются, каждый день добавляются новые возможности, а старые претерпевают изменения — если самостоятельно их отслеживать, придется уделять этому все свое время. Поэтому мы собрали наглядные примеры, чтобы помочь вам разобраться в скрытых процессах. А упомянутые вспомогательные инструменты позволят грамотно выстроить работу с Istio.
Источник: habr.ru