Поради з управління трафіком
Цей розділ надає конкретні вказівки щодо розгортання або конфігурації для уникнення проблем з мережею або управлінням трафіком.
Встановіть стандартні маршрути для сервісів
Хоча стандартно Istio зручно направляє трафік з будь-якого джерела на всі версії сервісу призначення без налаштування жодних правил, створення VirtualService
зі стандартним маршрутом для кожного сервісу з самого початку зазвичай вважається найкращою практикою в Istio.
Навіть якщо спочатку у вас є тільки одна версія сервісу, як тільки ви вирішите розгорнути другу версію, вам потрібно мати правило маршрутизації до запуску нової версії, щоб запобігти їй негайно отримувати трафік неконтрольованим способом.
Ще однією потенційною проблемою при використанні стандартної циклічної (round-robin) маршрутизації Istio є тонкість алгоритму оцінки правил призначення в Istio. Під час маршрутизації запиту Envoy спочатку оцінює правила маршрутизації у віртуальних службах, щоб визначити, чи є певна підмножина, до якої виконується маршрутизація. Якщо так, то тільки тоді він активує будь-які політики правил призначення, що відповідають підмножині. Отже, Istio застосовує політики, які ви визначили для певних підмножин, лише якщо ви явно спрямовуєте трафік до відповідної підмножини.
Наприклад, розгляньте наступне правило призначення як єдине налаштування, визначене для сервісу reviews, тобто, немає жодних правил маршрутизації у відповідному визначенні VirtualService
:
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
Навіть якщо стандартна циклічна маршрутизація Istio викликає екземпляри “v1” час від часу, можливо, навіть постійно, якщо “v1” є єдиною запущеною версією, наведена вище політика трафіку ніколи не буде застосована.
Ви можете виправити вищенаведений приклад одним із двох способів. Ви можете або перемістити політику трафіку на рівень вище в DestinationRule
, щоб вона застосовувалася до будь-якої версії:
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
subsets:
- name: v1
labels:
version: v1
Або, краще, визначте правильне правило маршрутизації для сервісу у визначенні VirtualService
. Наприклад, додайте просте правило маршрутизації для “reviews:v1”:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
Керування спільним використанням конфігурації в різних просторах імен
Ви можете визначити віртуальні сервіси, правила призначення або записи сервісів в одному просторі імен і потім використовувати їх в інших просторах імен, якщо вони експортовані в ці простори імен. Стандартно Istio експортує всі ресурси управління трафіком до всіх просторів імен, але ви можете перевизначити видимість за допомогою поля exportTo
. Наприклад, наступна віртуальна служба може впливати лише на запити від робочих навантажень у тому самому просторі імен:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myservice
spec:
hosts:
- myservice.com
exportTo:
- "."
http:
- route:
- destination:
host: myservice
Налаштування видимості правил призначення в конкретному просторі імен не гарантує, що правило буде використовуватися. Експорт правила призначення в інші простори імен дозволяє використовувати його в цих просторах імен, але для фактичного застосування під час запиту простір імен також має бути в шляху пошуку правила призначення:
- простір імен клієнта
- простір імен сервісу
- налаштований простір імен
meshconfig.rootNamespace
(стандартноistio-system
)
Наприклад, розглянемо наступне правило призначення:
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: myservice
spec:
host: myservice.default.svc.cluster.local
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
Припустимо, ви створюєте це правило призначення в просторі імен ns1
.
Якщо ви надсилаєте запит до сервісу myservice
з клієнта в ns1
, правило призначення застосовується, оскільки воно знаходиться в першому просторі імен на шляху пошуку, а саме, у просторі імен клієнта.
Якщо ви тепер надсилаєте запит з іншого простору імен, наприклад ns2
, клієнт більше не знаходиться в тому ж просторі імен, що й правило призначення, ns1
. Оскільки відповідний сервіс, myservice.default.svc.cluster.local
, також не знаходиться в ns1
, а в просторі імен default
, правило призначення також не буде знайдене у другому просторі імен шляху пошуку, просторі імен сервісу.
Навіть якщо сервіс myservice
експортований до всіх просторів імен і, отже, видимий в ns2
, і правило призначення також експортоване до всіх просторів імен, включаючи ns2
, воно не буде застосоване під час запиту з ns2
, оскільки не знаходиться в жодному з просторів імен на шляху пошуку.
Ви можете уникнути цієї проблеми, створюючи правило призначення в тому ж просторі імен, що й відповідний сервіс, default
у цьому прикладі. Тоді воно буде застосовуватися до запитів з клієнтів у будь-якому просторі імен. Ви також можете перемістити правило призначення до простору імен istio-system
, третього простору імен на шляху пошуку, хоча це не рекомендується, якщо правило призначення не є справжньою глобальною конфігурацією, яка застосовується в усіх просторах імен, і це вимагатиме адміністративних прав.
Istio використовує цей обмежений шлях пошуку правил призначення з двох причин:
- Перешкодити визначенню правил призначення, які можуть переписати поведінку сервісів у абсолютно несуміжних просторах імен.
- Мати чіткий порядок пошуку у випадку, якщо існує більше одного правила призначення для того ж хосту.
Розподіл великих віртуальних сервісів і правил призначення на кілька ресурсів
У ситуаціях, коли незручно визначати повний набір правил маршрутизації або політик для конкретного хосту в одному ресурсі VirtualService
або DestinationRule
, може бути доцільніше поступово вказувати конфігурацію для хосту в кількох ресурсах. Панель управління обʼєднає такі правила призначення та обʼєднає такі віртуальні сервіси, якщо вони привʼязані до шлюзу.
Розглянемо випадок VirtualService
, привʼязаного до вхідного шлюзу, що експонує хост застосунку, який використовує делегування на основі шляху до декількох служб впровадження, щось на кшталт цього:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp.com
gateways:
- myapp-gateway
http:
- match:
- uri:
prefix: /service1
route:
- destination:
host: service1.default.svc.cluster.local
- match:
- uri:
prefix: /service2
route:
- destination:
host: service2.default.svc.cluster.local
- match:
...
Недоліком такої конфігурації є те, що інші конфігурації (наприклад, правила маршрутів) для будь-якого з базових мікросервісів також повинні бути включені в цей єдиний конфігураційний файл, а не в окремі ресурси, повʼязані з окремими командами сервісів, які потенційно можуть належати їм. Див. Правила маршрутизації не впливають на запити шлюзу входу для деталей.
Щоб уникнути цієї проблеми, може бути доцільніше розділити конфігурацію myapp.com
на кілька фрагментів VirtualService
, по одному для кожного сервісу. Наприклад:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-service1
spec:
hosts:
- myapp.com
gateways:
- myapp-gateway
http:
- match:
- uri:
prefix: /service1
route:
- destination:
host: service1.default.svc.cluster.local
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-service2
spec:
hosts:
- myapp.com
gateways:
- myapp-gateway
http:
- match:
- uri:
prefix: /service2
route:
- destination:
host: service2.default.svc.cluster.local
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-...
Коли застосовується другий і подальші VirtualService
для наявного хосту, istiod
обʼєднає додаткові маршрутні правила з поточною конфігурацією хосту. Проте є кілька застережень, які слід врахувати при використанні цієї функції.
- Хоча порядок оцінки правил у будь-якому даному джерелі
VirtualService
буде збережено, порядок між ресурсами НЕ ВИЗНАЧЕНИЙ. Іншими словами, немає гарантованого порядку оцінки правил між конфігураціями фрагментів, тому поведінка буде передбачуваною лише в разі відсутності конфліктуючих правил або залежностей порядку між правилами в різних фрагментах. - Має бути тільки одне правило “catch-all” (тобто правило без поля
match
) у фрагментах. Всі такі правила “catch-all” будуть переміщені в кінець списку в обʼєднаній конфігурації, але оскільки вони охоплюють всі запити, те, яке буде застосоване першим, фактично перекриє і вимкне будь-які інші. VirtualService
можна розбити таким чином лише якщо він привʼязаний до шлюзу. Обʼєднання хостів не підтримується в sidecars.
DestinationRule
також можна розбити з подібною семантикою об’єднання та обмеженнями.
- Повинно бути тільки одне визначення будь-якої підмножини в декількох правилах призначення для одного і того ж хосту. Якщо існує декілька визначень з однаковою назвою, використовується перше визначення, а всі наступні дублікати відкидаються. Об’єднання вмісту підмножин не підтримується.
- Для одного хосту може бути лише одна
trafficPolicy
верхнього рівня. Якщо політики трафіку верхнього рівня визначено в декількох правилах призначення, буде використано перше оброблене правило. Будь-яка наступна конфігураціяtrafficPolicy
верхнього рівня буде відкинута. - На відміну від обʼєднання віртуальних сервісів, обʼєднання правил призначення працює як у sidecars, так і в шлюзах.
Уникнення помилок 503 під час переконфігурації маршрутів сервісу
При налаштуванні правил маршрутизації для направлення трафіку на конкретні версії (підмножини) сервісу слід бути обережним, щоб переконатися, що підмножини доступні перед їх використанням у маршрутах. Інакше виклики до сервісу можуть повертати помилки 503 під час періоду переконфігурації.
Створення як VirtualServices
, так і DestinationRules
, які визначають відповідні підмножини, за допомогою одного виклику kubectl
(наприклад, kubectl apply -f myVirtualServiceAndDestinationRule.yaml
) недостатньо, оскільки ресурси розповсюджуються (з конфігураційного сервера, тобто сервера API Kubernetes) до екземплярів istiod у спосіб, що забезпечує зрештою консистентність. Якщо VirtualService
, що використовує підмножини, надходить раніше, ніж DestinationRule
, де визначені підмножини, конфігурація Envoy, згенерована istiod, буде посилатися на відсутні пули для підключення. Це призводить до помилок HTTP 503, поки всі обʼєкти конфігурації не стануть доступними для istiod.
Щоб переконатися, що сервіси матимуть нульовий час простою під час конфігурації маршрутів з підмножинами, дотримуйтеся процесу “make-before-break”, як описано нижче:
При додаванні нових підмножин:
Оновіть
DestinationRules
, щоб спочатку додати нову підмножину, перед оновленням будь-якихVirtualServices
, що її використовують. Застосуйте правило за допомогоюkubectl
або будь-якого специфічного для платформи інструменту.Зачекайте кілька секунд, поки конфігурація
DestinationRule
пошириться на Envoy sidecars.Оновіть
VirtualService
, щоб посилатися на новостворені підмножини.
При видаленні підмножин:
Оновіть
VirtualServices
, щоб видалити будь-які посилання на підмножину, перед видаленням підмножини зDestinationRule
.Зачекайте кілька секунд, поки конфігурація
VirtualService
пошириться на Envoy sidecars.Оновіть
DestinationRule
, щоб видалити невикористовувані підмножини.