Egress з використанням шаблонів хостів

Завдання Доступ до зовнішніх сервісів та приклад Налаштування Egress Gateway описують, як налаштувати вихідний трафік для конкретних доменів, таких як edition.cnn.com. Цей приклад показує, як увімкнути вихідний трафік для набору хостів у спільному домені, наприклад *.wikipedia.org, замість того, щоб налаштовувати кожен хост окремо.

Контекст

Припустимо, ви хочете увімкнути вихідний трафік в Istio для сайтів wikipedia.org всіма мовами. Кожна версія wikipedia.org для конкретної мови має свій власний хост, наприклад, en.wikipedia.org та uk.wikipedia.org для англійської та української відповідно. Ви хочете увімкнути вихідний трафік за допомогою загальних конфігураційних елементів для всіх сайтів Wikipedia, без необхідності вказувати сайт для кожної мови окремо.

Перш ніж почати

  • Встановіть Istio з увімкненим журналюванням доступу та політикою стандартного блокування вихідного трафіку:
$ istioctl install --set profile=demo --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
  • Розгорніть демонстраційний застосунок curl для використання його як джерела тестових запитів. Якщо у вас увімкнено автоматична інʼєкія sidecar, виконайте наступну команду для розгортання застосунку:

    Zip
    $ kubectl apply -f @samples/curl/curl.yaml@

    В іншому випадку, вручну додайте sidecar перед розгортанням застосунку curl за допомогою наступної команди:

    Zip
    $ 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})

Налаштування прямого трафіку до хосту за шаблоном

Перший, і найпростіший, спосіб отримати доступ до набору хостів у спільному домені — це налаштування простого ServiceEntry зі знаком підстановки та виклик сервісів безпосередньо з sidecar. Коли ви викликаєте сервіси безпосередньо (тобто не через вихідний шлюз), конфігурація для знака підстановки не відрізняється від конфігурації будь-якого іншого (наприклад, повністю кваліфікованого) хосту, а є тільки зручнішим, коли багато хостів присутньо в спільному домені.

  1. Визначте ServiceEntry для *.wikipedia.org:

    $ kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: ServiceEntry
    metadata:
      name: wikipedia
    spec:
      hosts:
      - "*.wikipedia.org"
      ports:
      - number: 443
        name: https
        protocol: HTTPS
    EOF
  2. Надішліть HTTPS-запит до https://en.wikipedia.org та https://uk.wikipedia.org:

    $ kubectl exec "$SOURCE_POD" -c curl -- sh -c 'curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"; curl -s https://uk.wikipedia.org/wiki/Головна_сторінка | grep -o "<title>.*</title>"'
    <title>Wikipedia, the free encyclopedia</title>
    <title>Вікіпедія</title>

Вилучення налаштувань для прямого трафіку до хосту за шаблоном

$ kubectl delete serviceentry wikipedia

Налаштування трафіку через вихідний шлюз до хосту з підстановочним знаком

Коли всі хости з підстановочним знаком обслуговуються одним сервером, конфігурація для доступу через вихідний шлюз до хосту з підстановочним знаком дуже схожа на конфігурацію для будь-якого іншого хосту, з однією відмінністю: кінцевий пункт маршруту не буде тим же, що й налаштований хост, тобто підстановочним знаком. Замість цього буде налаштовано хост єдиного сервера для набору доменів.

  1. Створіть вихідний Gateway для *.wikipedia.org та правила маршрутизації, щоб направити трафік через вихідний шлюз і з вихідного шлюзу до зовнішнього сервісу:
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*.wikipedia.org"
    tls:
      mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: egressgateway-for-wikipedia
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
    - name: wikipedia
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: direct-wikipedia-through-egress-gateway
spec:
  hosts:
  - "*.wikipedia.org"
  gateways:
  - mesh
  - istio-egressgateway
  tls:
  - match:
    - gateways:
      - mesh
      port: 443
      sniHosts:
      - "*.wikipedia.org"
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: wikipedia
        port:
          number: 443
      weight: 100
  - match:
    - gateways:
      - istio-egressgateway
      port: 443
      sniHosts:
      - "*.wikipedia.org"
    route:
    - destination:
        host: www.wikipedia.org
        port:
          number: 443
      weight: 100
EOF
  1. Створіть ServiceEntry для сервера призначення, www.wikipedia.org:

    $ kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: ServiceEntry
    metadata:
      name: www-wikipedia
    spec:
      hosts:
      - www.wikipedia.org
      ports:
      - number: 443
        name: https
        protocol: HTTPS
      resolution: DNS
    EOF
  2. Надсилайте HTTPS-запити на адреси https://en.wikipedia.org та https://uk.wikipedia.org:

    $ kubectl exec "$SOURCE_POD" -c curl -- sh -c 'curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"; curl -s https://uk.wikipedia.org/wiki/Головна_сторінка | grep -o "<title>.*</title>"'
    <title>Wikipedia, the free encyclopedia</title>
    <title>Вікіпедія</title>
  3. Перевірте статистику проксі вихідного шлюзу на наявність лічильника, який відповідає вашим запитам до *.wikipedia.org:

$ kubectl exec "$(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}')" -c istio-proxy -n istio-system -- pilot-agent request GET clusters | grep '^outbound|443||www.wikipedia.org.*cx_total:'
outbound|443||www.wikipedia.org::208.80.154.224:443::cx_total::2

Вилучення налаштувань трафіку через вихідний шлюз до хосту з підстановочним знаком

$ kubectl delete serviceentry www-wikipedia
$ kubectl delete gateway istio-egressgateway
$ kubectl delete virtualservice direct-wikipedia-through-egress-gateway
$ kubectl delete destinationrule egressgateway-for-wikipedia

Конфігурація підстановочного знака для довільних доменів

Конфігурація в попередньому розділі працювала, оскільки всі сайти *.wikipedia.org можуть обслуговуватися будь-яким із серверів wikipedia.org. Однак це не завжди так. Наприклад, ви можете захотіти налаштувати контроль вихідного трафіку для доступу до більш загальних доменів з підстановочними знаками, таких як *.com або *.org. Налаштування трафіку для довільних доменів з підстановочними знаками створює проблему для шлюзів Istio; шлюз Istio можна налаштувати лише для маршрутизації трафіку до попередньо визначених хостів, попередньо визначених IP-адрес або до початкової IP-адреси призначення запиту.

У попередньому розділі ви налаштували віртуальний сервіс для перенаправлення трафіку на попередньо визначений хост www.wikipedia.org. Однак у загальному випадку ви не знаєте хост або IP-адресу, які можуть обслуговувати довільний хост, отриманий у запиті, що залишає початкову адресу призначення запиту єдиним значенням, за допомогою якого можна маршрутизувати запит. На жаль, при використанні вихідного шлюзу початкова адреса призначення запиту втрачається, оскільки початковий запит перенаправляється на шлюз, що призводить до зміни IP-адреси призначення на IP-адресу шлюзу.

Хоча цей підхід є не таким простим і дещо вразливим, оскільки він залежить від деталей реалізації Istio, ви можете використовувати фільтри Envoy для налаштування шлюзу на підтримку довільних доменів за допомогою значення SNI в запиті HTTPS або будь-якому запиті TLS для ідентифікації початкового призначення, до якого потрібно маршрутизувати запит. Один із прикладів такого підходу можна знайти в статті маршрутизація вихідного трафіку до підстановочних пунктів призначення.

Очищення

  • Зупиніть сервіс curl:

    Zip
    $ kubectl delete -f @samples/curl/curl.yaml@
  • Видаліть Istio з вашого кластера:

    $ istioctl uninstall --purge -y
Чи була ця інформація корисною?
Чи є у вас пропозиції щодо покращення?

Дякуємо за ваш відгук!