Маршрутизация исходящего трафика через шлюз с помощью 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.26.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}')
  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 Moved Permanently
    ...
    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 - -