Руководство прикладного разработчика#

Термины и определения#

Термин/аббревиатура

Определение

Платформа

Платформа оркестрации приложений со средствами автоматизации и управления на основе политик, например Kubernetes

Istio SE

Настраиваемая сервисная сетка с открытым исходным кодом, служащая для взаимодействия, мониторинга и обеспечения безопасности контейнеров в кластере Kubernetes

Platform V Synapse Service Mesh / SSM

Программный продукт на базе Istio SE, обеспечивающий возможность создания сервисной сети поверх Платформенной в Kubernetes

Контрольная панель

Проект, где запущены управляющие приложения Synapse Service Mesh (компонент POLM)

Управление политиками / POLM

Компонент Управление политиками из состава продукта Platform V Synapse Service Mesh

Граничный прокси / IGEG

Компонент Граничный прокси продукта Platform V Synapse Service Mesh

Сервисный прокси / SVPX

Компонент Сервисный прокси продукта Platform V Synapse Service Mesh

Ingress Gateway

Входная точка в проект компонента IGEG

Egress Gateway

Выходная точка из проекта компонента IGEG

istio-proxy

Граничный прокси - контейнер, предназначенный для маршрутизации трафика

Deployment

Набор инструкций для запуска приложения в Kubernetes

Pod

Набор контейнеров внутри узла кластера Kubernetes

TLS

Transport Layer Security, протокол защиты транспортного уровня

Системные требования#

Для использования компонента Граничный прокси из состава продукта Platform V Synapse Service Mesh необходимо выполнение следующих пререквизитов:

  • кластер Kubernetes (версии 1.19 и выше) развернут и настроен в соответствии с требованиями, предъявляемыми к Платформе;

  • в проекте создана учетная запись с правами на создание конфигураций;

  • настроен доступ для публикации образов разрабатываемых приложений в Docker-репозиторий;

  • на рабочей машине пользователя установлен клиент Kubernetes (kubectl) для доступа в Kubernetes c использованием консоли;

  • на рабочей машине пользователя установлен клиент istioctl, поставляемый в дистрибутиве.

Подключение и конфигурирование#

Подключение#

Подключение осуществляется администраторами прикладного проекта. Процесс описан в документе Руководство по установке.

Конфигурирование#

Сценарий 1. Настройка обработчиков на Ingress Gateway для входящего трафика#

Для настройки маршрутизации трафика на Ingress Gateway необходимо определиться с протоколом входящего трафика. Далее разберем примеры с HTTP- и HTTPS-трафиком.

HTTP-трафик

Шаблон конфигурации Service для граничного прокси:

kind: Service
apiVersion: v1
metadata:
  name: <имя_сервиса_по_которому_будут_обращаться_к_граничному_прокси>
spec:
  ports:
    - name: http
      protocol: TCP
      port: <порт_на_который_будут_обращаться_к_граничному_прокси>
      targetPort: <порт_на_котором_будет_поднят_обработчик>
  selector:
    <label1>: <value1>
    <label2>: <value2>
    ...
  type: ClusterIP

Пример Service:

kind: Service
apiVersion: v1
metadata:
  name: istio-ingressgateway
spec:
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
  selector:
    app: istio-ingressgateway
    istio: ingressgateway
  type: ClusterIP

Конфигурация Service позволит обращаться к граничному прокси. Для работы обработчика событий необходимо создать конфигурацию Gateway.

Шаблон конфигурации Gateway:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: <имя_конфига_gateway>
spec:
  selector:
    <label1>: <value1>
    <label2>: <value2>
  servers:
  - port:
      number: <порт_обработчика_событий>
      name: <имя_порта>
      protocol: <протокол_обработчика_событий>
    hosts:
    - <имя_хоста_на_который_пришел_запрос>

Для Pod в разделе selector указываются labels. Gateway будет получать трафик c Pod, на которых объявлены метки, указанные в labels конфигурации Gateway.

В host могут указываться как wildcard-значения, так и доменные имена в формате FQDN.

Для HTTP-трафика значение поля host должно совпадать со значением заголовка Host в поступающем запросе.

Для HTTP2/gRPC значение поле host должно совпадать со значением заголовка Authority.

В protocol в качестве протокола можно выбрать: HTTP, HTTPS, GRPC, HTTP2, MONGO, TCP или TLS 1.2.

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

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-ingress
spec:
  selector:
    app: istio-ingressgateway
    istio: ingressgateway
  servers:
  - port:
      number: 8080
      name: http
      protocol: HTTP
    hosts:
    - "*"

Для маршрутизации запроса, полученного граничным прокси, в прикладной сервис необходимо создать конфигурацию VirtualService.

Шаблон конфигурации VirtualService:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: <имя_конфига>
spec:
  exportTo:
    - '.'
  hosts:
  - <имя_хоста_на_который_пришел_запрос>
  gateways:
  - <имя_конфига_Gateway>
  <протокол_трафика>:
  - match:
    - port: <порт_обработчика_Gateway>
    route:
    - destination:
        host: <имя_прикладного_сервиса>
        port:
          number: <порт_прикладного_сервиса>

В качестве <протокол_трафика> можно указать http для протоколов HTTP/HTTP2/gRPC и для терминированного на граничном прокси трафика HTTPS.

Для нетерминированного трафика TLS 1.2 / HTTPS в качестве <протокол_трафика> используется tls или tcp.

Для трафика TCP в качестве <протокол_трафика> выставляется tcp.

Пример VirtualService:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: service-vs
spec:
  exportTo:
    - '.'
  hosts:
  - istio-ingressgateway
  gateways:
  - my-ingress
  http:
  - match:
    - port: 8080
    route:
    - destination:
        host: my-server.default.svc.cluster.local
        port:
          number: 8686

HTTPS-трафик

Конфигурация для HTTPS отличается от HTTP протоколом обработчика и наличием сертификатов.

HTTPS в качестве протокола безопасности использует TLS 1.2.

Для одностороннего TLS 1.2 валидируются только сертификаты сервера, а для двустороннего (mutual TLS 1.2, mTLS 1.2) валидируются сертификаты клиента и сервера. В режиме mTLS 1.2 клиенту необходимо предъявлять свой сертификат, иначе SSL 1.0 handshake не будет установлен.

В отличие от HTTP, для трафика HTTPS в конфигурации Gateway в параметре host указывается значение SNI протокола TLS 1.2. SNI проставляется на стороне клиента и обычно совпадает с DNS-именем host, на который отправляется запрос.

Шаблон конфигурации Gateway для одностороннего HTTPS:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: <имя_конфига>
spec:
  selector:
    <label1>: <value1>
    <label2>: <value2>
  servers:
  - port:
      number: 8080
      name: https
      protocol: HTTPS
    hosts:
    - <имя_хоста_на_который_пришел_запрос>
    tls:
      mode: SIMPLE
      caCertificates: <путь_к_цепочке_сертификатов_в_формате_pem>
      serverCertificate:  <путь_к_серверному_сертификату_в_формате_pem>
      privateKey: <путь_к_дешифрованному_приватному_ключу_для_серверного_сертификата_в_формате_pem>

В полях caCertificates, serverCertificate и privateKey задаются пути к соответствующим файлам в Pod.

Для корректной работы обработчика событий (а также для запуска и работы контейнера istio-proxy) необходимо подмонтировать сертификаты и ключ в Pod, а затем указать в перечисленных выше полях конфигурации абсолютный путь к файлам.

Шаблон конфигурации Gateway для двустороннего TLS 1.2:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: <имя_конфига>
spec:
  selector:
    <label1>: <value1>
    <label2>: <value2>
  servers:
  - port:
      number: 8080
      name: https
      protocol: HTTPS
    hosts:
    - <имя_хоста_на_который_пришел_запрос>
    tls:
      mode: MUTUAL
      caCertificates: <путь_к_цепочке_сертификатов_в_формате_pem>
      serverCertificate:  <путь_к_серверному_сертификату_в_формате_pem>
      privateKey: <путь_к_дешифрованному_приватному_ключу_для_серверного_сертификата_в_формате_pem>

Пример Gateway:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-ingress
spec:
  selector:
    app: istio-ingressgateway
    istio: ingressgateway
  servers:
  - port:
      number: 8080
      name: http
      protocol: HTTP
    hosts:
    - "*"
    tls:
      mode: MUTUAL
      caCertificates: /etc/certs/ca.pem
      serverCertificate: /etc/certs/servercert.pem
      privateKey: /etc/certs/privatekey.pem

Шифрование трафика на участке Ingress Gateway - прикладной сервис

По умолчанию трафик, поступивший на Ingress Gateway, расшифровывается, и дальнейший вызов прикладного сервиса выполняется в виде plain text. Рекомендуется настроить шифрование (терминацию) трафика на граничном прокси.

Для добавления шифрования между входным граничным прокси и прикладным сервисом необходимо создать конфигурацию DestinationRule.

Шаблон конфигурации DestinationRule:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: <имя_конфига>
spec:
  exportTo:
    - '.'
  host: <имя_прикладного_сервиса>
  workloadSelector:
    matchLabels:
      <label1>: <value1>
      <label2>: <value2>
  trafficPolicy:
    portLevelSettings:
    - port:
        number: <порт_прикладного_сервиса>
      tls:
        mode: ISTIO_MUTUAL

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

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: mtls-service
spec:
  exportTo:
    - '.'
  host: my-server.default.svc.cluster.local
  workloadSelector:
    matchLabels:
      app: dbserver
      version: v1
  trafficPolicy:
    portLevelSettings:
    - port:
        number: 8686
      tls:
        mode: ISTIO_MUTUAL

Значение mode: ISTIO_MUTUAL означает, что при взаимодействии между Pods прикладных сервисов внутри проекта будет использоваться двусторонний TLS 1.2, а в качестве сертификатов будут использоваться специальные сертификаты, выпускаемые компонентом POLM Platform V Synapse Service Mesh.

Сервис управления политиками (POLM) генерирует специальные сертификаты для шифрования трафика внутри проекта. Сертификаты автоматически создаются, добавляются в нужные прокси и обновляются, когда срок их службы подходит к концу.


Сценарий 2. Настройка маршрутизации трафика на Egress Gateway#

Для настройки маршрутизации исходящего из проекта трафика на граничном прокси (Egress Gateway) необходимо создать ряд конфигураций.

Если в Istio на уровне сервиса управления политиками в настройке outboundTrafficPolicy.mode включен режим REGISTRY_ONLY, то перед тем как создать конфиги для маршрутизации трафика на Egress Gateway, нужно создать конфигурацию ServiceEntry.

Значение REGISTRY_ONLY настройки outboundTrafficPolicy.mode настраивает все прокси таким образом, что они пропускают трафик только на сервисы, объявленные внутри проекта. На любой внешний host/сервис необходимо создавать конфигурацию ServiceEntry, которая зарегистрирует внешний host в реестре сервисов проекта. Тогда прокси смогут обращаться к host.

Противоположное REGISTRY_ONLY значение — ALLOW_ANY, такое значение не требует создание конфигураций ServiceEntry.

Шаблон конфигурации ServiceEntry:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: <имя_конфига>
spec:
  exportTo:
    - '.'
  hosts:
  - <внешний_хост>
  ports:
  - number: <порт_внешнего_сервиса>
    name: <имя_порта_внешнего_сервиса>
    protocol: <протокол_внешнего_сервиса>
  resolution: <способ_резолвинга_ip_внешнего_хоста>
  location: MESH_EXTERNAL

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

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: tl-snap-28
spec:
  exportTo:
    - '.'
  hosts:
  - tl-snap-28.ms.cloud.ru
  ports:
  - number: 9440
    name: http
    protocol: HTTP
  resolution: DNS
  location: MESH_EXTERNAL

Теперь нужно создать Service для Egress Gateway. Именно через этот Service будут проходить запросы к сервисам извне кластера. Конфигурация аналогична Ingress.

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

kind: Service
apiVersion: v1
metadata:
  name: istio-egressgateway
spec:
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
  selector:
    app: istio-egressgateway
    istio: egressgateway
  type: ClusterIP

Чтобы настроить маршрутизацию трафика на Egress Gateway, нужно создать по аналогии с Ingress Gateway конфигурацию Gateway.

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

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-egress
spec:
  selector:
    app: istio-egressgateway
    istio: egressgateway
  servers:
  - port:
      number: 8080
      name: http
      protocol: HTTP
    hosts:
    - tl-snap-28.ms.cloud.ru

Далее необходимо создать конфигурацию VirtualService, которая будет получать запросы к внешнему по отношению к проекту host на Service Egress, а затем уже отправлять его с Egress Gateway.

Шаблон конфигурации VirtualService:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: <имя_конфига>
spec:
  exportTo:
    - '.'
  hosts:
  - <внешний_хост>
  gateways:
  - <имя_конфига_Gateway_для_Egress>
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: <порт_внешнего_хоста>
    route:
    - destination:
        host: <имя_сервиса_Egress>
        port:
          number: <порт_сервиса_Egress>
      weight: 100
  - match:
    - gateways:
      - <имя_конфига_Gateway_для_Egress>
      port: <порт_сервиса_Egress>
    route:
    - destination:
        host: <внешний_хост>
        port:
          number: <порт_внешнего_хоста>
      weight: 100

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

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-for-tl-snap-28
spec:
  exportTo:
    - '.'
  hosts:
  - tl-snap-28.ms.cloud.ru
  gateways:
  - my-egress
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 9440
    route:
    - destination:
        host: istio-egressgateway.default.svc.cluster.local
        port:
          number: 80
      weight: 100
  - match:
    - gateways:
      - my-egress
      port: 80
    route:
    - destination:
        host: tl-snap-28.ms.cloud.ru
        port:
          number: 9440
      weight: 100

HTTPS для исходящего трафика

Если требуется устанавливать шифрование исходящего трафика, исходящего из граничного прокси, то необходимо заменить протокол с HTTP на HTTPS в ServiceEntry.

Пример ServiceEntry:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: tl-snap-28
spec:
  exportTo:
    - '.'
  hosts:
  - tl-snap-28.ms.cloud.ru
  ports:
  - number: 9440
    name: http
    protocol: HTTPS
  resolution: DNS
  location: MESH_EXTERNAL

Далее необходимо создать конфигурацию DestinationRule, где указать сертификаты для обращения к внешнему адресу.

Пример DestinationRule:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: mtls-tl-snap-28
spec:
  exportTo:
    - '.'
  host: tl-snap-28.ms.cloud.ru
  trafficPolicy:
    portLevelSettings:
    - port:
        number: 9440
      tls:
        mode: MUTUAL
        sni: tl-snap-28.ms.cloud.ru
        clientCertificate: /etc/certs/myclientcert.pem
        privateKey: /etc/certs/client_private_key.pem
        caCertificates: /etc/certs/ca.pem

В DestinationRule пути к файлам указываются аналогично сертификатам в конфигурации Gateway, только для клиентских сертификатов, с которыми будет совершаться вызов внешнего host с граничного прокси Egress Gateway. Соответственно, файлы нужно подмонтировать в Pod Egress Gateway по путям, которые были указаны в DestinationRule.

Далее необходимо настроить маршрутизацию от Egress к внешнему сервису с помощью конфигурации VirtualService.

Пример VirtualService:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-for-tl-snap-28
spec:
  exportTo:
    - '.'
  hosts:
  - tl-snap-28.ms.cloud.ru
  gateways:
  - my-egress
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 9440
    route:
    - destination:
        host: istio-egressgateway.default.svc.cluster.local
        port:
          number: 80
      weight: 100
  - match:
    - gateways:
      - my-egress
      port: 80
    route:
    - destination:
        host: tl-snap-28.ms.cloud.ru
        port:
          number: 9440
      weight: 100

Также рекомендуется создать конфигурацию DestinationRule для шифрования внутреннего трафика между Service Mesh и граничным прокси Egress.

Пример DestinationRule:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: mtls-egress
spec:
  exportTo:
    - '.'
  host: istio-egressgateway.default.svc.cluster.local
  trafficPolicy:
    portLevelSettings:
    - port:
        number: 9440
      tls:
        mode: ISTIO_MUTUAL

И добавить шифрование в конфигурацию Gateway.

Пример Gateway:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-egress
spec:
  selector:
    app: istio-egressgateway
    istio: egressgateway
  servers:
  - hosts:
    - tl-snap-28.ms.cloud.ru
    port:
      number: 8080
      name: http
      protocol: HTTP
    tls:
      mode: ISTIO_MUTUAL

Сценарий 3. Отключение обслуживания новых соединений после получения sigTerm#

Мягкое отключение подразумевает, что после получения sigTERM Pod будет вести себя следующим образом:

  • прекращает прием новых запросов;

  • закрывает персистентные соединения;

  • ожидает завершения (drain) открытых запросов.

С целью обеспечения функциональности мягкого отключения рекомендуется в Deployment граничных прокси указать:

    spec:
        terminationGracePeriodSeconds: 60 # время на завершение контейнера в секундах
     containers:
       - name: istio-proxy
         env:
           - name: TERMINATION_DRAIN_DURATION_SECONDS
             value: '45' # время на завершение запросов и соединений в секундах

Использование аннотаций обеспечивает мягкое отключение оставшихся Pods, для этого в Deployment сервисов с бизнес-логикой необходимо добавить:

spec:
  template:
    metadata:
      annotations:
        proxy.istio.io/config: |
          proxyMetadata:
            TERMINATION_DRAIN_DURATION_SECONDS: "45"

Сценарий 4. Настройка защищенного соединения с PostgreSQL на Egress Gateway#

В Synapse Service Mesh 3.6 (Istio 1.12) появилась возможность подключиться к БД PostgreSQL по SSL 1.0 и выше без необходимости написания дополнительного envoy-фильтра.

Начиная с версии SSM 3.11 добавлена возможность подключения к БД PostgreSQL через Egress без шифрования.

Работоспособность проверена с версиями PostgreSQL 11.2 и 14.1.

Можно подключиться с разными клиентскими сертификатами для нескольких пользователей БД (от разных клиентских приложений).

Сертификаты для подключения к БД настраиваются на Egress, клиентское приложение не хранит их.

Клиентское приложение должно инициировать подключение к БД без шифрования (параметр sslmode=disable строки подключения), так как его устанавливает Egress.

Настройка сертификатов для одного пользователя

Для настройки защищенного соединения к PostgreSQL необходимо создать ServiceEntry, для добавления сервера БД в реестр сервисов Istio, и указать там протокол postgres (регистр не важен).

Если подключение к БД выполняется с шифрованием, то в DestinationRule, которое маршрутизирует трафик к серверу БД, необходимо указать клиентские сертификаты из файлов, подмонтированных в Deployment Egress'а, или secrets Kubernetes. Параметр tls.mode должен быть установлен равным MUTUAL.

Если подключение к БД выполняется без шифрования, то можно не указывать параметры шифрования в DestinationRule, которое маршрутизирует трафик к серверу БД.

Пример Gateway:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: egress-gw
spec:
  selector:
    app: egress
  servers:
  - hosts:
    - test-postgres-db.XXXX.XX.XXX
    port:
      name: tls-54321
      number: 54321
      protocol: TLS
    tls:
      mode: ISTIO_MUTUAL

Пример DestinationRule для обращения к сервису Gateway с шифрованием ISTIO_MUTUAL:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: egress-gw-svc-dr
spec:
  exportTo:
  - .
  host: egress-gw-svc.test-pg-single.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
    portLevelSettings:
    - port:
        number: 54321
      tls:
        mode: ISTIO_MUTUAL
        sni: test-postgres-db.XXXX.XX.XXX

Пример ServiceEntry для обращения к серверу БД:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: postgres-se
spec:
  exportTo:
  - '.'
  hosts:
  - test-postgres-db.XXXX.XX.XXX
  ports:
  - name: postgres-5432
    number: 5432
    protocol: postgres
  resolution: DNS
  location: MESH_EXTERNAL

Пример DestinationRule для обращения к серверу БД с шифрованием (сертификаты должны быть в текстовом формате pem):

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: postgres-dr
spec:
  exportTo:
  - .
  host: test-postgres-db.XXXX.XX.XXX
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
    tls:
      caCertificates: /var/lib/postgresql/tucerts/ca.crt
      clientCertificate: /var/lib/postgresql/tucerts/tls.crt
      mode: MUTUAL
      privateKey: /var/lib/postgresql/tucerts/tls.key
  workloadSelector:
    matchLabels:
      app: egress

Пример DestinationRule для обращения к серверу БД без шифрования:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: postgres-dr
spec:
  exportTo:
  - .
  host: test-postgres-db.XXXX.XX.XXX
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
    # tls:
    #   caCertificates: /var/lib/postgresql/tucerts/ca.crt
    #   clientCertificate: /var/lib/postgresql/tucerts/tls.crt
    #   mode: MUTUAL
    #   privateKey: /var/lib/postgresql/tucerts/tls.key
  workloadSelector:
    matchLabels:
      app: egress

Пример проекта с одним пользователем

Проект Kubernetes / OpenShift находится в папке

/ssm_documents/IGEG/info/samples/postgres_ssl_single

Описание его сущностей:

/ssm_documents/IGEG/info/samples/postgres_ssl_single/README.md

Описание тестирования:

/ssm_documents/IGEG/info/samples/postgres_ssl_single/index.md

Настройка сертификатов для нескольких пользователей

Чтобы указать разные сертификаты для подключения к одному адресу и порту БД, нужно:

  • поднять внутренний Gateway с таким количеством портов, сколько будет разных пользователей БД (т.е. разных сертификатов для подключения к БД):

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: egress-gw
spec:
  selector:
    app: egress
  servers:
  - hosts:
    - test-postgres-db.XXXX.XX.XXX
    port:
      name: tls-54320-postgres
      number: 54320
      protocol: TLS
    tls:
      mode: ISTIO_MUTUAL
  - hosts:
    - test-postgres-db.XXXX.XX.XXX
    port:
      name: tls-54321-testuser
      number: 54321
      protocol: TLS
    tls:
      mode: ISTIO_MUTUAL
  • в VirtualService развести трафик от разных клиентских приложений по разным портам внутреннего Gateway, используя labels клиентских приложений:

  tcp:
  - match:
    - gateways:
      - mesh
      sourceLabels:
        app: pg-client-postgres
    route:
    - destination:
        host: egress-gw-svc.test-pg-multi.svc.cluster.local
        port:
          number: 54320
  - match:
    - gateways:
      - mesh
      sourceLabels:
        app: pg-client-testuser
    route:
    - destination:
        host: egress-gw-svc.test-pg-multi.svc.cluster.local
        port:
          number: 54321
  - match:
    - gateways:
      - mesh
      sourceLabels:
        app: pg-client-java
    route:
    - destination:
        host: egress-gw-svc.test-pg-multi.svc.cluster.local
        port:
          number: 54321
  • в VirtualService направить трафик, который должен быть зашифрован разными сертификатами, на разные subsets:

  - match:
    - gateways:
      - egress-gw
      port: 54320
    route:
    - destination:
        host: test-postgres-db.XXXX.XX.XXX
        port:
          number: 5432
        subset: postgres-back
  - match:
    - gateways:
      - egress-gw
      port: 54321
    route:
    - destination:
        host: test-postgres-db.XXXX.XX.XXX
        port:
          number: 5432
        subset: testuser-back
  • объявить соответствующие subsets в Destination Rule и прописать там сертификаты (они должны быть в текстовом формате pem):

  subsets:
  - labels:
      version: postgres-back
    name: postgres-back
    trafficPolicy:
      portLevelSettings:
      - port:
          number: 5432
        tls:
          mode: MUTUAL
          clientCertificate: /var/lib/postgresql/pgcerts/tls.crt
          privateKey: /var/lib/postgresql/pgcerts/tls.key
          caCertificates: /var/lib/postgresql/pgcerts/ca.crt
  - labels:
      version: testuser-back
    name: testuser-back
    trafficPolicy:
      portLevelSettings:
      - port:
          number: 5432
        tls:
          mode: MUTUAL
          clientCertificate: /var/lib/postgresql/tucerts/tls.crt
          privateKey: /var/lib/postgresql/tucerts/tls.key
          caCertificates: /var/lib/postgresql/tucerts/ca.crt
  • создать столько ServiceEntry и WorkloadEntry, сколько будет разных пользователей БД (т.е. разных сертификатов для подключения к БД), и связать каждый ServiceEntry с WorkloadEntry:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: postgres-back-se
spec:
  exportTo:
  - '.'
  hosts:
  - test-postgres-db.XXXX.XX.XXX
  ports:
  - name: postgres-5432-postgres
    number: 5432
    protocol: postgres
  resolution: DNS
  location: MESH_EXTERNAL
  workloadSelector:
    labels:
      version: postgres-back
apiVersion: networking.istio.io/v1beta1
kind: WorkloadEntry
metadata:
  name: postgres-we
spec:
  address: test-postgres-db.XXXX.XX.XXX
  labels:
    version: postgres-back
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: testuser-back-se
spec:
  exportTo:
  - '.'
  hosts:
  - test-postgres-db.XXXX.XX.XXX
  ports:
  - name: postgres-5432-testuser
    number: 5432
    protocol: postgres
  resolution: DNS
  location: MESH_EXTERNAL
  workloadSelector:
    labels:
      version: testuser-back
apiVersion: networking.istio.io/v1beta1
kind: WorkloadEntry
metadata:
  name: testuser-we
spec:
  address: test-postgres-db.XXXX.XX.XXX
  labels:
    version: testuser-back

Пример проекта с несколькими пользователями

Проект Kubernetes / OpenShift находится в папке

/ssm_documents/IGEG/info/samples/postgres_ssl_multi

Описание его сущностей:

/ssm_documents/IGEG/info/samples/postgres_ssl_multi/README.md,

Описание тестирования:

/ssm_documents/IGEG/info/samples/postgres_ssl_multi/index.md

Сценарий 5. Подключение к bootstrap-серверам кластера kafka через Egress#

В версии SSM 3.9.1 добавлена возможность подключения к кластеру kafka через Egress с использованием сертификатов. При этом достаточно указать только адреса bootstrap-серверов. К остальным узлам кластера envoy proxy подключится автоматически, опрашивая bootstrap-сервера.

Работа сценария тестировалась с Kafka версии 2.2, Сorax 6.272.0 (Core version: 2.7.2).

Применение сценария#

Данный сценарий взаимодействия предназначен для организации взаимодействия клиентского приложения kafka (в режиме потребителя или поставщика) с кластером kafka, часто меняющим топологию, например при регулярном масштабировании/переносе brokers на новые сетевые узлы.

Если кластер kafka имеет постоянную топологию, или изменения не требуют изменения конфигураций у большого (неизвестного) числа потребителей, то достаточно организовать взаимодействие через Egress по обычному сценарию.

Пререквизиты#
  1. Выпущены клиентские сертификаты и ключи для egressgateway.

  2. Аутентификация на стороне кластера kafka настроена по SSL 1.0 и выше. Режим SASL не поддерживается IGEG.

Настройка#

Для настройки подключения, не зависящего от изменений топологии кластера kafka, через Egress, необходимо:

  • создать объект Gateway и указать протокол порта: kafka;

  • создать объект Service, определяющий имя сервиса Gateway;

  • создать объект VirtualService с правилами маршрутизации трафика на сервис Gateway и после — в целевой кластер kafka;

  • создать объект ServiceEntry с протоколом портов: kafka и адресами bootstrap-серверов кластера kafka;

  • создать объект DestinationRule с правилами шифрования соединения от sidecar клиентского приложения до сервиса Gateway;

  • создать объект DestinationRule с правилами шифрования соединения от сервиса Gateway до целевого кластера kafka.

Пример Gateway

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: egress-gw
spec:
  selector:
    app: egress
  servers:
  - hosts:
    - egress-kafka.kafka-test.svc.cluster.local
    port:
      name: kafka-19093
      number: 19093
      protocol: kafka
    tls:
      mode: ISTIO_MUTUAL

Пример ServiceEntry

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: kafka-cluster-se
spec:
  hosts:
  - bootstrap1.sy.dev
  ports:
  - number: 9092
    name: kafka-9092
    protocol: kafka
  endpoints:
  - address: bootstrap1.sy.dev
    ports:
      kafka-9092: 9092
  - address: bootstrap2.sy.dev
    ports:
      kafka-9092: 9092
  location: MESH_EXTERNAL
  resolution: DNS

Пример DestinationRule для настройки шифрования к кластеру kafka

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: dr-kafka
spec:
  exportTo:
  - '.'
  host: bootstrap1.sy.dev
  trafficPolicy:
    tls:
      mode: MUTUAL
      clientCertificate: /kafka-tls/tls.crt
      privateKey: /kafka-tls/tls.key
      caCertificates: /kafka-root/kafka-root.crt
  workloadSelector:
    matchLabels:
      app: egress

Пример DestinationRule для настройки шифрования от сайдкара клиентского приложения до сервиса Gateway

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: dr-egress-svc
spec:
  exportTo:
  - '.'
  host: egress-kafka.kafka-test.svc.cluster.local
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
      sni: egress-kafka.kafka-test.svc.cluster.local

Пример настроенного проекта находится в папке /IGEG/info/samples/kafka_test.

Состав проекта:

  • приложение fluent-producer с sidecar istio-proxy, посылающее сообщения в кластер kafka;

  • приложение fluent-consumer с sidecar istio-proxy, получающее сообщения из кластера kafka;

  • приложение Egress, устанавливающее защищенное подключение к кластеру kafka;

  • configmaps для настройки приложений fluent-producer и fluent-consumer;

  • DestinationRule для шифрования соединения между sidecars клиентских приложений и Egress;

  • DestinationRule для шифрования соединения между Egress и кластером kafka;

  • Gateway, определяющий сервис Egress, доступный клиентским приложениям;

  • ServiceEntry с адресами bootstrap-серверов кластера kafka;

  • Service для сервиса Egress;

  • VirtualService для маршрутизации трафика.

Проверка взаимодействия#

В случае успешной настройки в логах контейнеров fluent-bit приложений producer и consumer будут постоянно появляться записи о чтении и записи сообщений в топик kafka. Также для проверки взаимодействия можно использовать приложение KafkaTool. Можно воспользоваться приложением из набора штатных утилит kafka:

kafka-topics.sh --list --bootstrap-server egress-kafka:19093

где egress-kafka - это имя Service Egress, и 19093 — порт Gateway.

Приложение должно при этом использовать настройки plaintext, защищенное соединение будет установлено с кластером kafka граничным прокси.

По завершении сессии в логе граничного прокси появится запись, указывающая на факт соединения Pod приложения 192.168.y.y с нашим граничным прокси 192.168.x.x, например:

[2023-08-13T11:39:11.099Z] "- - -" 0 - - - "-" 25524 71908 106291 - "-" "-" "-" "-" "-" - - 192.168.x.x:9093 192.168.y.y:41776
Отладка kafka-proxy#

Для включения расширенной отладки фильтра kafka-proxy, с целью анализа проблем подключения, выполните в терминале контейнера istio-proxy Pod граничного прокси команду:

curl -X POST localhost:15000/logging?kafka=trace

Также через установленную на рабочем месте администратора утилиту istioctl:

istioctl pc log <egress-pod> --level=kafka:trace

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

[debug][kafka] [C182] Kafka client send message, api key 1, version 11, correlation id 528744
[debug][kafka] [C181] Kafka client receive response, api key 3, version 9, correlation id 528743
[trace][kafka] [C177] Kafka proxy receives response api key 3, version 9, correlation id 528743
[debug][kafka] [C177] Metadata Response :
Brokers :
#0 : id 2, host x.x.x.x:9093
#1 : id 3, host y.y.y.y:9093
#2 : id 1, host z.z.z.z:9093
Topics :
	Name : quickstart-events
	Partitions :
		Index 0 error 0 leader_id 3
		Index 5 error 0 leader_id 1
		Index 8 error 0 leader_id 2

Миграция на текущую версию#

Для миграции на различные версии требуется провести установку. Процесс описан в документе Руководство по установке.

Быстрый старт#

Для получения примера конфигураций Ingress и Egress можно обратиться к администраторам контрольной панели за выгрузкой Deployments istio-ingressgateway и istio-egressgateway, которые разворачиваются с помощью IstioOperator.

Использование программного компонента#

Компонент Граничный прокси из состава продукта Platform V Synapse Service Mesh предназначен для обеспечения управляемого вызова интеграционных сервисов прикладной части в проекте Kubernetes. Также используется для контроля входа и выхода из прикладного проекта.

Часто встречающиеся проблемы и пути их устранения#

Проблема

Пути решения

Граничный прокси не может подключиться к компоненту POLM, в системном журнале видно сообщение Envoy proxy is NOT ready

Проверьте корректность подключения к контрольной панели Synapse Service Mesh.
Проверьте значения переменных окружения PROXY_CONFIG и CA_ADDR — в них должен быть указан корректный адрес сервиса istiod (из состава POLM)
Обратитесь к системным администраторам контрольной панели Synapse Service Mesh

До прикладного приложения не доходят запросы

Проверьте логи граничного прокси. Возможные варианты сообщений описаны ниже

В логе граничного прокси видно сообщение:
NR (No route configured):
В конфигурации граничного прокси отсутствует требуемый маршрут

Авторизуйтесь в прикладном проекте. Если вызов направлен на внутренний сервис, проверьте наличие сервиса с таким именем, проверьте корректность параметров хост/порт в конфигурационных файлах прикладного проекта — Gateway, DestinationRule и VirtualService. Если вызов направлен на внешний host, проверьте наличие конфигурационного файла ServiceEntry для данного сочетания host/порт

В логе граничного прокси видно сообщение:
UO (Upstream overflow with circuit breaking):
Поставщик перегружен запросами

Авторизуйтесь в прикладном проекте. Проверьте корректность конфигурации раздела connectionPoolSettings в DestinationRule

В логе граничного прокси видно сообщение:
UF (Failed to connect to upstream):
Поставщик сбросил соединение

Авторизуйтесь в прикладном проекте. Если используется автоматическая аутентификация ISTIO_MUTUAL — проверьте наличие конфликта в разделе trafficPolicy конфигурационного файла DestinationRule, относящегося к проблемному сервису, и раздела Spec/mtls конфигурационного файла peerAuthentication. В случае указания разных режимов работы в поле tls — возможны указанные ошибки

В логе граничного прокси видно сообщение:
UH (No healthy upstream):
Поставщик неработоспособен

Авторизуйтесь в прикладном проекте. Проверьте наличие вызываемого сервиса — в веб-интерфейсе Home/Networking/Services/Search_by_name найдите сервис. Проверьте наличие запущенного Pod, на который ссылается сервис — в веб-интерфейсе кликните правой кнопкой мыши на найденный сервис, выберите вкладку Pods на открывшейся странице. Убедитесь, что статус Pods на данной странице имеет значение running

В логе граничного прокси видны сообщения:
gRPC config for Cluster rejected: Error adding/updating cluster(s): Proto constraint validation failed:
Ошибка валидации конфигурации

Проверьте имена портов в объектах Service: они должны иметь формат <протокол>-<номер_порта>. Если имя порта начинается с kafka, postgres, mongo или других слов, обозначающих дополнительные протоколы, istiod попытается создать кластеры с указанными протоколами, что вызовет ошибку

Если указанные пути решения не помогли, обратитесь к системным администраторам контрольной панели Synapse Service Mesh.