Открытие сервиса через Istio Gateway и ресурсы VirtualService

В этом руководстве показано, как использовать ресурсы Istio Gateway и VirtualService для настройки gateway, развернутого с помощью gateway injection. Эти ресурсы настраивают gateway для открытия сервиса внутри mesh для трафика извне. После этого вы открываете gateway для внешнего трафика кластера, изменяя Service gateway на тип LoadBalancer.

Содержание

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

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

Процедура

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

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

    kubectl label namespace httpbin 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. Пометьте пространство имен с помощью имени ревизии, чтобы включить sidecar injection:

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

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

    apiVersion: networking.istio.io/v1
    kind: Gateway
    metadata:
      name: httpbin-gateway
      namespace: httpbin
    spec:
      selector:
        istio: <gateway_name>
      servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
            - httpbin.example.com
    1. Установите selector, чтобы он соответствовал уникальной метке или меткам, определенным в шаблоне pod для Deployment gateway proxy. По умолчанию конфигурация Istio Gateway применяется к соответствующим pod gateway во всех пространствах имен.
    2. В поле hosts укажите адреса, по которым клиенты могут получить доступ к mesh-сервису на соответствующем порту.
  5. Примените YAML-файл с помощью команды:

    kubectl apply -f httpbin-gw.yaml
  6. Создайте другой YAML-файл с именем httpbin-vs.yaml для VirtualService. Этот VirtualService определит правила маршрутизации трафика от gateway proxy к сервису httpbin.

    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: httpbin
      namespace: httpbin
    spec:
      hosts:
        - httpbin.example.com
      gateways:
        - httpbin-gateway
      http:
        - match:
            - uri:
                prefix: /status
            - uri:
                prefix: /headers
          route:
            - destination:
                port:
                  number: 8000
                host: httpbin
    1. Определите hosts, к которым будут применяться правила маршрутизации VirtualService. Указанные hosts должны быть открыты ресурсом Istio Gateway, к которому прикреплен этот VirtualService.
    2. Прикрепите VirtualService к ресурсу Istio Gateway из предыдущего шага, добавив имя Gateway в список gateways.
    3. Направьте совпадающий трафик к ранее развернутому сервису httpbin, определив destination, который указывает host и port сервиса httpbin.
  7. Примените YAML-файл с помощью команды:

    kubectl apply -f httpbin-vs.yaml

Проверка

  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. Сохраните имя pod клиента curl в переменную CURL_POD, выполнив команду:

    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, чтобы он соответствовал хосту, указанному в Istio Gateway и VirtualService. Выполните следующую команду curl:

    kubectl exec $CURL_POD -n curl -- \
      curl -s -I \
        -H Host:httpbin.example.com \
        <gateway_name>.<gateway_namespace>.svc.cluster.local/headers
  5. В ответе должен быть статус HTTP 200 OK, подтверждающий успешность запроса.

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

    HTTP/1.1 200 OK
    server: istio-envoy
    ...
  6. Отправьте другой запрос к эндпоинту, для которого нет соответствия URI prefix в VirtualService httpbin, выполнив команду:

    kubectl exec $CURL_POD -n curl -- \
      curl -s -I \
        -H Host:httpbin.example.com \
        <gateway_name>.<gateway_namespace>.svc.cluster.local/get

    В ответе должен быть статус 404 Not Found. Это ожидаемый результат, так как для эндпоинта /get не определено соответствие URI prefix в VirtualService httpbin.

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

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

    kubectl patch service <gateway_name> -n <gateway_namespace> -p '{"spec": {"type": "LoadBalancer"}}'
  8. Убедитесь, что сервис httpbin доступен извне кластера через внешний hostname или IP-адрес сервиса gateway. Не забудьте правильно установить переменную INGRESS_HOST для вашей среды кластера.

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

      INGRESS_HOST=$(kubectl get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

      В некоторых средах load balancer может быть доступен по имени хоста, а не по IP-адресу. В этом случае значение EXTERNAL-IP ingress gateway не будет IP-адресом, а именем хоста, и приведённая выше команда не сможет установить переменную окружения INGRESS_HOST. Используйте следующую команду для корректировки значения INGRESS_HOST:

      INGRESS_HOST=$(kubectl get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
    2. Отправьте запрос curl к сервису httpbin через хост gateway, выполнив команду:

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