Проблеми з управлінням трафіком
Запити відхиляються Envoy
Запити можуть бути відхилені з різних причин. Найкращий спосіб зрозуміти, чому запити відхиляються — це перевірити журнали доступу Envoy. Стандартно журнали доступу виводяться на стандартний вихід контейнера. Виконайте наступну команду, щоб переглянути журнал:
$ kubectl logs PODNAME -c istio-proxy -n NAMESPACE
У форматі журналу доступу стандартно прапорці відповіді Envoy розташовані після коду відповіді, якщо ви використовуєте власний формат журналу, переконайтеся, що ви включили %RESPONSE_FLAGS%
.
Зверніться до прапорців відповіді Envoy для отримання деталей про прапорці відповіді.
Загальні прапорці відповіді:
NR
: Шлях не налаштований, перевірте вашDestinationRule
абоVirtualService
.UO
: Переповнення upstream зі спрацюванням запобіжника (circuit breaking), перевірте налаштування запобіжника уDestinationRule
.UF
: Не вдалося підєднатися до upstream, якщо ви використовуєте автентифікацію Istio, перевірте конфлікт конфігурації взаємного TLS.
Правила маршрутизації, здається, не впливають на потік трафіку
З поточною реалізацією Envoy sidecar може знадобитися до 100 запитів для того, щоб розподіл версій з вагою став помітним.
Якщо правила маршрутизації працюють ідеально для Bookinfo, але аналогічні правила маршрутизації версій не мають жодного ефекту для вашого власного застосунку, можливо, що ваші сервіси Kubernetes потрібно трохи змінити. Сервіси Kubernetes повинні відповідати певним обмеженням, щоб скористатися функціями маршрутизації L7 Istio. Дивіться Вимоги до Podʼів та Services для отримання деталей.
Ще одна потенційна проблема може бути в тому, що правила маршрутизації можуть просто повільно набирати силу. Реалізація Istio в Kubernetes використовує алгоритм, що забезпечує в кінцевому рахунку вірний результат, щоб забезпечити всім sidecar Envoy правильну конфігурацію, включаючи всі правила маршрутизації. Зміна конфігурації займе деякий час для поширення на всі sidecar. При великих розгортаннях поширення займе більше часу і може бути затримка на кілька секунд.
Помилки 503 після налаштування DestinationRule
Якщо запити до сервісу починають негайно генерувати помилки HTTP 503 після того, як ви застосували DestinationRule
, і помилки тривають до тих пір, поки ви не видалите або не скасуєте DestinationRule
, ймовірно, що DestinationRule
викликає конфлікт TLS для сервісу.
Наприклад, якщо ви налаштували взаємний TLS у кластері глобально, DestinationRule
повинен включати наступний trafficPolicy
:
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
В іншому випадку стандартний режим буде DISABLE
, що викликає використання простих HTTP запитів з боку проксі клієнта замість зашифрованих TLS запитів. Таким чином, запити конфліктують з проксі сервера, оскільки серверний проксі очікує зашифровані запити.
Щоразу, коли ви застосовуєте DestinationRule
, переконайтеся, що режим TLS trafficPolicy
відповідає глобальній конфігурації сервера.
Правила маршрутизації не мають ефекту на запити до ingress gateway
Припустимо, ви використовуєте ingress Gateway
і відповідний VirtualService
, щоб отримати доступ до внутрішнього сервіса. Наприклад, ваш VirtualService
виглядає приблизно так:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- "myapp.com" # або "*" якщо ви тестуєте без DNS, використовуючи IP ingress-gateway (наприклад, http://1.2.3.4/hello)
gateways:
- myapp-gateway
http:
- match:
- uri:
prefix: /hello
route:
- destination:
host: helloworld.default.svc.cluster.local
- match:
...
У вас також є VirtualService
, який маршрутизує трафік для сервіса helloworld для певної підмножини:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- helloworld.default.svc.cluster.local
http:
- route:
- destination:
host: helloworld.default.svc.cluster.local
subset: v1
У цій ситуації ви помітите, що запити до сервіса helloworld через ingress gateway не будуть направлені до підмножини v1, а продовжать використовувати стандартну маршрутизацію round-robin.
Запити до ingress використовують хост gateway (наприклад, myapp.com
), який активує правила в myapp VirtualService
, що маршрутизують до будь-якої точки доступу сервісу helloworld. Лише внутрішні запити з хостом helloworld.default.svc.cluster.local
будуть використовувати helloworld VirtualService
, який направляє трафік виключно до підмножини v1.
Щоб контролювати трафік від gateway, вам також потрібно включити правило підмножини в myapp VirtualService
:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- "myapp.com" # або "*" якщо ви тестуєте без DNS, використовуючи IP ingress-gateway (наприклад, http://1.2.3.4/hello)
gateways:
- myapp-gateway
http:
- match:
- uri:
prefix: /hello
route:
- destination:
host: helloworld.default.svc.cluster.local
subset: v1
- match:
...
Альтернативно, ви можете обʼєднати обидва VirtualServices
в один, якщо це можливо:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp.com # не можна використовувати "*" тут, оскільки це поєднується з послугами мережі
- helloworld.default.svc.cluster.local
gateways:
- mesh # застосовується як внутрішньо, так і зовнішньо
- myapp-gateway
http:
- match:
- uri:
prefix: /hello
gateways:
- myapp-gateway # обмежує це правило застосовуватися лише до ingress gateway
route:
- destination:
host: helloworld.default.svc.cluster.local
subset: v1
- match:
- gateways:
- mesh # застосовується до всіх служб всередині мережі
route:
- destination:
host: helloworld.default.svc.cluster.local
subset: v1
Envoy виходить з ладу під навантаженням
Перевірте ваш ulimit -a
. Багато систем стандартно мають обмеження на кількість відкритих файлових дескрипторів в 1024, що може викликати збій Envoy з помилкою:
[2017-05-17 03:00:52.735][14236][critical][assert] assert failure: fd_ != -1: external/envoy/source/common/network/connection_impl.cc:58
Переконайтеся, що ви підвищили ваш ulimit. Наприклад: ulimit -n 16384
Envoy не підключається до мого HTTP/1.0 сервісу
Envoy вимагає трафіку HTTP/1.1
або HTTP/2
для висхідних (upstream) сервісів. Наприклад, при використанні NGINX для обробки трафіку за Envoy, вам потрібно встановити директиву proxy_http_version у вашій конфігурації NGINX на “1.1”, оскільки стандартно NGINX використовує версію 1.0.
Приклад конфігурації:
upstream http_backend {
server 127.0.0.1:8080;
keepalive 16;
}
server {
...
location /http/ {
proxy_pass http://http_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
...
}
}
Помилка 503 при доступі до headless сервісів
Припустимо, що Istio встановлено з наступною конфігурацією:
mTLS mode
встановлено наSTRICT
в межах мережіmeshConfig.outboundTrafficPolicy.mode
встановлено наALLOW_ANY
Розглянемо, що nginx
розгорнуто як StatefulSet
у стандартному просторі і відповідний Headless Service
визначено наступним чином:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: http-web # Явно визначаємо http порт
clusterIP: None # Створює Headless Service
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
Імʼя порту http-web
в визначенні Service явно вказує на протокол http для цього порту.
Припустимо, що у нас також є Deployment
podʼа curl в стандартному просторі. Коли nginx
доступний з цього podʼа curl
, використовуючи його IP-адресу (це один із поширених способів доступу до headless сервісу), запит проходить через PassthroughCluster
до серверної сторони, але проксі-сервер на стороні сервера не може знайти маршрут до nginx
і зіпиняється з помилкою HTTP 503 UC
.
$ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath='{.items..metadata.name}')
$ kubectl exec -it $SOURCE_POD -c curl -- curl 10.1.1.171 -s -o /dev/null -w "%{http_code}"
503
10.1.1.171
є IP-адресою однієї з реплік nginx
, а сервіс доступний на containerPort
80.
Ось кілька способів уникнути цієї помилки 503:
Вкажіть правильний заголовок Host:
Заголовок Host у запиті curl стандартно буде IP-адреса Pod. Вказання заголовка Host як
nginx.default
у нашому запиті доnginx
успішно повертаєHTTP 200 OK
.$ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath='{.items..metadata.name}') $ kubectl exec -it $SOURCE_POD -c curl -- curl -H "Host: nginx.default" 10.1.1.171 -s -o /dev/null -w "%{http_code}" 200
Встановіть імʼя порту як
tcp
абоtcp-web
абоtcp-<custom_name>
:Тут протокол явно вказано як
tcp
. У цьому випадку використовується тількиTCP Proxy
мережевий фільтр на проксі-сервері як на клієнтській, так і на серверній стороні. HTTP Connection Manager взагалі не використовується і тому жодний заголовок не очікується у запиті.Запит до
nginx
з або без явного вказання заголовка Host успішно повертаєHTTP 200 OK
.Це корисно в певних сценаріях, де клієнт може не мати можливості включити інформацію про заголовок у запит.
$ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath='{.items..metadata.name}') $ kubectl exec -it $SOURCE_POD -c curl -- curl 10.1.1.171 -s -o /dev/null -w "%{http_code}" 200
$ kubectl exec -it $SOURCE_POD -c curl -- curl -H "Host: nginx.default" 10.1.1.171 -s -o /dev/null -w "%{http_code}" 200
Використовуйте доменне імʼя замість IP-адреси Pod:
До конкретного екземпляру headless сервісу також можна отримати доступ за допомогою доменного імені.
$ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath='{.items..metadata.name}') $ kubectl exec -it $SOURCE_POD -c curl -- curl web-0.nginx.default -s -o /dev/null -w "%{http_code}" 200
Тут
web-0
є імʼям podʼа однієї з 3 реплікnginx
.
Зверніться до цієї сторінки маршрутизації трафіку для додаткової інформації про headless сервіси та поведінку маршрутизації трафіку для різних протоколів.
Помилки конфігурації TLS
Багато проблем з управлінням трафіком викликані неправильною конфігурацією TLS. Нижче описано деякі з найпоширеніших помилок конфігурації.
Надсилання HTTPS на HTTP порт
Якщо ваш застосуок надсилає HTTPS запит на сервіс, який оголошений як HTTP, проксі Envoy спробує обробити запит як HTTP під час пересилання запиту, що зазнає невдачі, оскільки HTTP несподівано зашифрований.
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: httpbin
spec:
hosts:
- httpbin.org
ports:
- number: 443
name: http
protocol: HTTP
resolution: DNS
Хоча наведену вище конфігурацію можна вважати правильною, якщо ви навмисно надсилаєте відкритий текст на порт 443 (наприклад, curl http://httpbin.org:443
), зазвичай порт 443 призначений для HTTPS трафіку.
Надсилання HTTPS запиту, наприклад, curl https://httpbin.org
, який стандартно використовує порт 443, призведе до помилки на кшталт curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
. Журнали доступу також можуть показувати помилку, таку як 400 DPE
.
Щоб виправити це, потрібно змінити протокол порту на HTTPS:
spec:
ports:
- number: 443
name: https
protocol: HTTPS
Невідповідність TLS між шлюзом і віртуальним сервісом
Можуть виникнути дві поширені невідповідності TLS при привʼязці віртуального сервіса до шлюзу.
- Шлюз термінує TLS, тоді як віртуальний сервіс конфігурує маршрутизацію TLS.
- Шлюз виконує TLS passthrough, тоді як віртуальний серві конфігурує HTTP маршрутизацію.
Шлюз з TLS термінацією
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: sds-credential
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "*.example.com"
gateways:
- istio-system/gateway
tls:
- match:
- sniHosts:
- "*.example.com"
route:
- destination:
host: httpbin.org
У цьому прикладі шлюз термінує TLS (конфігурація tls.mode
шлюзу є SIMPLE
, а не PASSTHROUGH
), тоді як віртуальний сервіс використовує маршрутизацію на основі TLS. Оцінка правил маршрутизації відбувається після завершення TLS шлюзом, тому правило TLS не матиме ефекту, оскільки запит тоді є HTTP, а не HTTPS.
З цією помилкою конфігурації ви отримаєте відповіді 404, оскільки запити будуть направлені на маршрутизацію HTTP, але не налаштовано жодних HTTP маршрутів. Ви можете підтвердити це, використовуючи команду istioctl proxy-config routes
.
Щоб виправити цю проблему, слід переключити віртуальний сервіс на маршрутизацію http
, а не tls
:
spec:
...
http:
- match:
- headers:
":authority":
regex: "*.example.com"
Шлюз з TLS passthrough
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: gateway
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- "*"
port:
name: https
number: 443
protocol: HTTPS
tls:
mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: virtual-service
spec:
gateways:
- gateway
hosts:
- httpbin.example.com
http:
- route:
- destination:
host: httpbin.org
У цій конфігурації віртуальний сервіс намагається з’єднати HTTP трафік з TLS трафіком, що проходить через шлюз. Це призведе до того, що конфігурація віртуального сервіса не матиме жодного ефекту. Ви можете спостерігати, що HTTP маршрут не застосовується за допомогою команд istioctl proxy-config listener
та istioctl proxy-config route
.
Щоб виправити це, потрібно переключити віртуальний сревіс на конфігурацію маршрутизації tls
:
spec:
tls:
- match:
- sniHosts: ["httpbin.example.com"]
route:
- destination:
host: httpbin.org
Альтернативно, ви можете термінувати TLS, а не передавати його через шлюз, змінивши конфігурацію tls
в шлюзі:
spec:
...
tls:
credentialName: sds-credential
mode: SIMPLE
Подвійний TLS (створення TLS для TLS-запиту)
При налаштуванні Istio для виконання створення TLS, необхідно переконатися, що застосунок надсилає запити у незашифрованому вигляді до sidecar, який потім ініціює TLS.
Наступний DestinationRule
ініціює TLS для запитів до сервісу httpbin.org
, але відповідний ServiceEntry
визначає протокол як HTTPS на порту 443.
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: httpbin
spec:
hosts:
- httpbin.org
ports:
- number: 443
name: https
protocol: HTTPS
resolution: DNS
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: originate-tls
spec:
host: httpbin.org
trafficPolicy:
tls:
mode: SIMPLE
З цією конфігурацією sidecar очікує, що застосунок надішле TLS-трафік на порт 443 (наприклад, curl https://httpbin.org
), але також виконає створення TLS перед пересиланням запитів. Це призведе до подвійного шифрування запитів.
Наприклад, надсилання запиту, як-от curl https://httpbin.org
, призведе до помилки: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
.
Виправити це можна, змінивши протокол порту в ServiceEntry
на HTTP:
spec:
hosts:
- httpbin.org
ports:
- number: 443
name: http
protocol: HTTP
Зверніть увагу, що з цією конфігурацією ваш застосунок повинен надсилати незашифровані запити на порт 443, як-от curl http://httpbin.org:443
, оскільки створення TLS не змінює порт. Однак починаючи з Istio 1.8, ви можете відкрити HTTP порт 80 для застосунку (наприклад, curl http://httpbin.org
) і потім перенаправити запити на targetPort
443 для сворення TLS:
spec:
hosts:
- httpbin.org
ports:
- number: 80
name: http
protocol: HTTP
targetPort: 443
Помилки 404 при налаштуванні кількох шлюзів з одним і тим же TLS сертифікатом
Налаштування більше одного шлюзу з одним і тим же TLS сертифікатом призведе до помилок 404 в оглядачах, які використовують повторне використання з’єднання HTTP/2 (тобто більшість оглядачів), коли ви звертаєтеся до другого хоста після того, як з’єднання з іншим хостом вже було встановлено.
Наприклад, припустимо, що у вас є 2 хости, які використовують один і той же TLS сертифікат:
- Wildcard сертифікат
*.test.com
, встановлений вistio-ingressgateway
- Конфігурація
Gateway
gw1
з хостомservice1.test.com
, селекторомistio: ingressgateway
та TLS, що використовує сертифікат шлюзу (wildcard) - Конфігурація
Gateway
gw2
з хостомservice2.test.com
, селекторомistio: ingressgateway
та TLS, що використовує сертифікат шлюзу (wildcard) - Конфігурація
VirtualService
vs1
з хостомservice1.test.com
і шлюзомgw1
- Конфігурація
VirtualService
vs2
з хостомservice2.test.com
і шлюзомgw2
Оскільки обидва шлюзи обслуговуються одним робочим навантаженням (тобто селектор istio: ingressgateway
), запити до обох сервісів (service1.test.com
і service2.test.com
) будуть розв’язані на одні й ті ж IP-адреси. Якщо спочатку звернутися до service1.test.com
, він поверне wildcard сертифікат (*.test.com
), вказуючи, що з’єднання з service2.test.com
можуть використовувати той же сертифікат. Оглядачі, такі як Chrome і Firefox, відповідно, повторно використовуватимуть існуюче з’єднання для запитів до service2.test.com
. Оскільки шлюз (gw1
) не має маршруту для service2.test.com
, він поверне помилку 404 (Не знайдено).
Ви можете уникнути цієї проблеми, налаштувавши один wildcard Gateway
, а не два (gw1
і gw2
). Тоді просто прив’яжіть обидва VirtualServices
до нього, ось так:
- Конфігурація
Gateway
gw
з хостом*.test.com
, селекторомistio: ingressgateway
та TLS, що використовує сертифікат шлюзу (wildcard) - Конфігурація
VirtualService
vs1
з хостомservice1.test.com
і шлюзомgw
- Конфігурація
VirtualService
vs2
з хостомservice2.test.com
і шлюзомgw
Налаштування маршрутизації SNI, коли SNI не надсилається
HTTPS Gateway
, який вказує поле hosts
, виконує SNI збіг для вхідних запитів. Наприклад, наступна конфігурація дозволяє лише запити, що відповідають *.example.com
в SNI:
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*.example.com"
Це може призвести до помилок для деяких запитів.
Наприклад, якщо ви не налаштували DNS і натомість безпосередньо встановлюєте заголовок хоста, як curl 1.2.3.4 -H "Host: app.example.com"
, SNI не буде встановлено, що призведе до помилки запиту. Замість цього, ви можете налаштувати DNS або використовувати прапорець --resolve
для curl
. Для отримання додаткової інформації дивіться завдання Захист Gateways.
Ще однією поширеною проблемою є балансувальники навантаження перед Istio. Більшість хмарних балансувальників навантаження не пересилають SNI, тому якщо ви термінуєте TLS у своєму хмарному балансувальнику навантаження, вам може знадобитися виконати одну з наступних дій:
- Налаштувати хмарний балансувальник навантаження для передачі TLS-зʼєднання
- Вимкнути зіставлення SNI у
Gateway
, встановивши поле hosts на*
Зазвичай симптомом цього є те, що перевірки справності балансувальника навантаження успішні, але реальний трафік не проходить.
Незмінена конфігурація фільтра Envoy раптово перестає працювати
Конфігурація EnvoyFilter
, яка вказує позицію вставки відносно іншого фільтра, може бути дуже нестійкою, оскільки, стандартно, порядок оцінювання базується на часі створення фільтрів. Розгляньте фільтр з наступною специфікацією:
spec:
configPatches:
- applyTo: NETWORK_FILTER
match:
context: SIDECAR_OUTBOUND
listener:
portNumber: 443
filterChain:
filter:
name: istio.stats
patch:
operation: INSERT_BEFORE
value:
...
Щоб працювати правильно, ця конфігурація фільтра залежить від того, щоб фільтр istio.stats
мав старіший час створення, ніж він. В іншому випадку операція INSERT_BEFORE
буде проігнорована без сповіщення про це. У журналі помилок не буде нічого, що вказує на те, що цей фільтр не було додано до ланцюга.
Це особливо проблематично при порівнянні фільтрів, таких як istio.stats
, які є версійно специфічними (тобто містять поле proxyVersion
у своїх критеріях збігу). Такі фільтри можуть бути видалені або замінені новими при оновленні Istio. Як результат, EnvoyFilter
, подібний до наведеного вище, може спочатку працювати бездоганно, але після оновлення Istio до новішої версії його більше не буде включено в ланцюг мережевого фільтра sidecarʼів.
Щоб уникнути цієї проблеми, ви можете або змінити операцію на ту, яка не залежить від наявності іншого фільтра (наприклад, INSERT_FIRST
), або встановити явний пріоритет у EnvoyFilter
, щоб перевизначити стандартне впорядкування на основі часу створення. Наприклад, додавання priority: 10
до наведеного вище фільтра забезпечить його обробку після фільтра istio.stats
, який має стандартний пріоритет 0.
Віртуальний сервіс з інʼєкцією хбоїва і політиками повторних спроб/тайм-аутів не працює як очікується
На даний момент Istio не підтримує конфігурацію інʼєкцій збоїв і політик повторних спроб або тайм-аутів в одному й тому ж VirtualService
. Розгляньте наступну конфігурацію:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /hello
fault:
abort:
httpStatus: 500
percentage:
value: 50
retries:
attempts: 5
retryOn: 5xx
route:
- destination:
host: helloworld
port:
number: 5000
Ви могли б очікувати, що, враховуючи пʼять налаштованих повторних спроб, користувач майже ніколи не побачити помилок при виклику сервісу helloworld
. Однак, оскільки і налаштування помилок, і повторні спроби сконфігуровані в одному й тому ж VirtualService
, конфігурація повторних спроб не буде застосовуватися, що призводить до рівня помилок 50%. Щоб розвʼязати цю проблему, ви можете видалити конфігурацію помилок з вашого VirtualService
і зроби інʼєкцію збою у висхідний (upstream) Envoy проксі за допомогою EnvoyFilter
замість цього:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: hello-world-filter
spec:
workloadSelector:
labels:
app: helloworld
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND # буде збігатися з вихідними слухачами в усіх sidecarʼах
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
patch:
operation: INSERT_BEFORE
value:
name: envoy.fault
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault"
abort:
http_status: 500
percentage:
numerator: 50
denominator: HUNDRED
Це працює, тому що таким чином політика повторних спроб конфігурується для клієнтського проксі, а інʼєкція збоїів — для upstream проксі.