Привет, уважаемые читатели Хабра!

Когда у нас есть десятки, сотни или даже тысячи микросервисов, становится важным уметь управлять трафиком между ними. Это может включать в себя маршрутизацию запросов, балансировку нагрузки, версионирование сервисов и даже внедрение A/B-тестирования. Контроль над трафиком необходим для обеспечения стабильности и производительности системы.

Мониторинг микросервисов и всей инфраструктуры позволяет выявлять и решать проблемы быстро. Это включает в себя сбор метрик, анализ логов и трассировку запросов. В мире микросервисов даже мелкие изменения могут иметь большое воздействие на производительность, и мониторинг помогает быстро реагировать на такие изменения.

И вот здесь на помощь приходит Istio, предоставляя мощные инструменты для управления трафиком и мониторинга в микросервисной архитектуре.

Установка и настройка Istio

Istio предоставляет несколько способов установки, но одним из наиболее распространенных и удобных является использование утилиты istioctl. Это CLI-инструмент, предназначенное для управления Istio и установки на вашем кластере. Для начала, вы можете загрузить istioctl из официального репозитория Istio:

curl -L https://istio.io/downloadIstio | sh -

Теперь, когда у вас есть istioctl, вы можете установить Istio на вашем Kubernetes-кластере с помощью одной команды:

istioctl install

Эта команда автоматически установит Istio с настройками по умолчанию. Однако в большинстве случаев вам, возможно, потребуется настроить Istio в соответствии с вашими требованиями.

Чтобы ваша микросервисная архитектура полноценно функционировала с Istio, вам потребуется настроить среду развертывания.

Одним из первых шагов будет интеграция ваших сервисов с sidecar-контейнерами Istio. Sidecar-контейнер - это часть каждого микросервиса, которая работает рядом с основным приложением и обрабатывает весь сетевой трафик. Это позволяет Istio контролировать трафик между микросервисами, применять политики безопасности и мониторинга.

Пример определения микросервиса с sidecar-контейнером Istio:

apiVersion: v1
kind: Pod
metadata:
  name: my-service
spec:
  containers:
  - name: my-app
    image: my-app:latest
  - name: istio-proxy
    image: istio/proxyv2:latest

Следующим важным шагом будет настройка Ingress Gateway. Это точка входа в ваш кластер, через которую запросы попадают в микросервисы.

Istio интегрируется тесно с Kubernetes. Для этой интеграции Istio использует ресурсы Kubernetes, такие как Deployment, Service, и Ingress.

Пример настройки маршрутизации трафика для вашего микросервиса с использованием Kubernetes и Istio:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-service
spec:
  hosts:
    - my-service
  http:
    - route:
      - destination:
          host: my-service
          subset: v1

Этот пример определяет виртуальный сервис, который направляет трафик к вашему микросервису. Ваша среда Kubernetes становится еще более мощной, когда вы добавляете Istio в уравнение.

Управление трафиком с Istio

Виртуальные сервисы в Istio позволяют определять, какие запросы направляются к каким версиям сервисов и как это происходит.

Пример 1: Простая настройка виртуального сервиса

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-service
spec:
  hosts:
    - my-service
  http:
    - route:
      - destination:
          host: my-service
          subset: v1

В этом примере мы создаем виртуальный сервис для my-service и направляем весь трафик к версии v1. Это может быть полезно, когда у вас есть одна версия микросервиса и вы хотите, чтобы все запросы шли к ней.

Пример 2: Маршрутизация на основе заголовков HTTP

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-service
spec:
  hosts:
    - my-service
  http:
    - match:
      - headers:
          version:
            exact: v2
      route:
      - destination:
          host: my-service
          subset: v2
    - route:
      - destination:
          host: my-service
          subset: v1

В этом примере мы используем заголовок HTTP с именем version для маршрутизации трафика. Если заголовок version установлен в v2, то трафик направляется к версии v2. В противном случае он идет к версии v1.

Пример 3: Весовая балансировка нагрузки

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-service
spec:
  hosts:
    - my-service
  http:
    - route:
      - destination:
          host: my-service
          subset: v1
        weight: 80
      - destination:
          host: my-service
          subset: v2
        weight: 20

Здесь мы настраиваем виртуальный сервис для маршрутизации трафика между версиями v1 и v2 на основе весов. 80% трафика направляется к версии v1, а 20% - к версии v2.

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

Маршрутизация на основе заголовков HTTP

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-service
spec:
  hosts:
    - my-service
  http:
    - match:
      - headers:
          version:
            exact: v2
      route:
      - destination:
          host: my-service
          subset: v2
    - route:
      - destination:
          host: my-service
          subset: v1

Этот пример был упомянут ранее, и он демонстрирует, как использовать заголовки HTTP для точной маршрутизации трафика.

Применение таймаутов и ретраев

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-service
spec:
  hosts:
    - my-service
  http:
    - route:
      - destination:
          host: my-service
          subset: v1
        timeout: 5s
        retries:
          attempts: 3
          perTryTimeout: 2s

Здесь мы настраиваем таймаут для запросов к версии v1 в 5 секунд и включаем повторные попытки с максимум 3 попытками и таймаутом на каждой попытке в 2 секунды.

Динамическая маршрутизация с помощью DestinationRules

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-service
spec:
  host: my-service
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN

Этот пример демонстрирует, как можно настроить маршрутизацию с использованием правил DestinationRule. Здесь мы используем стратегию LEAST_CONN, чтобы направлять трафик к экземплярам сервиса с наименьшим количеством соединений.

В Istio, политики маршрутизации и балансировки нагрузки можно настраивать с использованием VirtualService. Это позволяет точно контролировать, как трафик распределяется между вашими микросервисами и какие действия применяются в различных сценариях.

Применение политики таймаута

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-service
spec:
  hosts:
    - my-service
  http:
    - route:
      - destination:
          host: my-service
          subset: v1
        timeout: 5s

В этом примере мы устанавливаем таймаут в 5 секунд для всех запросов к версии v1. Это полезно, чтобы предотвратить долгие запросы от замедления всей системы.

Применение политики ретрая

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-service
spec:
    hosts:
    - my-service
    http:
    - route:
        - destination:
            host: my-service
            subset: v1
          retries:
            attempts: 3
            perTryTimeout: 2s

Здесь мы настраиваем повторные попытки для запросов к версии v1. Если запрос не удается выполнить с первой попытки, Istio будет предпринимать до 3 попыток с таймаутом 2 секунды на каждой.

Балансировка нагрузки с Round Robin

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-service
spec:
    hosts:
    - my-service
    http:
    - route:
        - destination:
            host: my-service
            subset: v1
          weight: 70
        - destination:
            host: my-service
            subset: v2
          weight: 30

В этом примере мы настраиваем виртуальный сервис для балансировки нагрузки между версиями v1 и v2 с использованием весов. 70% трафика направляется к версии v1, а 30% - к версии v2.

Мониторинг с Istio

1. Настройка сбора метрик с Istio

Для начала, вам необходимо настроить сбор метрик с Istio. Это делается путем создания соответствующих ресурсов Kubernetes и настройки Istio, чтобы он начал собирать данные. Вот пример Kubernetes манифеста для настройки сбора метрик:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  values:
    global:
      proxy:
        tracer: zipkin
      telemetry:
        v2:
          prometheus:
            enabled: true

Этот манифест включает сбор метрик с помощью Prometheus.

2. Визуализация метрик в Grafana

Вы можете настроить интеграцию Grafana и Prometheus с Istio, чтобы легко создавать дашборды и отслеживать производительность ваших микросервисов.

Создание дашборда для мониторинга HTTP запросов

В Grafana, к примеру, вы можете создать дашборд для мониторинга HTTP запросов ваших микросервисов. Например, вы можете отслеживать количество запросов, среднее время ответа, и многое другое:

{
  "panels": [
    {
      "title": "HTTP Requests",
      "type": "graph",
      "targets": [
        {
          "expr": "istio_requests_total",
          "legendFormat": "{{destination_service_name}} - {{response_code}}"
        }
      ],
      "legend": {
        "show": true
      },
      "aliasColors": {},
      "bars": false,
      "lines": true,
      "linewidth": 2,
      "nullPointMode": "null",
      "percentage": false,
      "span": 6,
      "stack": false,
      "steppedLine": false,
      "targets": [],
      "timeFrom": null,
      "timeShift": null
    }
  ],
  "title": "HTTP Request Metrics"
}

Этот дашборд отслеживает общее количество HTTP запросов и группирует их по кодам ответов и сервисам назначения.

Одной из основных особенностей Istio - это возможность создавать пользовательские метрики и дашборды для мониторинга конкретных аспектов вашего приложения. Это позволяет вам точно отслеживать показатели, которые важны именно для вас.

Создание пользовательской метрики с помощью Prometheus

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

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-service
spec:
  selector:
    matchLabels:
      app: my-service
  endpoints:
  - port: http
  metricRelabelings:
  - sourceLabels: [__name__]
    targetLabel: metric

Создание пользовательского дашборда в Grafana

Для создания пользовательского дашборда в Grafana, вы можете использовать PromQL (Prometheus Query Language) для запроса и визуализации ваших пользовательских метрик.

Анализ данных о производительности микросервисов позволяет выявлять и решать проблемы быстро. Istio предоставляет мощные средства для анализа данных о производительности, такие как гистограммы распределения времени ответа и трассировка запросов. Вы можете использовать инструменты, такие как Jaeger, для визуализации трассировки запросов и выявления узких мест в вашей микросервисной архитектур

1. Использование Jaeger для трассировки запросов

Jaeger - это инструмент для сбора, визуализации и анализа трассировки запросов. Вы можете интегрировать Istio с Jaeger, чтобы получить детальную информацию о том, как запросы проходят через ваши микросервисы.

Интеграция Jaeger с Istio

Для интеграции Jaeger с Istio, вы можете создать соответствующие ресурсы Kubernetes и настроить правила для трассировки запросов. Пример Kubernetes манифеста:

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: my-jaeger
spec:
  strategy: AllInOne
  allInOne:
    image: jaegertracing/all-in-one

Этот манифест создает экземпляр Jaeger, интегрированный с Istio.

Визуализация трассировки запросов в Jaeger

После интеграции Jaeger с Istio, вы можете использовать интерфейс Jaeger для визуализации трассировки запросов. Это позволяет вам легко выявлять проблемы в производительности и отслеживать, как запросы проходят через ваши микросервисы.

Заключение

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

Статья подготовлена в рамках набора на онлайн-курс «Microservice Architecture». Чтобы узнать, достаточно ли ваших знаний для прохождения программы курса, пройдите вступительное тестирование.

Комментарии (3)


  1. hVostt
    28.10.2023 16:43
    +1

    Спасибо! Подскажите пожалуйста, как настроить istio, чтобы в приложения (бекенд) отдавались запросы с заголовками traceparent и tracestate по стандартам OpenTelemetry (https://www.w3.org/TR/trace-context/)? Так как современные ПО умеют получать такие заголовки и пробрасывать спаны дальше, не теряя контекст? Если трассировка, отправляемая в Jaeger будет обрываться на бекенде, то мы теряем львиную и самую полезную информацию.


    1. badcasedaily1 Автор
      28.10.2023 16:43

      Нужно включить мониторинг запросов настройках Istio. Это обычно выполняется при установке Istio. Но вообще, вы можете использовать эту команду в баш:

      istioctl manifest apply --set values.telemetry.enabled=true
      

      Далее создаем конф. маршрута для бэкенда,нужно настроить маршруты Istio, чтобы передавать заголовки traceparent и tracestate. для этого вы можете использовать манифест VirtualService:

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: my-backend
      spec:
        hosts:
        - my-backend-service
        http:
        - match:
          - uri:
              prefix: /
          route:
          - destination:
              host: my-backend-service
              headers:
                request:
                  set:
                    traceparent: request.headers["traceparent"]
                    tracestate: request.headers["tracestate"]
      
      

      далее

      istioctl manifest apply
      


  1. kiriydmitriy
    28.10.2023 16:43

    Прикольно. К каждому пакету добавляется дикое latency и похоже это никого не парит .интересная модель работы