Открытие сервиса через Kubernetes Gateway API

Вы можете использовать Kubernetes Gateway API для создания ресурсов Gateway и HTTPRoute для развертывания шлюза. Эти ресурсы настраивают шлюз так, чтобы сделать сервис внутри mesh доступным для трафика извне. Затем вы можете изменить Service шлюза на LoadBalancer, чтобы открыть его для трафика вне кластера.

Содержание

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

  • Установлен Alauda Service Mesh v2 Operator.
  • Развернута контрольная плоскость Istio.

Процедура

  1. Создайте новое пространство имён с именем httpbin с помощью следующей команды:

    kubectl create namespace httpbin
  2. Разверните пример сервиса httpbin с помощью этой команды:

    kubectl apply -n httpbin -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/httpbin/httpbin.yaml
  3. Создайте файл с именем httpbin-k8s-gw.yaml, который определяет ресурс Kubernetes Gateway. Это настроит прокси-шлюзы для открытия порта 80 (HTTP) для хоста httpbin.example.com.

    Автоматическое развертывание

    По умолчанию каждый Gateway автоматически создаёт Service и Deployment. Они будут иметь имена в формате <Gateway name>-<GatewayClass name> (за исключением GatewayClass с именем istio-waypoint, который не добавляет суффикс). Эти конфигурации будут автоматически обновляться при изменении Gateway (например, при добавлении нового порта).

    Пример файла ресурса gateway

    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: http
          hostname: "httpbin.example.com"
          port: 80
          protocol: HTTP
          allowedRoutes:
            namespaces:
              from: All
    1. Указывает тип Service для шлюза; по умолчанию LoadBalancer.
    2. Указывает имя шлюза.
    3. Указывает пространство имён шлюза.
    4. Указывает виртуальное имя хоста, которое клиенты будут использовать для доступа к сервису mesh на этом порту.
  4. Примените YAML-файл с помощью команды:

    kubectl apply -f httpbin-k8s-gw.yaml
  5. Создайте YAML-файл с именем httpbin-hr.yaml, который определяет ресурс HTTPRoute. Этот ресурс задаёт правила маршрутизации трафика от прокси-шлюза к сервису httpbin.

    Пример файла HTTPRoute

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin
      namespace: httpbin
    spec:
      parentRefs:
      - name: httpbin-gateway
        namespace: httpbin
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /status
        - path:
            type: PathPrefix
            value: /headers
        backendRefs:
        - name: httpbin
          port: 8000
    1. Связывает ресурс HTTPRoute с ранее созданным Kubernetes Gateway, добавляя имя шлюза в список.
    2. Направляет совпадающий трафик к сервису httpbin, определяя запись backendRefs с именем и портом сервиса httpbin.
  6. Примените YAML-файл, выполнив команду:

    kubectl apply -f httpbin-hr.yaml
  7. Убедитесь, что сервис Gateway API готов и имеет выделенный адрес, выполнив команду:

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

Проверка

  1. Создайте пространство имён для клиента 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. Установите переменную CURL_POD с именем pod клиента curl с помощью команды:

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

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

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

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

    HTTP/1.1 200 OK
    server: istio-envoy
    ...
  5. Отправьте запрос curl к эндпоинту без совпадающего префикса URI в HTTPROUTE сервиса httpbin, выполнив команду:

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

    В ответе будет статус 404 Not Found. Это ожидаемо, так как эндпоинт /get не имеет совпадающего префикса URI, определённого в ресурсе HTTPROUTE сервиса httpbin.

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

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

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

    1. Установите переменную INGRESS_HOST, выполнив команду:

      export INGRESS_HOST=$(kubectl get gtw httpbin-gateway -n httpbin -o jsonpath='{.status.addresses[0].value}')
    2. Установите переменную INGRESS_PORT, выполнив команду:

      INGRESS_PORT=$(kubectl get gtw httpbin-gateway -n httpbin -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')
    3. Используя хост шлюза, отправьте запрос curl к сервису httpbin с помощью команды:

      curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/headers
  8. Убедитесь, что в ответе отображается статус HTTP/1.1 200 OK, что подтверждает успешность запроса.