Circuit Breaker | Circuit Breaker |
The | Для выявления проблемных эндпоинтов используются настройки |
Example: | Пример: |
yaml apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: reviews-cb-policy spec: host: reviews.prod.svc.cluster.local trafficPolicy: connectionPool: tcp: maxConnections: 100 # The maximum number of connections to the host (cumulative for all endpoints) http: maxRequestsPerConnection: 10 # The connection will be re-established after every 10 requests outlierDetection: consecutive5xxErrors: 7 # Seven consecutive errors are allowed (including 5XX, TCP and HTTP timeouts) interval: 5m # over 5 minutes. baseEjectionTime: 15m # Upon reaching the error limit, the endpoint will be excluded from balancing for 15 minutes. | yaml 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 минут. |
Additionally, the VirtualService resource is used to configure the HTTP timeouts. These timeouts are also taken into account when calculating error statistics for endpoints. | А также, для настройки HTTP-таймаутов используется ресурс VirtualService. Эти таймауты также учитываются при подсчёте статистики ошибок на эндпоинтах. |
Example: | Пример: |
yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: my-productpage-rule namespace: myns spec: hosts:
| yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: my-productpage-rule namespace: myns spec: hosts:
|
gRPC balancing | Балансировка gRPC |
Caution! Assign a name with the | Важно! Для того, чтобы балансировка gRPC-сервисов заработала автоматически, присвойте name с префиксом или значением |
Locality Failover | Locality Failover |
|
|
Istio allows you to configure a priority-based locality (geographic location) failover between endpoints. Istio uses node labels with the appropriate hierarchy to define the zone: | Istio позволяет настроить приоритетный географический фейловер между эндпоинтами. Для определения зоны Istio использует лейблы узлов с соответствующей иерархией: |
|
|
This comes in handy for inter-cluster failover when used together with a multicluster. | Это полезно для межкластерного фейловера при использовании совместно с мультикластером. |
Caution! The Locality Failover can be enabled using the DestinationRule CR. Note that you also have to configure the outlierDetection. | Важно! Для включения Locality Failover используется ресурс DestinationRule, в котором также необходимо настроить outlierDetection. |
Example: | Пример: |
yaml apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: helloworld spec: host: helloworld trafficPolicy: loadBalancer: localityLbSetting: enabled: true # LF is enabled outlierDetection: # outlierDetection must be enabled consecutive5xxErrors: 1 interval: 1s baseEjectionTime: 1m | yaml apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: helloworld spec: host: helloworld trafficPolicy: loadBalancer: localityLbSetting: enabled: true # включили LF outlierDetection: # outlierDetection включить обязательно consecutive5xxErrors: 1 interval: 1s baseEjectionTime: 1m |
Retry | Retry |
You can use the VirtualService resource to configure Retry for requests. | С помощью ресурса VirtualService можно настроить Retry для запросов. |
Caution! All requests (including POST ones) are retried three times by default. | Внимание! По умолчанию при возникновении ошибок все запросы (включая POST-запросы) выполняются повторно до трех раз. |
Example: | Пример: |
yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: ratings-route spec: hosts:
| yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: ratings-route spec: hosts:
|
Canary | Canary |
Caution! Istio is only responsible for flexible request routing that relies on special request headers (such as cookies) or simply randomness. The CI/CD system is responsible for customizing this routing and “switching” between canary versions. | Важно! Istio отвечает лишь за гибкую маршрутизацию запросов, которая опирается на спец-заголовки запросов (например, cookie) или просто на случайность. За настройку этой маршрутизации и “переключение” между канареечными версиями отвечает CI/CD система. |
The idea is that two Deployments with different versions of the application are deployed in the same namespace. The Pods of different versions have different labels ( | Подразумевается, что в одном namespace выкачено два Deployment с разными версиями приложения. У Pod’ов разных версий разные лейблы ( |
You have to configure two custom resources:
| Требуется настроить два custom resource:
|
Example: | Пример: |
yaml apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: productpage-canary spec: host: productpage subsets are only available when accessing the host via the VirtualService from a Pod managed by Istio. These subsets must be defined in the routes. subsets:
| yaml apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: productpage-canary spec: host: productpage subset-ы доступны только при обращении к хосту через через VirtualService из Pod’а под управлением Istio. Эти subset-ы должны быть указаны в маршрутах. subsets:
|
Cookie-based routing | Распределение по наличию cookie |
yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: productpage-canary spec: hosts:
| yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: productpage-canary spec: hosts:
|
Probability-based routing | Распределение по вероятности |
yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: productpage-canary spec: hosts:
| yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: productpage-canary spec: hosts:
|
Ingress to publish applications | Ingress для публикации приложений |
Istio Ingress Gateway | Istio Ingress Gateway |
Example: | Пример: |
yaml apiVersion: deckhouse.io/v1alpha1 kind: IngressIstioController metadata: name: main spec: ingressGatewayClass contains the label selector value used to create the Gateway resource ingressGatewayClass: istio-hp inlet: HostPort hostPort: httpPort: 80 httpsPort: 443 nodeSelector: node-role/frontend: ‘’ tolerations:
| yaml apiVersion: deckhouse.io/v1alpha1 kind: IngressIstioController metadata: name: main spec: ingressGatewayClass содержит значение селектора меток, используемое при создании ресурса Gateway ingressGatewayClass: istio-hp inlet: HostPort hostPort: httpPort: 80 httpsPort: 443 nodeSelector: node-role/frontend: ‘’ tolerations:
|
yaml apiVersion: v1 kind: Secret metadata: name: app-tls-secert namespace: d8-ingress-istio # note the namespace isn’t app-ns type: kubernetes.io/tls data: tls.crt: | | yaml apiVersion: v1 kind: Secret metadata: name: app-tls-secert namespace: d8-ingress-istio # обратите внимание, что namespace не является app-ns type: kubernetes.io/tls data: tls.crt: | |
yaml apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: gateway-app namespace: app-ns spec: selector: label selector for using the Istio Ingress Gateway main-hp istio.deckhouse.io/ingress-gateway-class: istio-hp servers:
| yaml 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:
|
yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: vs-app namespace: app-ns spec: gateways:
| yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: vs-app namespace: app-ns spec: gateways:
|
Nginx Ingress | Nginx Ingress |
To use Ingress, you need to:
| Для работы с Nginx Ingress требуется подготовить:
|
Examples: | Примеры: |
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: productpage
namespace: bookinfo
annotations:
Nginx proxies traffic to the ClusterIP instead of pods’ own IPs.
nginx.ingress.kubernetes.io/service-upstream: “true”
In Istio, all routing is carried out based on the
| yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: productpage
namespace: bookinfo
annotations:
Просим nginx проксировать трафик на ClusterIP вместо собственных IP Pod’ов.
nginx.ingress.kubernetes.io/service-upstream: “true”
В Istio вся маршрутизация осуществляется на основе
|
yaml apiVersion: v1 kind: Service metadata: name: productpage namespace: bookinfo spec: ports:
| yaml apiVersion: v1 kind: Service metadata: name: productpage namespace: bookinfo spec: ports:
|
Authorization configuration examples | Примеры настройки авторизации |
Decision-making algorithm | Алгоритм принятия решения |
Caution! The following algorithm for deciding the fate of a request becomes active after AuthorizationPolicy is created for the application:
| Важно! Как только для приложения создаётся
|
In other words, if you explicitly deny something, then only this restrictive rule will work. If you explicitly allow something, only explicitly authorized requests will be allowed (however, restrictions will stay in force and have precedence). | Иными словами, если вы явно что-то запретили, то работает только ваш запрет. Если же вы что-то явно разрешили, то теперь разрешены только явно одобренные запросы (запреты никуда не исчезают и имеют приоритет). |
Caution! The policies based on high-level parameters like namespace or principal require enabling Istio for all involved applications. Also, there must be organized Mutual TLS between applications. | Важно! Для работы политик, основанных на высокоуровневых параметрах, таких как namespace или principal, необходимо, чтобы все вовлечённые сервисы работали под управлением Istio. Также, между приложениями должен быть организован Mutual TLS. |
Examples:
| Примеры:
|
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-post-requests namespace: foo spec: selector: matchLabels: app: myapp action: DENY rules:
| yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-post-requests namespace: foo spec: selector: matchLabels: app: myapp action: DENY rules:
|
|
|
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: selector: matchLabels: app: myapp action: ALLOW # The default value, can be skipped. rules:
| yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: selector: matchLabels: app: myapp action: ALLOW # default, можно не указывать rules:
|
|
|
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: selector: matchLabels: app: myapp action: ALLOW # The default value, can be skipped. rules: [] | yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: selector: matchLabels: app: myapp action: ALLOW # default, можно не указывать. rules: [] |
|
|
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all namespace: foo spec: selector: matchLabels: app: myapp rules:
| yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all namespace: foo spec: selector: matchLabels: app: myapp rules:
|
Deny all for the foo namespace | Запретить вообще всё в рамках namespace foo |
There are two ways you can do that: | Два способа: |
|
|
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: action: DENY rules:
| yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: action: DENY rules:
|
|
|
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: {} | yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: foo spec: {} |
Deny requests from the foo NS only | Запретить доступ только из namespace foo |
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-from-ns-foo namespace: myns spec: action: DENY rules:
| yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-from-ns-foo namespace: myns spec: action: DENY rules:
|
Allow requests for the foo NS only | Разрешить запросы только в рамках нашего namespace foo |
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-intra-namespace-only namespace: foo spec: action: ALLOW rules:
| yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-intra-namespace-only namespace: foo spec: action: ALLOW rules:
|
Allow requests from anywhere in the cluster | Разрешить из любого места в нашем кластере |
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all-from-my-cluster namespace: myns spec: action: ALLOW rules:
| yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all-from-my-cluster namespace: myns spec: action: ALLOW rules:
|
Allow any requests for foo or bar clusters | Разрешить любые запросы только кластеров foo или bar |
yaml 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:
| yaml 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:
|
Allow any requests from foo or bar clusters where the namespace is baz | Разрешить любые запросы только кластеров foo или bar, при этом из namespace baz |
yaml 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:
| yaml 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:
|
Allow from any cluster (via mtls) | Разрешить из любого кластера (по mtls) |
Caution! The denying rules (if they exist) have priority over any other rules. See the algorithm. | Важно! Если есть запрещающие правила, то у них будет приоритет. Смотри алгоритм. |
Example: | Пример: |
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all-from-any-cluster-with-mtls namespace: myns spec: action: ALLOW rules:
| yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all-from-any-cluster-with-mtls namespace: myns spec: action: ALLOW rules:
|
Allow all requests from anywhere (including no mTLS - plain text traffic) | Разрешить вообще откуда угодно (в том числе без mtls) |
yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all-from-any namespace: myns spec: action: ALLOW rules: [{}] | yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all-from-any namespace: myns spec: action: ALLOW rules: [{}] |
Setting up federation for two clusters using the IstioFederation CR | Устройство федерации из двух кластеров с помощью CR IstioFederation |
Cluster A: | Cluster A: |
yaml apiVersion: deckhouse.io/v1alpha1 kind: IstioFederation metadata: name: cluster-b spec: metadataEndpoint: https://istio.k8s-b.example.com/metadata/ trustDomain: cluster-b.local | yaml 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: | Cluster B: |
yaml apiVersion: deckhouse.io/v1alpha1 kind: IstioFederation metadata: name: cluster-a spec: metadataEndpoint: https://istio.k8s-a.example.com/metadata/ trustDomain: cluster-a.local | yaml apiVersion: deckhouse.io/v1alpha1 kind: IstioFederation metadata: name: cluster-a spec: metadataEndpoint: https://istio.k8s-a.example.com/metadata/ trustDomain: cluster-a.local |
Setting up multicluster for two clusters using the IstioMulticluster CR | Устройство мультикластера из двух кластеров с помощью ресурса IstioMulticluster |
Cluster A: | Cluster A: |
yaml apiVersion: deckhouse.io/v1alpha1 kind: IstioMulticluster metadata: name: cluster-b spec: metadataEndpoint: https://istio.k8s-b.example.com/metadata/ | yaml apiVersion: deckhouse.io/v1alpha1 kind: IstioMulticluster metadata: name: cluster-b spec: metadataEndpoint: https://istio.k8s-b.example.com/metadata/ |
Cluster B: | Cluster B: |
yaml apiVersion: deckhouse.io/v1alpha1 kind: IstioMulticluster metadata: name: cluster-a spec: metadataEndpoint: https://istio.k8s-a.example.com/metadata/ | yaml apiVersion: deckhouse.io/v1alpha1 kind: IstioMulticluster metadata: name: cluster-a spec: metadataEndpoint: https://istio.k8s-a.example.com/metadata/ |
Control the data-plane behavior | Управление поведением data-plane |
[experimental feature] Prevent istio-proxy from terminating before the main application’s connections are closed | [экспериментальная функция] Предотвратить завершение работы istio-proxy до завершения соединений основного приложения |
By default, during termination, all containers in a Pod, including istio-proxy one, receive SIGTERM signal simultanuesly. But some applications need time to properly handle the termination and sometimes they need to do some network requests. It isn’t possible when the istio-proxy stops before the application do. The solution is to add a preStop hook which evaluates the application’s activity via discovering application’s network sockets and let the sidecar stop when they aren’t in network namespace.
The annotation below adds the preStop hook to istio-proxy container in application’s Pod:
| По умолчанию, в процессе остановки пода, все контейнеры, включая istio-proxy, получают сигнал SIGTERM одновременно. Но некоторым приложениям для правильного завершения работы необходимо время и иногда дополнительная сетевая активность. Это невозможно если istio-proxy завершился раньше.
Решение — добавить в istio-proxy preStop-хук для оценки активности прикладных контейнеров, а единственный доступный метод — это выявление сетевых сокетов приложения, и если таковых нет, то можно останавливать контейнер.
Аннотация ниже добавляет описанный выше preStop-хук в контейнер istio-proxy прикладного пода:
|
Upgrading Istio control-plane | Обновление control-plane Istio |
|
|
To find all Pods with old Istio revision, execute the following command: | Чтобы найти все Pod’ы под управлением старой ревизии Istio, выполните: |
shell
kubectl get pods -A -o json | jq –arg revision “v1x12” | shell
kubectl get pods -A -o json | jq –arg revision “v1x12” |