• Русский
  • Открытие сервиса через Kubernetes Gateway API в ambient-режиме

    В ambient-режиме Istio Kubernetes Gateway API является рекомендуемым способом настройки маршрутизации входящего трафика. Вы можете создать ресурсы Gateway и HTTPRoute для развертывания шлюза, который делает сервисы внутри mesh доступными для внешнего трафика.

    Waypoint-прокси для маршрутизации уровня 7

    Для применения политик маршрутизации уровня 7 (L7) — включая маршрутизацию по пути и сопоставление заголовков — разверните waypoint-прокси в namespace, содержащем целевой сервис. Waypoint-прокси обрабатывает L7-трафик и применяет правила маршрутизации, определённые через ресурсы HTTPRoute и GRPCRoute.

    WARNING

    В ambient-режиме ресурсы VirtualService имеют ограниченную совместимость и не должны использоваться вместе с конфигурацией Gateway API. Используйте ресурсы Kubernetes Gateway API как стандартный способ маршрутизации трафика в ambient-режиме.

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

    • Установлен оператор Alauda Service Mesh v2.
    • Ресурсы Istio и IstioCNI настроены с профилем ambient.
    • Создан ресурс Ztunnel.
    • Подтвердите совместимость с ядром Linux.
    • Ваш Kubernetes-кластер поддерживает внешние балансировщики нагрузки (то есть сервисы типа LoadBalancer).

    Процедура

    1. Создайте namespace с именем httpbin:

      kubectl create namespace httpbin
    2. Добавьте метку istio-discovery=enabled в namespace httpbin:

      kubectl label namespace httpbin istio-discovery=enabled
    3. Включите ambient-режим для namespace, применив метку режима dataplane:

      kubectl label namespace httpbin istio.io/dataplane-mode=ambient
    4. Разверните пример сервиса httpbin:

      kubectl apply -n httpbin -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/httpbin/httpbin.yaml
    5. Создайте файл httpbin-waypoint.yaml для определения waypoint-прокси. Этот ресурс Gateway использует класс шлюза istio-waypoint для обработки L7-трафика сервисов в namespace.

      apiVersion: gateway.networking.k8s.io/v1
      kind: Gateway
      metadata:
        name: httpbin-waypoint
        namespace: httpbin
        labels:
          istio.io/waypoint-for: service
      spec:
        gatewayClassName: istio-waypoint
        listeners:
          - name: mesh
            port: 15008
            protocol: HBONE
      1. Метка istio.io/waypoint-for: service указывает, что этот waypoint обрабатывает трафик для сервисов. Значение метки определяет тип обрабатываемого трафика. Подробнее см. Waypoint traffic types (документация Istio).
      2. Указывает класс шлюза istio-waypoint, который разворачивает waypoint-прокси вместо стандартного ingress-шлюза.
    6. Примените конфигурацию waypoint-прокси:

      kubectl apply -f httpbin-waypoint.yaml
    7. Пометьте сервис httpbin, чтобы направлять входящий трафик через waypoint-прокси:

      kubectl label service httpbin -n httpbin istio.io/ingress-use-waypoint=true
      NOTE

      Метка istio.io/ingress-use-waypoint=true гарантирует, что трафик, поступающий из ingress-шлюза, проходит через waypoint-прокси, позволяя применять политики L7, настроенные на waypoint, до того, как трафик достигнет сервиса httpbin.

    8. Свяжите все сервисы в namespace с waypoint-прокси, пометив namespace:

      kubectl label ns httpbin istio.io/use-waypoint=httpbin-waypoint
    9. Создайте файл httpbin-gw.yaml, определяющий ресурс Kubernetes Gateway. Он настраивает gateway-прокси для приёма HTTP-трафика на порту 80 для хоста httpbin.example.com.

      apiVersion: gateway.networking.k8s.io/v1
      kind: Gateway
      metadata:
        annotations:
          networking.istio.io/service-type: ClusterIP
        name: httpbin-gateway
        namespace: httpbin
      spec:
        gatewayClassName: istio
        listeners:
          - name: default
            hostname: "httpbin.example.com"
            port: 80
            protocol: HTTP
            allowedRoutes:
              namespaces:
                from: All
      1. Указывает тип Service для шлюза; по умолчанию LoadBalancer.
      2. Указывает виртуальное имя хоста, которое клиенты используют при доступе к mesh-сервису на этом порту.
    10. Примените конфигурацию шлюза:

      kubectl apply -f httpbin-gw.yaml
    11. Создайте файл httpbin-ingress-hr.yaml, определяющий ресурс HTTPRoute для ingress-шлюза. Этот ресурс задаёт, как трафик маршрутизируется от gateway-прокси к сервису httpbin.

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: httpbin-ingress
        namespace: httpbin
      spec:
        parentRefs:
          - name: httpbin-gateway
            namespace: httpbin
        hostnames:
          - "httpbin.example.com"
        rules:
          - backendRefs:
              - name: httpbin
                port: 8000
      1. Привязывает этот HTTPRoute к Kubernetes Gateway, созданному на предыдущем шаге.
      2. Маршрутизирует подходящий трафик к сервису httpbin на порт 8000.
    12. Примените ingress HTTPRoute:

      kubectl apply -f httpbin-ingress-hr.yaml
    13. Создайте файл httpbin-waypoint-hr.yaml, определяющий ресурс HTTPRoute для waypoint-прокси. Этот ресурс настраивает правила маршрутизации по пути, которые применяет waypoint.

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: httpbin-waypoint-route
        namespace: httpbin
      spec:
        parentRefs:
          - group: ""
            kind: Service
            name: httpbin
            namespace: httpbin
        rules:
          - matches:
              - path:
                  type: PathPrefix
                  value: /status
              - path:
                  type: PathPrefix
                  value: /headers
            backendRefs:
              - name: httpbin
                port: 8000
      1. Привязывает этот HTTPRoute к сервису httpbin. В сочетании с меткой istio.io/ingress-use-waypoint=true это настраивает правила маршрутизации L7, которые применяет waypoint-прокси для трафика, направленного к сервису.
      2. Перенаправляет подходящий трафик к сервису httpbin на порт 8000.
    14. Примените waypoint HTTPRoute:

      kubectl apply -f httpbin-waypoint-hr.yaml
      NOTE

      В этой конфигурации трафик из ingress-шлюза проходит через waypoint-прокси благодаря метке istio.io/ingress-use-waypoint=true на сервисе. Затем waypoint HTTPRoute применяет политики маршрутизации по пути до того, как трафик достигнет сервиса httpbin.

    15. Дождитесь готовности waypoint-прокси:

      kubectl wait --for=condition=programmed gtw httpbin-waypoint -n httpbin

    Проверка

    1. Создайте namespace для клиента curl:

      kubectl create namespace curl
    2. Разверните клиент curl:

      kubectl apply -n curl -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/curl/curl.yaml
    3. Добавьте метку istio-discovery=enabled в namespace curl:

      kubectl label namespace curl istio-discovery=enabled
    4. Включите ambient-режим для namespace curl:

      kubectl label namespace curl istio.io/dataplane-mode=ambient
    5. Сохраните имя pod клиента curl в переменную:

      export CURL_POD=$(kubectl get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}')
      echo "CURL_POD=$CURL_POD"
    6. С клиента curl отправьте запрос к эндпоинту /headers приложения httpbin через ingress-шлюз Service. Установите заголовок Host в httpbin.example.com, чтобы он соответствовал хосту, указанному в ресурсах Kubernetes Gateway и HTTPRoute:

      kubectl exec $CURL_POD -n curl -- \
        curl -sS -I \
          -H Host:httpbin.example.com \
          httpbin-gateway-istio.httpbin.svc.cluster.local/headers

      В ответе должен быть статус HTTP/1.1 200 OK, что означает успешную обработку запроса.

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

      HTTP/1.1 200 OK
      ...
      server: istio-envoy
      ...
    7. Отправьте запрос к эндпоинту без соответствующего префикса URI в waypoint HTTPRoute:

      kubectl exec $CURL_POD -n curl -- \
        curl -sS -I \
          -H Host:httpbin.example.com \
          httpbin-gateway-istio.httpbin.svc.cluster.local/get

      В ответе будет HTTP/1.1 404 Not Found, что ожидаемо, так как путь /get не имеет соответствующего префикса в waypoint HTTPRoute.

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

      HTTP/1.1 404 Not Found
      ...
      server: istio-envoy
      ...
    8. Откройте gateway-прокси для трафика вне кластера, изменив тип Service на значение по умолчанию LoadBalancer:

      kubectl -n httpbin annotate gtw httpbin-gateway networking.istio.io/service-type-
    9. Проверьте доступность сервиса httpbin извне кластера, используя внешний hostname или IP-адрес gateway Service. Установите переменную INGRESS_HOST в соответствии с вашей средой кластера.

      a. Установите переменную INGRESS_HOST:

      export INGRESS_HOST=$(kubectl get gtw httpbin-gateway -n httpbin -o jsonpath='{.status.addresses[0].value}')
      echo "INGRESS_HOST=$INGRESS_HOST"

      b. Установите переменную INGRESS_PORT:

      export INGRESS_PORT=$(kubectl get gtw httpbin-gateway -n httpbin -o jsonpath='{.spec.listeners[?(@.name=="default")].port}')
      echo "INGRESS_PORT=$INGRESS_PORT"

      c. Отправьте запрос curl к сервису httpbin, используя хост gateway:

      INFO

      Если $INGRESS_HOST — это IPv6-адрес, заключите его в квадратные скобки при формировании URL. Например:

      curl -sS -g -I -H Host:httpbin.example.com http://[$INGRESS_HOST]:$INGRESS_PORT/headers
      curl -sS -g -I -H Host:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/headers
    10. Убедитесь, что в ответе присутствует статус HTTP/1.1 200 OK, что означает успешное выполнение запроса.

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

      HTTP/1.1 200 OK
      ...
      server: istio-envoy
      ...

    Очистка

    Удалите ресурсы, созданные в этой процедуре:

    # Удалите метки ambient dataplane из namespace
    kubectl label namespace curl istio.io/dataplane-mode-
    kubectl label namespace httpbin istio.io/dataplane-mode-
    # Удалите namespace
    kubectl delete namespace curl
    kubectl delete namespace httpbin