Стадия жизненного цикла модуля: General Availability
У модуля есть требования для установки
Circuit Breaker
Для выявления проблемных эндпоинтов используются настройки outlierDetection в кастомном ресурсе DestinationRule.
Более подробно алгоритм Outlier Detection описан в документации Envoy.
Пример:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews-cb-policy
spec:
host: reviews.prod.svc.cluster.local
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100 # Максимальное число соединений в сторону host, суммарно для всех эндпоинтов.
http:
maxRequestsPerConnection: 10 # Каждые 10 запросов, соединение будет пересоздаваться.
outlierDetection:
consecutive5xxErrors: 7 # Допустимо 7 ошибок (включая пятисотые, TCP-таймауты и HTTP-таймауты)
interval: 5m # в течение пяти минут,
baseEjectionTime: 15m # после которых эндпоинт будет исключен из балансировки на 15 минут.
А также для настройки HTTP-таймаутов используется ресурс VirtualService. Эти таймауты также учитываются при подсчете статистики ошибок на эндпоинтах.
Пример:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: my-productpage-rule
namespace: myns
spec:
hosts:
- productpage
http:
- timeout: 5s
route:
- destination:
host: productpage
Балансировка gRPC
Чтобы балансировка gRPC-сервисов заработала автоматически, присвойте имя с префиксом или значением grpc для порта в соответствующем сервисе.
Locality Failover
При необходимости ознакомьтесь с документацией Istio о Locality Failover.
Istio позволяет настроить приоритетный географический failover между эндпоинтами. Для определения зоны Istio использует лейблы узлов с соответствующей иерархией:
topology.istio.io/subzone;topology.kubernetes.io/zone;topology.kubernetes.io/region.
Это полезно для межкластерного failover при использовании совместно с мультикластером.
Для включения Locality Failover используется ресурс DestinationRule, в котором также необходимо настроить outlierDetection.
Пример:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: helloworld
spec:
host: helloworld
trafficPolicy:
loadBalancer:
localityLbSetting:
enabled: true # Включили Locality Failover.
outlierDetection: # outlierDetection включить обязательно.
consecutive5xxErrors: 1
interval: 1s
baseEjectionTime: 1m
Retry
С помощью ресурса VirtualService можно настроить Retry для запросов.
По умолчанию при возникновении ошибок все запросы (включая POST-запросы) выполняются повторно до трех раз.
Пример:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- route:
- destination:
host: ratings.prod.svc.cluster.local
retries:
attempts: 3
perTryTimeout: 2s
retryOn: gateway-error,connect-failure,refused-stream
Canary
Istio отвечает лишь за гибкую маршрутизацию запросов, которая опирается на спецзаголовки запросов (например, cookie) или просто на случайность. За настройку этой маршрутизации и переключение между канареечными версиями отвечает CI/CD-система.
Подразумевается, что в одном неймспейсе развёрнуты два Deployment с разными версиями приложения. У подов разных версий разные лейблы (version: v1 и version: v2).
Требуется настроить два кастомных ресурса:
- DestinationRule с описанием, как идентифицировать разные версии вашего приложения (subset);
- VirtualService с описанием, как распределять трафик между разными версиями приложения.
Пример:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: productpage-canary
spec:
host: productpage
# subset доступны только при обращении к хосту через VirtualService из пода под управлением Istio.
# Эти subset должны быть указаны в маршрутах.
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
Распределение по наличию cookie
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: productpage-canary
spec:
hosts:
- productpage
http:
- match:
- headers:
cookie:
regex: "^(.*;?)?(canary=yes)(;.*)?"
route:
- destination:
host: productpage
subset: v2 # Ссылка на subset из DestinationRule.
- route:
- destination:
host: productpage
subset: v1
Распределение по вероятности
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: productpage-canary
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1 # Ссылка на subset из DestinationRule.
weight: 90 # Процент трафика, который получат поды с лейблом version: v1.
- route:
- destination:
host: productpage
subset: v2
weight: 10
Ingress для публикации приложений
Istio Ingress Gateway
Кастомный ресурс IngressIstioController разворачивает выделенный прокси Istio Ingress Gateway. Каждый экземпляр контроллера получает собственный класс шлюза, и нужный экземпляр выбирается из ресурса Istio Gateway по соответствующему лейблу istio.deckhouse.io/ingress-gateway-class. Модуль управляет рабочей нагрузкой шлюза и его ресурсом Service, тогда как ресурсы Gateway и маршрутизации (VirtualService) остаются под вашим управлением.
Начните с создания IngressIstioController. В примере ниже HTTP и HTTPS публикуются на выбранных frontend-узлах через host-порты:
apiVersion: deckhouse.io/v1alpha1
kind: IngressIstioController
metadata:
name: main
spec:
# Значение, которое выбирается ресурсами Gateway через лейбл istio.deckhouse.io/ingress-gateway-class.
ingressGatewayClass: istio-hp
# IngressIstioController поддерживает инлеты LoadBalancer, NodePort и HostPort.
inlet: HostPort
hostPort:
httpPort: 80
httpsPort: 443
nodeSelector:
node-role.deckhouse.io/frontend: ""
tolerations:
- effect: NoExecute
key: dedicated.deckhouse.io
operator: Equal
value: frontend
resourcesRequests:
mode: VPA
Обратите внимание, что ресурс Secret с TLS для ingress gateway должен быть создан в пространстве имён d8-ingress-istio, а не в пространстве имён приложения — эту деталь легко упустить.
apiVersion: v1
kind: Secret
metadata:
name: app-tls-secret
namespace: d8-ingress-istio # Обратите внимание, неймспейс не является app-ns.
type: kubernetes.io/tls
data:
tls.crt: |
<tls.crt data>
tls.key: |
<tls.key data>
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: gateway-app
namespace: app-ns
spec:
selector:
# Селектор лейблов для использования Istio Ingress Gateway main-hp.
istio.deckhouse.io/ingress-gateway-class: istio-hp
servers:
- port:
# Стандартный шаблон для использования протокола HTTP.
number: 80
name: http
protocol: HTTP
hosts:
- app.example.com
- port:
# Стандартный шаблон для использования протокола HTTPS.
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
# Ресурс Secret с сертификатом и ключом, который должен быть создан в нейсмпейсе d8-ingress-istio.
# Поддерживаемые форматы ресурсов Secret можно посмотреть по ссылке https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/#key-formats.
credentialName: app-tls-secret
hosts:
- app.example.com
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vs-app
namespace: app-ns
spec:
gateways:
- gateway-app
hosts:
- app.example.com
http:
- route:
- destination:
host: app-svc
Полный список настроек контроллера — аннотации балансировщика нагрузки, топология сети, планирование и управление ресурсами — приведён в справочнике по кастомному ресурсу IngressIstioController.
Сохранение атрибутов клиента за внешними прокси
Когда шлюз развёрнут за другими прокси или балансировщиками нагрузки (например, за облачным балансировщиком или обратным прокси), настройте spec.networkTopology, чтобы шлюз мог корректно извлекать исходные атрибуты клиента, например IP-адрес источника. Подробнее — в документации Istio о топологии сети шлюза.
Используйте numTrustedProxies, когда вышестоящие прокси передают IP-адрес клиента в заголовке X-Forwarded-For. Укажите количество доверенных прокси, развёрнутых перед шлюзом, чтобы Istio извлекал корректный адрес клиента и заполнял заголовок X-Envoy-External-Address для вышестоящих сервисов. Например, если перед шлюзом находятся облачный балансировщик и обратный прокси, укажите значение 2:
apiVersion: deckhouse.io/v1alpha1
kind: IngressIstioController
metadata:
name: main
spec:
ingressGatewayClass: istio-hp
inlet: LoadBalancer
networkTopology:
numTrustedProxies: 2
nodeSelector:
node-role.deckhouse.io/frontend: ""
resourcesRequests:
mode: VPA
Используйте proxyProtocol, когда вышестоящий L4/TCP-балансировщик передаёт атрибуты клиента через PROXY-протокол, а не через HTTP-заголовки. При включении этого параметра шлюз начинает разбирать заголовок PROXY-протокола во входящих TCP-соединениях:
apiVersion: deckhouse.io/v1alpha1
kind: IngressIstioController
metadata:
name: main
spec:
ingressGatewayClass: istio-hp
inlet: LoadBalancer
networkTopology:
proxyProtocol: true
nodeSelector:
node-role.deckhouse.io/frontend: ""
resourcesRequests:
mode: VPA
numTrustedProxies и proxyProtocol можно использовать вместе. Если настроены оба параметра и входящий запрос содержит заголовок X-Forwarded-For, Istio использует доверенную цепочку X-Forwarded-For вместо атрибутов PROXY-протокола.
Управление запросами ресурсов шлюза
Используйте spec.resourcesRequests для управления запросами (requests) CPU и памяти для подов ingress gateway. Доступны два режима:
-
Static— запросы задаются напрямую и остаются фиксированными:apiVersion: deckhouse.io/v1alpha1 kind: IngressIstioController metadata: name: main spec: ingressGatewayClass: istio-hp inlet: HostPort hostPort: httpPort: 80 httpsPort: 443 resourcesRequests: mode: Static static: cpu: 100m memory: 128Mi -
VPA— Vertical Pod Autoscaler изменяет запросы в заданных пределахmin/max. Начиная с версии DP 1.75, рекомендуемым режимом VPA являетсяInPlaceOrRecreate: он изменяет ресурсы пода «на месте» (in-place), если это поддерживается кластером, и пересоздаёт под в противном случае (устаревший режимAutoвсегда пересоздаёт под):apiVersion: deckhouse.io/v1alpha1 kind: IngressIstioController metadata: name: main spec: ingressGatewayClass: istio-hp inlet: HostPort hostPort: httpPort: 80 httpsPort: 443 resourcesRequests: mode: VPA vpa: mode: InPlaceOrRecreate cpu: min: 100m max: 1000m memory: min: 128Mi max: 2000Mi
Ingress NGINX
Для работы с Ingress NGINX требуется подготовить:
- Ingress-контроллер, добавив к нему сайдкар от Istio. В нашем случае — включить параметр
enableIstioSidecarв кастомном ресурсе IngressNginxController модуля ingress-nginx. - Ingress-ресурс, который ссылается на Service. Обязательные аннотации для Ingress-ресурса:
nginx.ingress.kubernetes.io/service-upstream: "true"— с этой аннотацией Ingress-контроллер будет отправлять запросы на ClusterIP сервиса (из диапазона Service CIDR) вместо того, чтобы слать их напрямую в поды приложения. Sidecar-контейнерistio-proxyперехватывает трафик только в сторону диапазона Service CIDR, остальные запросы отправляются напрямую;nginx.ingress.kubernetes.io/upstream-vhost: myservice.myns.svc— с данной аннотацией сайдкар сможет идентифицировать прикладной сервис, для которого предназначен запрос.
Примеры:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: productpage
namespace: bookinfo
annotations:
# Просим nginx проксировать трафик на ClusterIP вместо собственных IP подов.
nginx.ingress.kubernetes.io/service-upstream: "true"
# В Istio вся маршрутизация осуществляется на основе `Host:` заголовка запросов.
# Чтобы не сообщать Istio о существовании внешнего домена `productpage.example.com`,
# мы просто используем внутренний домен, о котором Istio осведомлен.
nginx.ingress.kubernetes.io/upstream-vhost: productpage.bookinfo.svc
spec:
rules:
- host: productpage.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: productpage
port:
number: 9080
apiVersion: v1
kind: Service
metadata:
name: productpage
namespace: bookinfo
spec:
ports:
- name: http
port: 9080
selector:
app: productpage
type: ClusterIP
Примеры настройки авторизации
Алгоритм принятия решения
Как только для приложения создается AuthorizationPolicy, начинает работать следующий алгоритм принятия решения о судьбе запроса:
- Если запрос попадает под политику DENY — запретить запрос.
- Если для данного приложения нет политик ALLOW — разрешить запрос.
- Если запрос попадает под политику ALLOW — разрешить запрос.
- Все остальные запросы — запретить.
Иными словами, если вы явно что-то запретили, работает только ваш запрет. Если же вы что-то явно разрешили, теперь разрешены только явно одобренные запросы (запреты никуда не исчезают и имеют приоритет).
Для работы политик, основанных на высокоуровневых параметрах, таких как неймспейсы или principal, необходимо, чтобы все вовлеченные сервисы работали под управлением Istio. Также между приложениями должен быть организован Mutual TLS.
Примеры:
-
Запретим POST-запросы для приложения myapp. Отныне, так как для приложения появилась политика, согласно алгоритму выше будут запрещены только POST-запросы к приложению.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-post-requests namespace: foo spec: selector: matchLabels: app: myapp action: DENY rules: - to: - operation: methods: ["POST"] -
Для приложения создана разрешающая политика ALLOW. При ней будут разрешены только запросы из неймспейса
bar, остальные запрещены.apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: selector: matchLabels: app: myapp action: ALLOW # default, можно не указывать. rules: - from: - source: namespaces: ["bar"] -
Здесь для приложения создана политика ALLOW. При этом она не содержит ни одного правила, вследствие чего ни один запрос не попадает под критерии фильтрации. Однако сам факт наличия политики активирует алгоритм проверки, где всё, что не разрешено явно, считается запрещенным. В данном случае блокируются абсолютно все запросы
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: selector: matchLabels: app: myapp action: ALLOW # default, можно не указывать. rules: [] -
Здесь для приложения создана политика ALLOW (это default) и одно пустое правило. Под это правило попадает любой запрос и автоматически получает разрешение.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all namespace: foo spec: selector: matchLabels: app: myapp rules: - {}
Запретить все действия в рамках неймспейса foo
Два способа:
-
Запретить явно. Здесь мы создаем политику DENY с единственным универсальным фильтром
{}, под который попадают все запросы:apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: action: DENY rules: - {} -
Неявно. Здесь мы создаем политику ALLOW (по умолчанию), но не создаем ни одного фильтра, так что ни один запрос под нее не попадет и будет автоматически запрещен.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: {}
Запретить доступ только из неймспейса foo
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-from-ns-foo
namespace: myns
spec:
action: DENY
rules:
- from:
- source:
namespaces: ["foo"]
Разрешить запросы только в рамках нашего неймспейса foo
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-intra-namespace-only
namespace: foo
spec:
action: ALLOW
rules:
- from:
- source:
namespaces: ["foo"]
Разрешить из любого места в нашем кластере
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all-from-my-cluster
namespace: myns
spec:
action: ALLOW
rules:
- from:
- source:
principals: ["mycluster.local/*"]
Разрешить любые запросы только кластеров foo или bar
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all-from-foo-or-bar-clusters-to-ns-baz
namespace: baz
spec:
action: ALLOW
rules:
- from:
- source:
principals: ["foo.local/*", "bar.local/*"]
Разрешить любые запросы только от сущностей из неймспейса baz кластеров foo или bar
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all-from-foo-or-bar-clusters-to-ns-baz
namespace: baz
spec:
action: ALLOW
rules:
- from:
- source: # Правила ниже логически перемножаются.
namespaces: ["baz"]
principals: ["foo.local/*", "bar.local/*"]
Разрешить из любого кластера (по mTLS)
Если есть запрещающие правила, у них будет приоритет. Подробнее — в разделе «Алгоритм принятия решения».
Пример:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all-from-any-cluster-with-mtls
namespace: myns
spec:
action: ALLOW
rules:
- from:
- source:
principals: ["*"] # Принудительное использование mTLS.
Разрешить вообще откуда угодно (в том числе без mTLS)
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all-from-any
namespace: myns
spec:
action: ALLOW
rules: [{}]
Устройство федерации из двух кластеров с помощью кастомного ресурса IstioFederation
Доступно в редакциях Enterprise Edition, Ultimate, Certified Security Edition Pro, DP Certified Pro.
Федерация работает только с рабочими нагрузками в режиме сайдкаров. Подробнее — в разделе Ограничения ambient mesh.
Cluster A:
apiVersion: deckhouse.io/v1alpha1
kind: IstioFederation
metadata:
name: cluster-b
spec:
metadataEndpoint: https://istio.k8s-b.example.com/metadata/
trustDomain: cluster-b.local
Cluster B:
apiVersion: deckhouse.io/v1alpha1
kind: IstioFederation
metadata:
name: cluster-a
spec:
metadataEndpoint: https://istio.k8s-a.example.com/metadata/
trustDomain: cluster-a.local
Устройство мультикластера из двух кластеров с помощью ресурса IstioMulticluster
Доступно в редакциях Enterprise Edition, Ultimate, Certified Security Edition Pro, DP Certified Pro.
Мультикластер работает только с рабочими нагрузками в режиме сайдкаров. Подробнее — в разделе Ограничения ambient mesh.
Cluster A:
apiVersion: deckhouse.io/v1alpha1
kind: IstioMulticluster
metadata:
name: cluster-b
spec:
metadataEndpoint: https://istio.k8s-b.example.com/metadata/
Cluster B:
apiVersion: deckhouse.io/v1alpha1
kind: IstioMulticluster
metadata:
name: cluster-a
spec:
metadataEndpoint: https://istio.k8s-a.example.com/metadata/
Ambient mesh
Доступно только в Enterprise Edition и Certified Security Edition Pro.
Поддержка ambient mesh является экспериментальной и не рекомендуется для использования в production-окружении.
Рабочие нагрузки в режиме ambient не могут участвовать в федерации и мультикластере. Подробнее — в разделе Ограничения ambient mesh.
Упоминаемые в этом подразделе компоненты ambient mesh описаны на странице с основным описанием модуля.
Включение ambient mesh
Для работы режима ambient требуется режим перенаправления трафика CNIPlugin и Istio 1.25 или более новой версии.
Пример конфигурации модуля с включенным режимом ambient:
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: istio
spec:
enabled: true
version: 2
settings:
dataPlane:
trafficRedirectionSetupMode: CNIPlugin
ambient:
enabled: true
После включения модуль запускает DaemonSet ztunnel и контроллер waypoint. Чтобы подключить рабочие нагрузки к сети ambient, выполните следующие шаги.
Подключение рабочих нагрузок к сети ambient (L4)
Добавьте лейбл istio.io/dataplane-mode=ambient на неймспейс, чтобы захватывать трафик его подов с помощью ztunnel. Это позволяет использовать возможности уровня L4 (Mutual TLS, идентификация, авторизация L4) без сайдкара:
d8 k label namespace myns istio.io/dataplane-mode=ambient
Добавление waypoint для возможностей L7
Чтобы получить возможности уровня L7 (маршрутизация HTTP, авторизация L7, более подробная телеметрия), создайте в неймспейсе ресурс WaypointInstance.
Пример ресурса WaypointInstance, который создаёт waypoint для всех рабочих нагрузок и сервисов неймспейса:
apiVersion: network.deckhouse.io/v1alpha1
kind: WaypointInstance
metadata:
name: main
namespace: myns
spec:
waypointFor: All
replicasManagement:
mode: Static
static:
replicas: 2
resourcesManagement:
mode: VPA
vpa:
mode: InPlaceOrRecreate
cpu:
min: 100m
max: 1000m
memory:
min: 128Mi
max: 2000Mi
Контроллер создаёт инфраструктуру waypoint (Deployment, Service, Gateway, VPA, а также PDB — если эффективное количество реплик >= 2). Контроллер не подключает рабочие нагрузки к waypoint. Для этого используйте лейбл istio.io/use-waypoint.
Чтобы подключить все рабочие нагрузки и сервисы неймспейса к waypoint, выполните следующую команду:
d8 k label namespace myns istio.io/use-waypoint=main
Чтобы подключить отдельный сервис или рабочую нагрузку, выполните следующую команду:
d8 k -n myns label service myservice istio.io/use-waypoint=main
Отключение ambient mesh
Перед отключением режима ambient удалите все ресурсы WaypointInstance. При отключенном режиме ambient контроллер waypoint не запускается и не может согласовывать или удалять ресурсы waypoint. Это приводит к появлению orphan-ресурсов, о чём Deckhouse Platform (DP) сигнализирует алертом D8IstioActiveWaypointsWithAmbientDisabled.
Чтобы отключить режим ambient, выполните следующие шаги:
-
Проверьте наличие ресурсов WaypointInstance и при необходимости удалите их с помощью следующих команд:
d8 k get waypointinstance -A d8 k -n myns delete waypointinstance main -
Отключите режим, установив значение
falseдля параметраambient.enabledв настройках модуля.
Управление поведением data plane
Предотвращение завершения работы istio-proxy до завершения соединений основного приложения
По умолчанию в процессе остановки пода все контейнеры, включая istio-proxy, получают сигнал SIGTERM одновременно. Но некоторым приложениям для правильного завершения работы необходимо время и иногда дополнительная сетевая активность. Это невозможно, если istio-proxy завершился раньше.
Решение — добавить в istio-proxy preStop-хук для оценки активности прикладных контейнеров, а единственный доступный метод — это выявление сетевых сокетов приложения, и если таковых нет, тогда можно останавливать контейнер.
Аннотация ниже добавляет описанный выше preStop-хук в контейнер istio-proxy прикладного пода:
annotations:
inject.istio.io/templates: "sidecar,d8-hold-istio-proxy-termination-until-application-stops"
Telemetry API: метрики mesh и журналы доступа
Istio Telemetry API (telemetry.istio.io) — рекомендуемый способ настройки сбора данных о работе сервисов (метрики, access log, провайдеры трассировки) в связке с meshConfig.
Модуль поддерживает два режима, задаваемые параметром telemetryAPI.enabled:
| Режим | Поведение |
|---|---|
false (по умолчанию) |
Прежний режим (без Telemetry API): полностью включён telemetry.v2 в ресурсе Istio Operator / Istio (в том числе telemetry.v2.prometheus для Sail). Модуль всегда создаёт Telemetry d8-main в d8-istio только для access log; без spec.metrics / spec.tracing и без defaultProviders.metrics |
true |
Режим Telemetry API: в meshConfig выставлен defaultProviders.metrics: [prometheus], фильтры telemetry.v2 выключены; тот же Telemetry d8-main дополняется spec.metrics (и при настроенной трассировке — spec.tracing через deckhouse-tracing из tracing.collector). Формат журнала — в dataPlane.accessLog |
Включение режима Telemetry API
Пример ModuleConfig:
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: istio
spec:
version: 1
enabled: true
settings:
telemetryAPI:
enabled: true
Дождитесь применения манифеста Istio / IstioOperator в неймспейсе d8-istio и обновления конфигурации сайдкаров; при необходимости перезапустите прикладные поды после появления трафика, если метрики ещё не видны на дашбордах.
Проверка метрик и логов
После генерации трафика между сервисами mesh используйте команду:
# Текст метрик Prometheus через admin API сайдкара (в istio-proxy есть pilot-agent, curl нет).
istio_pod="$(
d8 k -n my-namespace get pods -l app=my-app -o jsonpath='{.items[0].metadata.name}'
)"
d8 k exec -n my-namespace "${istio_pod}" -c istio-proxy -- \
/usr/local/bin/pilot-agent request GET stats/prometheus | head
Пример успешного вывода:
# TYPE istio_requests_total counter
istio_requests_total{...} 12
istio_request_duration_milliseconds_bucket{...} 12
istio_request_bytes_bucket{...} 12
istio_response_bytes_bucket{...} 12
Если в выводе присутствуют метрики вида istio_requests_total, сбор настроен корректно.
Prometheus и Grafana
При включённом модуле operator-prometheus для метрик сайдкаров создаётся PodMonitor. Набор неймспейсов под мониторинг вычисляется автоматически по членству в mesh (инъекция Istio); чтобы исключить неймспейс из сборщика метрик, на объект Namespace можно выставить лейбл istio.deckhouse.io/discard-metrics: "true".
Если в Grafana пустые панели «workload», а control plane в порядке, необходимо определить причину отсутствия workload-метрик. Для этого проверьте:
- у подов есть сайдкар и лейбл
service.istio.io/canonical-name; - на неймспейсе приложения нет
istio.deckhouse.io/discard-metrics: "true".
Дополнительные политики Telemetry (по желанию)
Дополнительные Telemetry удобно задавать с явным workload‑селектором или targetRef. Два объекта Telemetry в одном неймспейсе без селектора провайдеру применять нельзя: Istio выдаёт IST0160. Модуль уже создаёт в d8-istio единственный объект без селектора (d8-main); второй там же без селектора не добавляйте без осознанной замены.
Пример ограниченной политики в прикладном неймспейсе:
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
name: team-a-prometheus-defaults
namespace: team-a
spec:
metrics:
- providers:
- name: prometheus
Тонкая настройка тегов и отключение отдельных метрик описана в документации Istio.
Трассировка через Telemetry API
tracing.collector — единая точка настройки mesh-wide экспорта (Zipkin или OpenTelemetry).
- При
telemetryAPI.enabled: falseиtracing.enabledtrue— только прежний режим:meshConfig.defaultConfig.tracing.zipkinизtracing.collector.zipkin.address(host:port, порт Jaeger Zipkin9411). Экспорт по OTLP (OpenTelemetry Protocol) требует режима Telemetry API. - При
telemetryAPI.enabled: trueиtracing.enabled: trueмодуль создаётdeckhouse-tracing, если заданыtracing.collector.opentelemetryserviceиport, или приtracing.collector.zipkin.address(при одновременной настройке приоритет у OpenTelemetry).defaultConfig.tracingне заполняется; вTelemetryd8-mainдобавляетсяspec.tracing(tracing.sampling→randomSamplingPercentage, по умолчанию1.0).
Нестандартные провайдеры — через Telemetry с selector в неймспейсе приложения, не второй CR без селектора в d8-istio (IST0160). Подробнее о настройке трассировки через Telemetry API — в документации Istio.
Пример — Telemetry API + Jaeger через Zipkin
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: istio
spec:
version: 1
enabled: true
settings:
telemetryAPI:
enabled: true
tracing:
enabled: true
sampling: 25
collector:
zipkin:
address: "jaeger-collector.observability.svc.cluster.local:9411"
Дождитесь применения CR Istio/IstioOperator из d8-istio; при проблемах с дашбордами перегенерируйте трафик и перепроверьте сайдкары.
Kiali
Для UI в Kiali задайте tracing.kiali (Jaeger UI + корректный gRPC endpoint для запросов Kiali из кластера).
Пример — mesh-wide OTLP через ModuleConfig
Экспорт OpenTelemetry в модуле соответствует распределённой трассировке с OpenTelemetry на Istio 1.25+. На Istio 1.21 используйте Zipkin/Jaeger через tracing.collector.zipkin или обновите ревизию control plane.
Разверните Collector, доступный из mesh, включите Telemetry API и укажите tracing.collector.opentelemetry. Модуль добавит провайдер deckhouse-tracing и spec.tracing в d8-main — не дописывайте OTLP вручную в meshConfig CR Istio / IstioOperator.
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: istio
spec:
version: 1
enabled: true
settings:
telemetryAPI:
enabled: true
tracing:
enabled: true
sampling: 10
collector:
opentelemetry:
service: opentelemetry-collector.observability.svc.cluster.local
port: 4317
Для HTTP OTLP задайте collector.opentelemetry.http.path (и при необходимости timeout) в параметре tracing.collector.opentelemetry.http.
Точечные настройки по workload — Telemetry с selector в неймспейсе приложения, ссылаясь на deckhouse-tracing (или на другой провайдер, который вы определите сами вне d8-istio). В d8-istio не создавайте второй Telemetry без селектора (IST0160).
Пример — трассировка только для части приложений
Используйте selector (или targetRef), чтобы Telemetry применялась только к подходящим подам — пример ниже безопасен с точки зрения IST0160. В одном неймспейсе без селектора может существовать не больше одного объекта Telemetry; не создавайте несколько манифестов без селектора в одном неймспейсе.
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
name: checkout-tracing
namespace: shop
spec:
selector:
matchLabels:
app: checkout
tracing:
- providers:
- name: jaeger-zipkin
randomSamplingPercentage: 100.0
Пример — отключить отправку спанов (например, у ingress)
В DP при включённом модуле ingress-nginx модуль Istio дополнительно создаёт Telemetry ingress-nginx-disable-span-reporting в неймспейсе d8-ingress-nginx и выставляет tracing.disableSpanReporting, чтобы контроллер с istio-proxy не отправлял спаны в бэкенд трассировки. Другие случаи — своим объектом:
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
name: no-tracing-example
namespace: my-namespace
spec:
tracing:
- disableSpanReporting: true
Возврат к прежнему режиму метрик
spec:
settings:
telemetryAPI:
enabled: false
Управляемые модулем Telemetry для этого режима будут убраны при следующей синхронизации; снова включится прежний telemetry.v2.
Диагностика Istio с помощью istioctl из debug-контейнера
В debug-контейнер DP входят бинарные файлы istioctl для поддерживаемых версий Istio. Используйте их, когда нужно проверить конфигурацию Istio, запустить анализаторы или получить конфигурацию Envoy из прикладных подов.
Перед запуском debug-контейнера создайте отдельный ServiceAccount и выдайте ему права, необходимые для команд istioctl, которые вы планируете запускать. Например, следующий манифест предоставляет права, необходимые для выполнения команды istioctl proxy-config для подов в одном прикладном неймспейсе:
apiVersion: v1
kind: ServiceAccount
metadata:
name: istioctl-debug
namespace: <debug-namespace>
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: istioctl-debug
namespace: <target-namespace>
rules:
- apiGroups: [""]
resources:
- pods
verbs:
- get
- list
- apiGroups: [""]
resources:
- pods/portforward
verbs:
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: istioctl-debug
namespace: <target-namespace>
subjects:
- kind: ServiceAccount
name: istioctl-debug
namespace: <debug-namespace>
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: istioctl-debug
Замените <debug-namespace> на неймспейс, в котором будет создан временный debug-под, а <target-namespace> — на неймспейс прикладного пода, который нужно проверить. Создайте ресурсы Role и RoleBinding для каждого целевого неймспейса, где istioctl должен получать доступ к подам.
Этот RBAC-манифест рассчитан на команды, которые обращаются к поду напрямую, например, к ресурсу вида <pod-name>.<target-namespace>. Если использовать имена типизированных ресурсов, например deployment/<name>, выдайте дополнительный доступ на чтение этих типов ресурсов, чтобы istioctl смог определить соответствующие поды.
Создание подов в системных неймспейсах, таких как d8-system, и использование системных ServiceAccount, таких как deckhouse, обычно требует прав уровня cluster-admin. Используйте отдельный ServiceAccount с минимально необходимыми правами.
Запустите временный debug-под со встроенным debug-образом:
IMG="$(d8 k -n d8-system get cm debug-container -o jsonpath='{.data.image}')"
d8 k -n <debug-namespace> run istioctl-debug \
--rm -it \
--restart=Never \
--image="$IMG" \
--overrides='{"spec":{"serviceAccountName":"istioctl-debug","automountServiceAccountToken":true}}' \
-- bash
Выберите минорную версию Istio, которая используется нужным control plane:
export ISTIOCTL_VERSION=1.21
Доступные значения: 1.21, 1.25 и 1.27. Также можно запустить конкретный бинарный файл напрямую: istioctl-1.21, istioctl-1.25 или istioctl-1.27.
Пример:
istioctl pc all <pod-name>.<target-namespace>
Для команд istioctl pc у целевого пода должен быть добавлен сайдкар istio-proxy. Если у целевого пода нет сайдкара, административный порт Envoy 15000 будет недоступен.
Приведённого выше RBAC-манифеста недостаточно для выполнения команд istioctl analyze или istioctl analyze -A. Для них нужны дополнительные права на чтение неймспейсов, а также Kubernetes- и Istio-ресурсов, которые проверяют анализаторы. Выдавайте такие права отдельно в соответствии с вашей политикой безопасности.
Ограничения режима перенаправления прикладного трафика CNIPlugin
В отличие от режима InitContainer, настройка перенаправления осуществляется в момент создании пода, а не в момент срабатывания init-контейнера istio-init. Это значит, что прикладные init-контейнеры не смогут взаимодействовать с остальными сервисами так как весь трафик будет перенаправлен на обработку в sidecar-контейнер istio-proxy, который ещё не запущен. Обходные пути:
- Запустить прикладной init-контейнер от пользователя с uid
1337. Запросы данного пользователя не перехватываются под управление Istio. - Исключить IP-адрес или порт сервиса из-под контроля Istio с помощью аннотаций
traffic.sidecar.istio.io/excludeOutboundIPRangesилиtraffic.sidecar.istio.io/excludeOutboundPorts.
Каждый из обходных вариантов выводит трафик из-под контроля Istio и отключает шифрование между прикладными сервисами.
UID 1337 зарезервирован Istio для сайдкар-контейнера istio-proxy. Не запускайте прикладные контейнеры с этим UID — их трафик полностью обойдёт Istio (без правил маршрутизации, mTLS и телеметрии). Используйте UID 1337 только в init-контейнерах, когда сетевые запросы нужны до запуска сайдкара.
Обновление Istio
Обновление control plane Istio
- DP позволяет установить несколько версий control plane одновременно:
- Одна глобальная, обслуживает неймспейсы или поды без явного указания версии (лейбл у неймспейсов
istio-injection: enabled). Настраивается параметромglobalVersion. - Остальные — дополнительные, обслуживают неймспейсы или поды с явным указанием версии (лейбл у неймспейса или пода
istio.io/rev: v1x21). Настраиваются параметромadditionalVersions.
- Одна глобальная, обслуживает неймспейсы или поды без явного указания версии (лейбл у неймспейсов
- Istio заявляет обратную совместимость между data plane и control plane в диапазоне двух минорных версий:

- Алгоритм обновления (для примера, с версии
1.21на версию1.25):- Добавить желаемую версию в параметр модуля additionalVersions (
additionalVersions: ["1.25"]).
- Добавить желаемую версию в параметр модуля additionalVersions (
- Дождаться появления соответствующего пода
istiod-v1x25-xxx-yyyв неймспейсеd8-istio. - Для каждого прикладного неймспейса, где включен Istio:
- поменять лейбл
istio-injection: enabledнаistio.io/rev: v1x25; - по очереди пересоздать поды в неймспейсе, параллельно контролируя работоспособность приложения.
- поменять лейбл
- Поменять настройку
globalVersionна1.25и удалитьadditionalVersions. - Убедиться, что старый под
istiodудалился. - Поменять лейблы прикладных неймспейсов на
istio-injection: enabled.
Чтобы найти все поды под управлением старой ревизии Istio (в примере — версия 21), выполните команду:
d8 k get pods -A -o json | jq --arg revision "v1x21" \
'.items[] | select(.metadata.annotations."sidecar.istio.io/status" // "{}" | fromjson |
.revision == $revision) | .metadata.namespace + "/" + .metadata.name'
Обновление до версии Istio 1.25 возможно только с версии 1.21.
Автоматическое обновление data plane Istio
Доступно в редакциях Enterprise Edition, Ultimate, Certified Security Edition Pro, DP Certified Pro.
Для автоматизации обновления istio-сайдкаров установите лейбл istio.deckhouse.io/auto-upgrade="true" на Namespace либо на отдельный ресурс — Deployment, DaemonSet или StatefulSet.
Автоматическое обновление срабатывает, когда у пода с istio-сайдкаром текущая версия data plane отличается от желаемой. Добавление версии в параметр additionalVersions само по себе не перезапускает прикладные поды. Обычно расхождение появляется в следующих случаях:
- изменился параметр
globalVersionдля неймспейса, где используется глобальная версия Istio (istio-injection=enabledилиistio.io/rev=default); - изменился лейбл
istio.io/revна неймспейсе или на поде; - обновилась патч-версия установленного control plane.
Перед перезапуском рабочей нагрузки модуль проверяет, что соответствующий control plane установлен и готов к работе. Затем модуль добавляет или обновляет аннотацию istio.deckhouse.io/full-version в spec.template.metadata.annotations, а Kubernetes выполняет штатный rollout. В одном неймспейсе модуль не начинает обновлять следующую рабочую нагрузку, пока предыдущая обновляемая рабочая нагрузка не готова.
Лейбл istio.deckhouse.io/auto-upgrade="true" должен быть установлен на той же сущности, которая определяет использование Istio для рабочей нагрузки:
- Если инъекция включена на уровне неймспейса с помощью
istio-injection=enabled,istio.io/rev=<REVISION>илиistio.io/rev=default, лейблistio.deckhouse.io/auto-upgrade="true"можно установить на этот же неймспейс. - Если сайдкар включён на уровне рабочей нагрузки или pod template, например с помощью
sidecar.istio.io/inject="true", установитеistio.deckhouse.io/auto-upgrade="true"на соответствующий Deployment, DaemonSet или StatefulSet. - Неймспейс с одним только лейблом
istio.deckhouse.io/auto-upgrade="true"не включает автоматическое обновление рабочей нагрузки, если инъекция настроена только на уровне рабочей нагрузки или pod template.
Автоматическое обновление поддерживается только для ресурсов Deployment, DaemonSet и StatefulSet. Ресурсы Job, CronJob, отдельные поды и кастомные контроллеры, в том числе Kruise AdvancedDaemonSet, не обрабатываются. Если ingress-контроллера управляется через AdvancedDaemonSet, лейбл istio.deckhouse.io/auto-upgrade="true" на таком ресурсе будет проигнорирован. Обновляйте такие ingress-контроллеры вручную по процедуре обновления control plane Istio и в разделе Ingress NGINX.
Для обнаружения подов, у которых патч-версия data plane отличается от версии control plane (сценарий, который закрывает автоматическое обновление), используйте алерт D8IstioDataPlaneVersionMismatch. Алерт D8IstioActualDataPlaneVersionNotEqualDesired сигнализирует о несовпадении ревизии Istio и обычно требует изменения лейблов неймспейса или пода перед обновлением сайдкаров.
Не удаляйте старый control plane Istio вручную во время обновления. Старый istiod и связанные с ним ресурсы удаляются автоматически после того, как в кластере не останется сайдкаров, подключённых к старой ревизии. Ручное удаление может нарушить штатную автоматику обновления.
Настройка ресурсов istio-proxy sidecar
Для переопределения глобальных ограничений ресурсов для сайдкара istio-proxy в отдельных рабочих нагрузках используются аннотации. Поддерживаются следующие аннотации:
Поддерживаемые аннотации
| Аннотация | Описание | Пример значения |
|---|---|---|
sidecar.istio.io/proxyCPU |
Запрос CPU для сайдкара | 200m |
sidecar.istio.io/proxyCPULimit |
Лимит CPU для сайдкара | "1" |
sidecar.istio.io/proxyMemory |
Запрос памяти для сайдкара | 128Mi |
sidecar.istio.io/proxyMemoryLimit |
Лимит памяти для сайдкара | 512Mi |
Примеры конфигурации
Для Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
# ...
spec:
template:
metadata:
annotations:
sidecar.istio.io/proxyCPU: 200m
sidecar.istio.io/proxyCPULimit: "1"
sidecar.istio.io/proxyMemory: 128Mi
sidecar.istio.io/proxyMemoryLimit: 512Mi
# ... остальная часть манифеста
Для ReplicaSet:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
# ...
spec:
template:
metadata:
annotations:
sidecar.istio.io/proxyCPU: 200m
sidecar.istio.io/proxyCPULimit: "1"
sidecar.istio.io/proxyMemory: 128Mi
sidecar.istio.io/proxyMemoryLimit: 512Mi
# ... остальная часть манифеста
Для Pod:
apiVersion: v1
kind: Pod
metadata:
annotations:
sidecar.istio.io/proxyCPU: 200m
sidecar.istio.io/proxyCPULimit: "1"
sidecar.istio.io/proxyMemory: 128Mi
sidecar.istio.io/proxyMemoryLimit: 512Mi
# ... остальная часть манифеста
Все четыре параметра должны быть указаны вместе — sidecar.istio.io/proxyCPU, sidecar.istio.io/proxyCPULimit, sidecar.istio.io/proxyMemory и sidecar.istio.io/proxyMemoryLimit. Частичная конфигурация не поддерживается.