• Русский
  • Маршрутизация исходящего трафика через шлюз с помощью Istio APIs

    В этом разделе объясняется, как использовать Istio APIs для маршрутизации исходящего HTTP-трафика через шлюз, установленный с помощью gateway injection.

    Предварительные требования

    • Шлюз Istio установлен с использованием gateway injection.

    Процедура

    1. Создайте namespace с именем curl, выполнив следующую команду:

      kubectl create namespace curl
    2. Включите sidecar injection для namespace. Если в вашей конфигурации используется стратегия обновления InPlace, выполните эту команду:

      kubectl label namespace curl istio-injection=enabled
      NOTE

      Если вы используете стратегию обновления RevisionBased, выполните следующие команды:

      1. Чтобы узнать ваше <revision-name>, выполните:

        kubectl get istiorevisions.sailoperator.io

        Пример вывода:

        NAME      NAMESPACE      PROFILE   READY   STATUS    IN USE   VERSION   AGE
        default   istio-system             True    Healthy   True     v1.28.3   47h
      2. Пометьте namespace с помощью имени ревизии, чтобы включить sidecar injection:

        kubectl label namespace curl istio.io/rev=default
    3. Разверните приложение curl, выполнив команду:

      kubectl apply -n curl -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/curl/curl.yaml
    4. Инициализируйте и экспортируйте переменную окружения CURL_POD, содержащую имя pod с curl:

      export CURL_POD=$(kubectl get pod -n curl -l app=curl -o jsonpath='{.items[0].metadata.name}')
      echo "CURL_POD=$CURL_POD"
    5. Создайте YAML-файл с именем http-se.yaml для направления трафика из mesh к внешнему сервису. В примере ниже определяется ServiceEntry для конкретного URL.

      Пример конфигурации

      apiVersion: networking.istio.io/v1
      kind: ServiceEntry
      metadata:
        name: egress-se
        namespace: curl
      spec:
        hosts:
          - docs.alauda.io
        ports:
          - number: 80
            name: http-port
            protocol: HTTP
        location: MESH_EXTERNAL
        resolution: DNS
    6. Примените этот YAML-файл, выполнив команду:

      kubectl apply -f http-se.yaml
    7. Подтвердите успешное применение конфигурации ServiceEntry. Отправьте HTTP-запрос к хосту, указанному на предыдущем шаге, выполнив команду:

      kubectl exec "$CURL_POD" -n curl -c curl -- curl -sSL -o /dev/null -D - http://docs.alauda.io

      Эта команда должна вернуть HTTP-коды статуса, такие как 302 (перенаправление) или 200 (успех), что подтверждает работоспособность соединения.

    8. Создайте YAML-файл с именем http-egress-gw.yaml, который создаст egress Gateway и направит трафик из mesh к хосту, определённому для внешнего сервиса.

      Пример конфигурации

      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: egress-gw
        namespace: <gateway_namespace> # Namespace, где развернут egress gateway
      spec:
        selector:
          istio: <gateway_name> # Выбирает экземпляр egress-gateway для обработки этого трафика
        servers:
          - port:
              number: 80
              name: http
              protocol: HTTP
            hosts:
              - docs.alauda.io # Хост внешнего сервиса, не полный URL.
      ---
      apiVersion: networking.istio.io/v1alpha3
      kind: DestinationRule
      metadata:
        name: egress-dr
        namespace: <gateway_namespace> # Namespace, где развернут egress gateway
      spec:
        host: <gateway_name>.<gateway_namespace>.svc.cluster.local
        subsets:
          - name: alauda-docs
    9. Примените YAML-файл, выполнив команду:

      kubectl apply -f http-egress-gw.yaml
    10. Создайте YAML-файл с именем http-egress-vs.yaml для настройки VirtualService, который будет управлять потоком трафика от sidecar приложений через egress gateway к внешнему хосту.

      Пример конфигурации

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: egress-vs
        namespace: curl # Namespace, где запущен pod curl
      spec:
        hosts:
          - docs.alauda.io # Хост внешнего сервиса, не полный URL.
        gateways:
          - mesh
          - <gateway_namespace>/egress-gw # Имя egress gateway, определённое в файле с предыдущего шага.
        http:
          - match:
              - gateways:
                  - mesh
                port: 80
            route:
              - destination:
                  host: <gateway_name>.<gateway_namespace>.svc.cluster.local
                  subset: alauda-docs
                  port:
                    number: 80
                weight: 100
          - match:
              - gateways:
                  - <gateway_namespace>/egress-gw # Имя egress gateway, определённое в файле с предыдущего шага.
                port: 80
            route:
              - destination:
                  host: docs.alauda.io
                  port:
                    number: 80
                weight: 100
    11. Примените этот YAML-файл, выполнив команду:

      kubectl apply -f http-egress-vs.yaml
    12. Повторно отправьте HTTP-запрос к URL:

      kubectl exec "$CURL_POD" -n curl -c curl -- curl -sSL -o /dev/null -D - http://docs.alauda.io

      Вывод в терминале должен быть похож на следующий:

      Пример вывода

      ...
      HTTP/1.1 302 Found
      server: envoy
      ...
      location: <example_url>
      ...
      
      HTTP/2 200
      Content-Type: text/html; charset=utf-8
    13. Подтвердите, что запрос был маршрутизирован через шлюз, выполнив команду:

      Включение логирования доступа

      Для корректной работы этого шага необходимо, чтобы логирование доступа было включено. Вы можете включить его, создав следующий ресурс Telemetry.

      kubectl apply -f - <<EOF
      apiVersion: telemetry.istio.io/v1
      kind: Telemetry
      metadata:
        name: gateway-access-log
        namespace: <gateway_namespace>
      spec:
        selector:
          matchLabels:
            istio: <gateway_name>
        accessLogging:
          - providers:
              - name: envoy
      EOF
      kubectl logs deployment/<gateway_name> -n <gateway_namespace> | tail -1

      В вашем терминале должна отобразиться информация, похожая на следующий вывод:

      Пример вывода

      [2025-09-21T07:45:45.331Z] "GET / HTTP/2" 302 - via_upstream - "-" 0 137 107 105 "10.3.0.56" "curl/8.15.0" "1503bbf4-1571-4d16-9d2b-c9817355284e" "docs.alauda.io" "119.28.207.230:80" outbound|80||docs.alauda.io 10.3.0.41:55194 10.3.0.41:80 10.3.0.56:60876 - -