Доступ до зовнішніх сервісів
Оскільки весь вихідний трафік з podʼа, який використовує Istio, стандартно перенаправляється до його sidecar proxy, доступність URL-адрес за межами кластера залежить від конфігурації проксі. Типово Istio налаштовує проксі Envoy для пропуску запитів до невідомих сервісів. Попри те, що це зручний спосіб почати роботу з Istio, зазвичай бажано налаштовувати більш суворий контроль.
Це завдання показує, як отримати доступ до зовнішніх сервісів трьома різними способами:
- Дозволити проксі Envoy пропускати запити до сервісів, які не налаштовані всередині mesh.
- Налаштувати service entries, щоб забезпечити контрольований доступ до зовнішніх сервісів.
- Повністю оминути проксі Envoy для певного діапазону IP-адрес.
Перш ніж розпочати
Налаштуйте Istio, дотримуючись інструкцій з Посібника з встановлення. Використовуйте профіль конфігурації
demo
або ж увімкніть реєстрацію доступу Envoy.Розгорніть демонстраційний застосунок curl, щоб використовувати його як тестове джерело для надсилання запитів. Якщо у вас увімкнено автоматичну інʼєкцію sidecar, виконайте наступну команду для розгортання демонстраційного застосунку:
$ kubectl apply -f @samples/curl/curl.yaml@
Або ж вручну виконайте інʼєкцію sidecar перед розгортанням демонстраційного застосунку
curl
за допомогою наступної команди:$ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@)
В зміну оточення
SOURCE_POD
встановіть назву вашого podʼа джерела:$ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath='{.items..metadata.name}')
Передача трафіку через Envoy до зовнішніх сервісів
Istio має опцію встановлення, meshConfig.outboundTrafficPolicy.mode
, яка налаштовує обробку sidecar зовнішніх сервісів, тобто тих, які не визначені у внутрішньому реєстрі сервісів Istio. Якщо ця опція встановлена в значення ALLOW_ANY
, проксі Istio дозволяє проходити викликам до невідомих сервісів. Якщо ж опція встановлена в значення REGISTRY_ONLY
, тоді проксі Istio блокує будь-який хост, якщо для нього не визначений HTTP-сервіс або service entry у mesh. Стандартне значенням — ALLOW_ANY
, що дозволяє вам швидко почати працювати з Istio без контролю доступу до зовнішніх сервісів. Пізніше ви можете вирішити налаштувати доступ до зовнішніх сервісів.
Щоб побачити цей підхід у дії, потрібно переконатися, що ваше встановлення Istio налаштоване з опцією
meshConfig.outboundTrafficPolicy.mode
, встановленою наALLOW_ANY
. Якщо ви явно не встановлювали режимREGISTRY_ONLY
під час інсталяції Istio, ймовірно, що за стандартно увімкнений режимALLOW_ANY
.Якщо ви не впевнені, ви можете виконати наступну команду, щоб переглянути конфігурацію вашого mesh:
$ kubectl get configmap istio -n istio-system -o yaml
Якщо ви не бачите явного налаштування
meshConfig.outboundTrafficPolicy.mode
зі значеннямREGISTRY_ONLY
, ви можете бути впевнені, що опція встановлена наALLOW_ANY
, яке є єдиним іншим можливим значенням і є стандартним значенням.Виконайте кілька запитів до зовнішніх HTTPS сервісів з
SOURCE_POD
, щоб підтвердити успішні відповіді200
:$ kubectl exec "$SOURCE_POD" -c curl -- curl -sSI https://www.google.com | grep "HTTP/"; kubectl exec "$SOURCE_POD" -c curl -- curl -sI https://edition.cnn.com | grep "HTTP/" HTTP/2 200 HTTP/2 200
Вітаю! Ви успішно передали вихідний трафік з вашого mesh.
Цей простий підхід до доступу до зовнішніх сервісів має недолік, оскільки ви втрачаєте можливість моніторингу та контролю Istio для трафіку до зовнішніх сервісів. У наступному розділі показано, як моніторити та контролювати доступ вашого mesh до зовнішніх сервісів.
Контрольований доступ до зовнішніх сервісів
Використовуючи конфігурації Istio ServiceEntry
, ви можете отримати доступ до будь-якого загальнодоступного сервісу зсередини вашого Istio кластера. У цьому розділі показано, як налаштувати доступ до зовнішнього HTTP сервісу, httpbin.org, а також до зовнішнього HTTPS сервісу, www.google.com, зберігаючи можливості моніторингу та контролю трафіку в Istio.
Перехід на політику стандартного блокування
Щоб продемонструвати контрольований спосіб увімкнення доступу до зовнішніх сервісів, вам потрібно змінити опцію meshConfig.outboundTrafficPolicy.mode
з режиму ALLOW_ANY
на режим REGISTRY_ONLY
.
Змініть опцію
meshConfig.outboundTrafficPolicy.mode
наREGISTRY_ONLY
.Якщо ви використовували конфігурацію
IstioOperator
для встановлення Istio, додайте наступне поле до вашої конфігурації:spec: meshConfig: outboundTrafficPolicy: mode: REGISTRY_ONLY
В іншому випадку додайте відповідне налаштування до вашої оригінальної команди
istioctl install
, наприклад:$ istioctl install <flags-you-used-to-install-Istio> \ --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
Виконайте кілька запитів до зовнішніх HTTPS сервісів з
SOURCE_POD
, щоб перевірити, що вони тепер заблоковані:$ kubectl exec "$SOURCE_POD" -c curl -- curl -sI https://www.google.com | grep "HTTP/"; kubectl exec "$SOURCE_POD" -c curl -- curl -sI https://edition.cnn.com | grep "HTTP/" command terminated with exit code 35 command terminated with exit code 35
Доступ до зовнішнього HTTP сервісу
Створіть
ServiceEntry
для дозволу доступу до зовнішнього HTTP сервісу.$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: httpbin-ext spec: hosts: - httpbin.org ports: - number: 80 name: http protocol: HTTP resolution: DNS location: MESH_EXTERNAL EOF
Виконайте запит до зовнішнього HTTP сервісу з
SOURCE_POD
:$ kubectl exec "$SOURCE_POD" -c curl -- curl -sS http://httpbin.org/headers { "headers": { "Accept": "*/*", "Host": "httpbin.org", ... "X-Envoy-Decorator-Operation": "httpbin.org:80/*", ... } }
Зверніть увагу на заголовки, додані sidecar проксі Istio:
X-Envoy-Decorator-Operation
.Перевірте журнал sidecar проксі для
SOURCE_POD
:$ kubectl logs "$SOURCE_POD" -c istio-proxy | tail [2019-01-24T12:17:11.640Z] "GET /headers HTTP/1.1" 200 - 0 599 214 214 "-" "curl/7.60.0" "17fde8f7-fa62-9b39-8999-302324e6def2" "httpbin.org" "35.173.6.94:80" outbound|80||httpbin.org - 35.173.6.94:80 172.30.109.82:55314 -
Зверніть увагу на запис, що стосується вашого HTTP-запиту до
httpbin.org/headers
.
Доступ до зовнішнього HTTPS-сервісу
Створіть
ServiceEntry
, щоб дозволити доступ до зовнішнього HTTPS-сервісу.$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: google spec: hosts: - www.google.com ports: - number: 443 name: https protocol: HTTPS resolution: DNS location: MESH_EXTERNAL EOF
Зробіть запит до зовнішнього HTTPS-сервісу з
SOURCE_POD
:$ kubectl exec "$SOURCE_POD" -c curl -- curl -sSI https://www.google.com | grep "HTTP/" HTTP/2 200
Перевірте ло sidecar проксі
SOURCE_POD
:$ kubectl logs "$SOURCE_POD" -c istio-proxy | tail [2019-01-24T12:48:54.977Z] "- - -" 0 - 601 17766 1289 - "-" "-" "-" "-" "172.217.161.36:443" outbound|443||www.google.com 172.30.109.82:59480 172.217.161.36:443 172.30.109.82:59478 www.google.com
Зверніть увагу на запис, повʼязаний з вашим HTTPS-запитом до
www.google.com
.
Керування трафіком до зовнішніх сервісів
Подібно до запитів між сервісами всередині кластера, правила маршрутизації можуть бути налаштовані й для зовнішніх сервісів, до яких здійснюється доступ за допомогою конфігурацій ServiceEntry
. У цьому прикладі ви налаштуєте правило тайм-ауту для запитів до сервісу httpbin.org
.
Зсередини podʼа, який використовується як тестове джерело, виконайте curl запит до точки доступу
/delay
зовнішнього сервісу httpbin.org:$ kubectl exec "$SOURCE_POD" -c curl -- time curl -o /dev/null -sS -w "%{http_code}\n" http://httpbin.org/delay/5 200 real 0m5.024s user 0m0.003s sys 0m0.003s
Запит має поеврнути 200 (OK) приблизно через 5 секунд.
За допомогою
kubectl
встановіть таймаут у 3 секунди на виклики до зовнішнього сервісуhttpbin.org
:
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
http:
- timeout: 3s
route:
- destination:
host: httpbin.org
weight: 100
EOF
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-ext
spec:
parentRefs:
- kind: ServiceEntry
group: networking.istio.io
name: httpbin-ext
hostnames:
- httpbin.org
rules:
- timeouts:
request: 3s
backendRefs:
- kind: Hostname
group: networking.istio.io
name: httpbin.org
port: 80
EOF
Зачекайте кілька секунд, а потім повторіть запит curl ще раз:
$ kubectl exec "$SOURCE_POD" -c curl -- time curl -o /dev/null -sS -w "%{http_code}\n" http://httpbin.org/delay/5 504 real 0m3.149s user 0m0.004s sys 0m0.004s
This time a 504 (Gateway Timeout) appears after 3 seconds. Although httpbin.org was waiting 5 seconds, Istio cut off the request at 3 seconds.
Видалення контрольованого доступу до зовнішніх сервісів
$ kubectl delete serviceentry httpbin-ext google
$ kubectl delete virtualservice httpbin-ext --ignore-not-found=true
$ kubectl delete serviceentry httpbin-ext
$ kubectl delete httproute httpbin-ext --ignore-not-found=true
Прямий доступ до зовнішніх сервісів
Якщо ви бажаєте повністю оминути Istio для певного діапазону IP-адрес, ви можете налаштувати sidecarʼи Envoy так, щоб вони не перехоплювали зовнішні запити. Для налаштування оминання змініть параметри конфігурації global.proxy.includeIPRanges
або global.proxy.excludeIPRanges
та оновіть config map istio-sidecar-injector
, використовуючи команду kubectl apply
. Це також можна налаштувати на рівні podʼа за допомогою відповідних анотацій, таких як traffic.sidecar.istio.io/includeOutboundIPRanges
. Після оновлення конфігурації istio-sidecar-injector
зміни впливатимуть на всі подальші розгортання podʼів застосунків.
Простий спосіб не включати всі зовнішні IP-адреси з перенаправлення до sidecar проксі — це налаштувати параметр конфігурації global.proxy.includeIPRanges
на діапазон або діапазони IP-адрес, які використовуються для внутрішніх сервісів кластера. Значення цих діапазонів IP-адрес залежить від платформи, на якій працює ваш кластер.
Визначте внутрішні діапазони IP для вашої платформи
Встановіть значення параметра values.global.proxy.includeIPRanges
відповідно до вашого провайдера кластера.
IBM Cloud Private
Отримайте свій
service_cluster_ip_range
з конфігураційного файлу IBM Cloud Private у файліcluster/config.yaml
:$ grep service_cluster_ip_range cluster/config.yaml
Нижче наведено приклад виводу:
service_cluster_ip_range: 10.0.0.1/24
Використовуйте
--set values.global.proxy.includeIPRanges="10.0.0.1/24"
IBM Cloud Kubernetes Service
Щоб побачити, який CIDR використовується у кластері, скористайтеся ibmcloud ks cluster get -c <CLUSTER-NAME>
і знайдіть Service Subnet
:
$ ibmcloud ks cluster get -c my-cluster | grep "Service Subnet"
Service Subnet: 172.21.0.0/16
Потім використовуйте --set values.global.proxy.includeIPRanges="172.21.0.0/16"
Google Kubernetes Engine (GKE)
Діапазони не фіксовані, тому вам потрібно буде виконати команду gcloud container clusters describe
, щоб визначити діапазони для використання. Наприклад:
$ gcloud container clusters describe XXXXXXX --zone=XXXXXX | grep -e clusterIpv4Cidr -e servicesIpv4Cidr
clusterIpv4Cidr: 10.4.0.0/14
servicesIpv4Cidr: 10.7.240.0/20
Використовуйте --set values.global.proxy.includeIPRanges="10.4.0.0/14\,10.7.240.0/20"
Azure Kubernetes Service (AKS)
Kubenet
Щоб побачити, які service CIDR і pod CIDR використовуються в кластері, скористайтеся командою az aks show
і знайдіть serviceCidr
:
$ az aks show --resource-group "${RESOURCE_GROUP}" --name "${CLUSTER}" | grep Cidr
"podCidr": "10.244.0.0/16",
"podCidrs": [
"serviceCidr": "10.0.0.0/16",
"serviceCidrs": [
Потім, --set values.global.proxy.includeIPRanges="10.244.0.0/16\,10.0.0.0/16"
Azure CNI
Дотримуйтеся цих кроків, якщо ви використовуєте Azure CNI в режимі мережі non-overlay. Якщо ви використовуєте Azure CNI з мережею overlay, будь ласка, дотримуйтесь інструкцій для Kubenet. Для отримання додаткової інформації перегляньте документацію Azure CNI Overlay.
Щоб дізнатися, який CIDR використовується для сервісів у кластері, використовуйте команду az aks show
і знайдіть параметр serviceCidr
:
$ az aks show --resource-group "${RESOURCE_GROUP}" --name "${CLUSTER}" | grep serviceCidr
"serviceCidr": "10.0.0.0/16",
"serviceCidrs": [
Щоб дізнатися, який CIDR використовується у кластері, скористайтеся az
CLI для перевірки vnet
:
$ az aks show --resource-group "${RESOURCE_GROUP}" --name "${CLUSTER}" | grep nodeResourceGroup
"nodeResourceGroup": "MC_user-rg_user-cluster_region",
"nodeResourceGroupProfile": null,
$ az network vnet list -g MC_user-rg_user-cluster_region | grep name
"name": "aks-vnet-74242220",
"name": "aks-subnet",
$ az network vnet show -g MC_user-rg_user-cluster_region -n aks-vnet-74242220 | grep addressPrefix
"addressPrefixes": [
"addressPrefix": "10.224.0.0/16",
Пртім, --set values.global.proxy.includeIPRanges="10.244.0.0/16\,10.0.0.0/16"
Minikube, Docker For Desktop, Bare Metal
Стандартне значення 10.96.0.0/12
, але воно не фіксоване. Використовуйте наступну команду, щоб визначити ваше поточне значення:
$ kubectl describe pod kube-apiserver -n kube-system | grep 'service-cluster-ip-range'
--service-cluster-ip-range=10.96.0.0/12
Потім, --set values.global.proxy.includeIPRanges="10.96.0.0/12"
Налаштування оминання проксі
Оновіть config map istio-sidecar-injector
, використовуючи діапазони IP-адрес, специфічні для вашої платформи. Наприклад, якщо діапазон становить 10.0.0.1/24, використовуйте наступну команду:
$ istioctl install <flags-you-used-to-install-Istio> --set values.global.proxy.includeIPRanges="10.0.0.1/24"
Використовуйте ту саму команду, що й для встановлення Istio, додавши --set values.global.proxy.includeIPRanges="10.0.0.1/24"
.
Доступ до зовнішніх сервісів
Оскільки конфігурація оминання впливає тільки на нові розгортання, вам потрібно завершити роботу та повторно розгорнути застосунок curl
, як описано в розділі Перш ніж розпочати.
Після оновлення configmap istio-sidecar-injector
і повторного розгортання застосунку curl
, sidecar Istio перехоплюватиме та керуватиме лише внутрішніми запитами всередині кластера. Будь-які зовнішні запити будуть оминати sidecar і направлятися безпосередньо до відповідного пункту призначення. Наприклад:
$ kubectl exec "$SOURCE_POD" -c curl -- curl -sS http://httpbin.org/headers
{
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
...
}
}
На відміну від доступу до зовнішніх сервісів через HTTP або HTTPS, ви не побачите жодних заголовків, повʼязаних із sidecar Istio, і запити, надіслані до зовнішніх сервісів, не відображатимуться в журналах sidecar. Оминання sidecar Istio означає, що ви більше не зможете моніторити доступ до зовнішніх сервісів.
Видаліть прямий доступ до зовнішніх сервісів
Оновіть конфігурацію, щоб припинити оминання sidecar проксі для низки IP-адрес:
$ istioctl install <flags-you-used-to-install-Istio>
Розуміння того, що сталося
У цьому завданні ви розглянули три способи виклику зовнішніх сервісів з Istio mesh:
Налаштування Envoy для дозволу доступу до будь-якого зовнішнього сервісу.
Використання service entry для реєстрації доступного зовнішнього сервісу всередині mesh. Це рекомендований підхід.
Налаштування sidecar Istio для виключення зовнішніх IP-адрес з його перевизначеної таблиці IP.
Перший підхід спрямовує трафік через проксі-сервер Istio, включаючи виклики до сервісів, які не визначені в mesh. Використовуючи цей підхід, ви не можете контролювати доступ до зовнішніх сервісів або використовувати функції керування трафіком Istio для них. Для легкого переходу до другого підходу для конкретних сервісів просто створіть service entries для цих зовнішніх сервісів. Цей процес дозволяє вам спочатку отримати доступ до будь-якого зовнішнього сервісу, а потім вирішити, чи слід контролювати доступ, увімкнути моніторинг трафіку та використовувати функції керування трафіком за потреби.
Другий підхід дозволяє використовувати всі ті ж самі функції Istio service mesh для викликів до сервісів як усередині, так і поза кластером. У цьому завданні ви дізналися, як моніторити доступ до зовнішніх сервісів і налаштувати правило тайм-ауту для викликів до зовнішнього сервісу.
Третій підхід оминає проксі-сервер Istio, надаючи вашим сервісам прямий доступ до будь-якого зовнішнього сервера. Однак конфігурація проксі таким чином вимагає знання специфічних для провайдера кластера налаштувань. Подібно до першого підходу, ви також втрачаєте можливість моніторингу доступу до зовнішніх сервісів і не можете застосовувати функції Istio до трафіку на зовнішні сервіси.
Примітка з безпеки
Щоб реалізувати контроль трафіку egress більш безпечним способом, потрібно направити трафік egress через egress gateway і ознайомитися з питаннями безпеки, описаними в розділі додаткові міркування щодо безпеки.
Очищення
Зупиніть сервіс curl:
$ kubectl delete -f @samples/curl/curl.yaml@