Что такое Istio и когда его внедрять
Istio - это сервисная сетка для Kubernetes. Она ставит рядом с каждым подом прокси-контейнер Envoy, который перехватывает входящий и исходящий трафик. Приложение продолжает работать, но управление маршрутизацией, шифрованием и сбором метрик выносится на уровень инфраструктуры.
Главные компоненты Istio: control plane (istiod) и data plane (sidecar-прокси). Control plane отвечает за конфигурацию и выдачу сертификатов. Data plane выполняет правила маршрутизации.
Настройка сводится к трём шагам: установить control plane, включить sidecar-инъекцию в нужных namespace и проверить, что трафик между сервисами проходит через mesh. Ниже все шаги разобраны с командами и YAML-манифестами.
Когда Istio оправдан: микросервисная архитектура, десятки и сотни подов, потребность в канареечных деплоях, распределённой трассировке, mTLS и тонкой маршрутизации. Когда можно обойтись без него: небольшой кластер с монолитом или парой сервисов, отсутствие требований к security и observability на уровне сети.
Более широкий обзор критериев выбора и production-чек-лист есть в статье Практическое руководство по внедрению Istio в Kubernetes.
Подготовка кластера и установка Istio
Для установки нужен кластер Kubernetes с правами cluster-admin и набор утилит: kubectl, helm (опционально), curl. Если кластера нет, для тестового стенда подойдёт облачный Kubernetes, например Timeweb Cloud.
Проверка совместимости версий Kubernetes и Istio
Проверьте версию кластера:
kubectl version --short
Каждая ветка Istio поддерживает конкретный диапазон версий Kubernetes. Например, Istio 1.23 работает с Kubernetes 1.27-1.30, Istio 1.24 с 1.28-1.31. Точную таблицу сверяйте в документации Istio. Несовместимость версий частая причина ошибок при старте.
Проверьте, что кластер доступен:
kubectl cluster-info
Установите istioctl. Самый быстрый способ:
curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH
Проверьте версию:
istioctl version
Выбор профиля установки: demo, default или production
Профили управляют набором компонентов и параметрами. Посмотреть список:
istioctl profile list
| Профиль | Компоненты | Когда использовать |
|---|---|---|
| demo | istiod, ingressgateway, egressgateway, Kiali, Prometheus, Grafana, Jaeger | Для обучения и локальных стендов |
| default | istiod, ingressgateway, egressgateway | Минимальный набор для production |
| production | istiod, ingressgateway | Строгие лимиты и настройки безопасности |
Для первого запуска выбирайте demo. Он разворачивает все инструменты наблюдаемости и сразу даёт полный стек. Для рабочего кластера используйте default или production с собственными настройками.
Установите Istio:
istioctl install --set profile=demo -y
В namespace istio-system появятся поды istiod и шлюзы. Проверьте состояние:
kubectl get pods -n istio-system
kubectl get svc -n istio-system
Все поды должны быть Running или Completed. Если istiod в CrashLoopBackOff, смотрите логи:
kubectl logs -n istio-system deployment/istiod
Настройка автоматической инъекции sidecar-контейнеров
Sidecar - это контейнер istio-proxy на базе Envoy. Он добавляется в каждый под и перехватывает трафик. Автоматическая инъекция включается label на namespace.
Добавьте label:
kubectl label namespace default istio-injection=enabled
Проверьте label у всех namespace:
kubectl get namespaces -L istio-injection
Теперь новые поды в namespace default будут получать sidecar автоматически. Существующие поды не изменятся, их нужно перезапустить.
Для особых случаев можно использовать ручную инъекцию:
istioctl kube-inject -f app.yaml | kubectl apply -f -
В повседневной работе label удобнее.
Проверка sidecar в поде: ожидаемое количество контейнеров
Разверните простое приложение:
kubectl create deployment nginx --image=nginx
kubectl scale deployment nginx --replicas=1
Посмотрите поды:
kubectl get pods
В колонке READY должно быть 2/2: один контейнер приложения, один istio-proxy.
Детальная проверка:
kubectl describe pod nginx-<pod-id>
В секции Containers должны быть nginx и istio-proxy. Если istio-proxy нет, инъекция не сработала.
Что делать, если инъекция не сработала
Частые причины:
- Нет label на namespace. Проверьте:
kubectl get namespace default -L istio-injection. - Неправильное имя namespace. Label ставится на namespace, а не на deployment.
- Конфликт с другими admission webhooks. Проверьте логи istiod:
kubectl logs -n istio-system deployment/istiod. - Под создан до включения label. Удалите под, deployment создаст новый с sidecar.
Проверьте, что webhook зарегистрирован:
kubectl get mutatingwebhookconfigurations
Там должен быть istio-sidecar-injector. Если его нет, переустановите Istio или проверьте Helm-релиз.
Проверка, что трафик действительно проходит через mesh
Установка и инъекция не гарантируют, что трафик перехватывается. Нужна проверка.
Сгенерируйте тестовый трафик. Запустите curl-контейнер в том же namespace и обратитесь к nginx:
kubectl run curl-test --image=curlimages/curl -it --rm -- sh
curl http://nginx
Если ответ пришёл, часть трафика уже проходит через sidecar. Теперь проверьте логи прокси в поде nginx:
kubectl logs nginx-<pod-id> -c istio-proxy
В логах появятся записи о входящих и исходящих соединениях.
Использование Kiali для визуализации трафика
Профиль demo включает Kiali. Откройте дашборд:
istioctl dashboard kiali
Или через port-forward:
kubectl port-forward -n istio-system svc/kiali 20001:20001
В графе сервисов вы увидите nginx и curl-test, соединённые зелёными линиями. Зелёный цвет означает успешные ответы. Красные линии указывают на ошибки.
Проверка метрик и логов sidecar
Метрики Istio собирает Prometheus. Запросите счётчик запросов:
kubectl -n istio-system port-forward svc/prometheus 9090:9090
Откройте в браузере Prometheus и выполните запрос:
istio_requests_total
Если метрика появляется, sidecar передаёт телеметрию в control plane. Для конкретного сервиса уточните запрос по метке destination_service.
Логи конкретного sidecar:
kubectl logs <pod> -c istio-proxy --tail=50
Типичные ошибки первого запуска и их устранение
Ниже собраны проблемы, которые чаще всего ломают первый запуск.
Недостаточно ресурсов для sidecar
Симптом: под в состоянии OOMKilled, контейнер istio-proxy перезапускается. Причина: лимиты памяти по умолчанию слишком малы для приложения или Envoy при высокой нагрузке.
Решение: задайте ресурсы sidecar через аннотацию:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
annotations:
sidecar.istio.io/proxyCPU: '100m'
sidecar.istio.io/proxyMemory: '256Mi'
spec:
containers:
- name: nginx
image: nginx
Либо глобально через meshConfig.
Конфликт портов с приложением
Симптом: sidecar не стартует или приложение не может открыть порт. Причина: приложение использует зарезервированные порты Istio: 15000, 15001, 15006, 15021, 15090.
Решение: измените порт приложения или исключите его из перехвата:
traffic.sidecar.istio.io/excludeInboundPorts: '15000'
Если порт нужен приложению, перенесите его на другой порт. Не отключайте перехват без острой необходимости, это ломает mesh для этого пода.
Базовая маршрутизация трафика: пример VirtualService и DestinationRule
Чтобы убедиться в работе traffic management, настройте распределение трафика между двумя версиями сервиса. Разверните v1 и v2 одного приложения:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-v1
spec:
replicas: 1
selector:
matchLabels:
app: web
version: v1
template:
metadata:
labels:
app: web
version: v1
spec:
containers:
- name: web
image: nginx
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-v2
spec:
replicas: 1
selector:
matchLabels:
app: web
version: v2
template:
metadata:
labels:
app: web
version: v2
spec:
containers:
- name: web
image: httpd
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
DestinationRule описывает подмножества:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: web
spec:
host: web
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
VirtualService направляет 90% трафика в v1 и 10% в v2:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: web
spec:
hosts:
- web
http:
- route:
- destination:
host: web
subset: v1
weight: 90
- destination:
host: web
subset: v2
weight: 10
Проверьте распределение серией запросов:
kubectl run curl-test --image=curlimages/curl -it --rm -- sh
for i in $(seq 1 20); do curl -s http://web | grep -o 'Welcome to nginx\|It works'; done
Примерно 9 из 10 ответов должны приходить от v1. Расширенные сценарии canary и A/B-тестов разобраны в статье продвинутая маршрутизация с Istio и Linkerd.
Заключение: что дальше?
Вы установили Istio, включили sidecar-инъекцию, проверили трафик и настроили базовую маршрутизацию. Это минимальный рабочий стенд.
Следующие темы: mTLS и политики безопасности, расширенная маршрутизация, fault injection, интеграция с внешними сервисами. Если sidecar-модель кажется тяжёлой, изучите Istio Ambient Mode. Перед production проверьте систему по чек-листу из статьи типовые ошибки при внедрении Service Mesh.
Оставьте комментарий, если столкнулись с ошибкой, которой нет в этой статье.