Руководство по системному администрированию#

Термины и сокращения#

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

Определение

АС

Автоматизированная система

gRPC

Высокопроизводительный фреймворк, разработанный компанией Google для вызова удаленных процедур (RPC)

HTTP

HyperText Transfer Protocol, протокол передачи гипертекста

mTLS

Mutual TLS, протокол взаимной TLS-аутентификации

POST

Запрос для отправки данных на сервер

TLS

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

Deployment/Деплоймент

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

Pod

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

Istio SE

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

Platform V Synapse Service Mesh / SSM

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

Istio SE

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

Платформа

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

Сценарии администрирования#

Компонент REQV не имеет собственного пользовательского интерфейса для администрирования. Все действия по управлению компонентом производятся с использованием интерфейсов, предоставляемых Платформой Kubernetes.

Ниже приведены возможные сценарии администрирования с использованием веб-интерфейcа Kubernetes и с использованием консоли клиента Kubernetes.

Программный компонент Request Validator (далее — Валидатор) может быть настроен на три режима приема запросов:

  • Работа в режиме sidecar в Ingress Gateway Deployment (IGEG)

  • Работа в режиме sidecar в Egress Gateway Deployment (IGEG)

  • Работа в режиме отдельного сервиса Валидации

Базовое конфигурирование#

Для запуска тестового экземпляра валидатора запросов REQV используйте следующие артефакты Kubernetes:

Артефакт

Содержание

Описание

Deployment

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

Наименование экземпляра приложения, ссылка на образ контейнера приложения, запрашиваемые ресурсы, публикуемые порты, параметры liveness и readiness проб, необходимость и параметры подключения sidecar контейнеров, точки монтирования конфигурационных артефактов в файловую систему контейнера

Config Map

validator-config.yml

Файл, содержащий параметры конфигурации приложения, используется во всех режимах работы REQV

Config Map

validator-schemas.yml

Файл, содержащий схемы валидации, используется во всех режимах работы REQV

Service

Артефакт для регистрации приложения в service discovery Kubernetes

Селекторы и порты для подключения приложения Ingress Gateway/Egress Gateway/Sidecar к механизмам распределения трафика Kubernetes, используется в режимах работы валидатора Ingress/Egress

Virtual Service

Артефакт для настройки политик Istio SE

Параметры маршрутизации трафика между сервисами в Kubernetes используется в режимах работы валидатора Ingress/Egress

Gateway

Артефакт для настройки политик Istio SE

Параметры балансировки трафика между pods приложения используется в режимах работы валидатора Ingress/Egress

Service Entry

Артефакт для регистрации внешнего сервиса в Kubernetes

Содержит адрес локального сервиса для Egress Gateway Deployment используется в режимах работы валидатора Ingress/Egress

Настройка приложения выполняется в конфигурации приложения (ConfigMap) с названием, определенным в документе «Руководство по установке». В блоке schemas данной конфигурации задаются параметры валидации тела запроса (поля) для каждого URL.

Общая настройка приложения в ConfigMap

Пример настройки REQV:

Параметр

Обязательное

Значение по умолчанию

Описание

service_name

нет

request-validator

Название сервиса валидации, используется в логировании

log_level

нет

info

Уровень логирования (error, warn, debug, info)

log_path

нет

/opt/synapse/logs/general.log

Логирование в файл. Используется для отправки логов в Fluent-bit

port

нет

8787

Порт сервиса, используется в режиме "отдельного" сервиса валидации

audit

нет

-

Раздел конфигурации отправки событий в ТС Аудит

schemas

да

-

Раздел конфигурации валидации отдельных запросов

metrics

нет

-

Раздел с конфигурацией метрик

maxRequestHeadersByte

нет

4096

Параметр устанавливающий максимальный суммарный размер всех заголовков запроса

Описание полей schemas:

Свойство

Обязательное

Значение по умолчанию

Описание

Использование в Ingress Gateway

Использование в Egress Gateway

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

port

нет

8787

Используется в режиме Egress валидации (необходимо также внести порт в EnvoyFilter и SeviceEntry) и в режиме валидатора, как sidecar к АС.

да

да

да

name

да

-

Имя валидатора, используется внутри сервиса как уникальный идентификатор валидатора

да

да

да

method

да

-

Используемый HTTP метод для URL запроса

да

да

да

path

да

-

URL запроса, в формате '/foo/bar', при обращении в корневой путь используется '/'

да

да

да

schema

да

-

Путь до схемы валидации в формате '/schemas/{имя файла схемы}'

да

да

да

type

да

-

Тип схемы валидации, задается один из типов: json, xml, pass. Тип 'pass' используется для пропуска данного запроса без валидации, в данном случае поле schema необязательно.

да

да

да

headers

нет

""

Mассив из объектов Header: поля key (string), value (string), для выбора схемы исходя из пути, метода и HTTP заголовков

да

нет

да

error_code

нет

403 (Forbidden)

HTTP код возвращаемой ошибки при неудачной валидации (тип integer)

да

нет

да

error_response

нет

-

Шаблон тела ответа. Для вставки значения хедера запроса используется форма . Для вывода ошибки в теле ответа используется шаблон с зарезервированным именем ошибки "error_message".

да

нет

да

error_headers

нет

"Content-Type:application/json"

Массив заголовков, которые будут вставлены в ответ на запрос, который не прошел валидацию. В качестве значения заголовка может быть вставлено значение любого значения заголовка из запроса конструкцией '' Пример: error_headers: - key: "foo-id" value: ''

да

нет

да

response_schema

нет

-

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

нет

да

нет

Описание полей audit:

Свойство

Обязательное

Значение по умолчанию

Описание

Использование в Ingress Gateway

Использование в Egress Gateway

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

enable

нет

false

Флаг включения отправки логов в AUDT

да

да

да

url

да

''

Host endpoin сервиса AUDT

да

да

да

send_valid

нет

false

Флаг отправки успешных событий

да

да

да

metamodel.module

да

validator

Название модуля AUDT

да

да

да

metamodel.attempts

нет

-

Кол-во попыток подключения к AUDT при старте компонента

да

да

да

metamodel.delay

нет

-

Задержка при подключении

да

да

да

eventmodel

нет

""

Описание реквизитов подключения к AUDT

да

да

да

Пример конфигурации для прикладного приложения

Данный пример нужен для настройки прикладного приложения для работы с REQV.

ConfigMap: Application settings: ConfigMap: Application settings

Конфигурация для добавления схем валидации

Приведенный ниже пример показывает как добавить схему валидации в REQV. Названия файлов схем используются в путях к схемам в конфигурации валидатора.

ConfigMap: Schemas: ConfigMap: Schemas

Настройка проверок валидации#

Для валидации тела запросов необходимо выполнить запрос на Ingress Gateway/Egress Gateway по заранее определенному порту, настроенному в файле с конфигурацией EnvoyFilter. Подробнее в документе Руководство по установке.

Запрос должен содержать метод POST и тело запроса в одном из форматов: XML или JSON. Путь запроса должен совпадать с определенным путем в необходимой схеме валидации (раздел "Параметры настройки" данного раздела)

Пример запроса:

curl --location --request POST 'http://ingress.ru/ping' \
--header 'Content-Type: application/xml' \
--header 'Cookie: a5bb735cfb6f25d78d49b337936fee0e=4833785809f819b4df782e9c198f83e1' \
--data-raw '<?xml version="1.0" encoding="UTF-8"?>
<address>
    <street>Orchardroad</street>
    <street-number>15</street-number>
    <city>Uusikaupunki</city>
    <zip>1313</zip>
    <country>Farawayistan</country>
</address>'

Настройка проверки валидации всех входящих запросов#

Для включения проверки валидации всех входящих запросов на нужный порт, например, 8088 требуется EnvoyFilter для Ingress Gateway (IGEG). Необходимо заменить {INGRESS_MATCH_LABEL} на актуальный лейбл деплоймента Ingress, чтобы данный фильтр применился к нужному Ingress, а также заменить {PORT} на 8088

Обратите внимание:

  • status_on_error: задается код ошибки при недоступности валидатора.

  • max_request_bytes: максимальный размер тела запроса, поменять, если превышает.

  • если сервис валидации развернут в среде Kubernetes (использование Envoy API V3), то необходимо указать порт "50052" поля grpc_service.google_grpc.target_uri.

Пример: Ingress: EnvoyFilter

Настройка проверки валидации ответов на запросы к внешним АС#

Для включения проверки валидации ответов на запросы к внешним АС на порт 8088 требуется EnvoyFilter для Egress Gateway (IGEG). Необходимо заменить {EGRESS_MATCH_LABEL} на актуальный лейбл деплоймента Egress, чтобы данный фильтр применился к нужному Egress Gateway.

Фильтр дает возможность кастомизации заголовков запросов и ответов в секциях envoy_on_response и envoy_on_request . При запросе возможна буферизация заголовков (например, заголовки path и method в секции envoy_on_request ), возможно добавление своих заголовков и изменение заголовков в запросе.

Для изменения кода ответа, не прошедшего валидацию, заголовок ":status" меняется на необходимый для прикладного сервиса.

Внимание! При неуспешной валидации тело ответа все равно доходит до прикладного сервиса, для результата валидации необходимо ориентироваться на код ответа.

Алгоритм валидирования ответов:

  1. Прикладной сервис отправляет запрос к внешней АС.

  2. Запрос идет через прокси Egress Gateway на определенный для запроса порт.

  3. Ответ от внешней АС отправляется на sidecar Валидатора.

  4. Если валидация успешная, то ответ от внешней АС приходит к прикладному сервису.

  5. Если валидация неуспешная (получен ответ с HTTP кодом от Валидатора, отличный от "200"), то прикладному сервису приходит ответ с кодом "403".

Пример: Egress: EnvoyFilter

В случае валидации ответа через Egress Gateway, необходимо, также, добавить ServiceEntry для ссылки на sidecar валидатора из фильтр ( " outbound|8787||auth.local")

Egress: ServiceEntry: Egress: ServiceEntry

Проверка валидации запросов#

Проверка валидации запросов в режиме Ingress Gateway и Egress Gateway#

val.sch.png

val.sch.png

Для валидации тела запросов необходимо выполнить запрос на Ingress Gateway/Egress Gateway по заранее определенному порту, настроенному согласно документу Руководство по установке.

Запрос должен содержать метод POST и тело запроса в одном из форматов: XML или JSON. Путь запроса должен совпадать с определенным путем в необходимой схеме валидации.

Пример схемы валидации bar.xsd из configMap validator-schemas :

data:
  bar.xsd: |-
    <?xml version="1.0" encoding="UTF-8" ?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="address">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="street" type="xs:string"/>
                    <xs:element name="street-number" type="xs:string"/>
                    <xs:element name="city" type="xs:string"/>
                    <xs:element name="zip" type="xs:string"/>
                    <xs:element name="country" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:schema>

Пример валидного XML запроса для схемы bar.xsd:

  curl -X POST -v 'reqv-ingressgateway.namespace.svc:8080/ping' \
  --header 'Content-Type: application/xml' \
  --header 'Cookie: a5bb735cfb6f25d78d49b337936fee0e=4833785809f819b4df782e9c198f83e1' \
  --header 'BAR: 1223' \
  --header 'FOO: 23432' \
  --data-raw '<?xml version="1.0" encoding="UTF-8"?>
  <address>
      <street>Orchardroad</street>
      <street-number>15</street-number>
      <city>Uusikaupunki</city>
      <zip>1313</zip>
      <country>Farawayistan</country>
  </address>'

Пример схемы валидации foo.json из configMap validator-schemas :

data:
  foo.json: |-
    {
      "$id": "http://json-schema.org/draft/2019-09/json-schema-core.html",
      "$schema": "https://json-schema.org/draft/2019-09/schema",
      "$comment": "sample comment",
      "title": "Config dump",
      "type": "object",
      "properties": {
        "configs": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "@type": {
                "type": "string"
              },
              "last_updated": {
                "type": "string"
              },
              "bootstrap": {
                "type": "object",
                "properties": {
                  "admin": {
                    "type": "object"
                  },
                  "dynamic_resources": {
                    "type": "object"
                  },
                  "node": {
                    "type": "object"
                  },
                  "static_resources": {
                    "type": "object"
                  },
                  "stats_config": {
                    "type": "object"
                  }
                },
                "required": ["admin", "dynamic_resources", "node", "static_resources", "stats_config"]
              }
            },
            "required": ["@type", "last_updated", "bootstrap"]
          }
        }
      },
      "required": [
        "configs"
      ]
    }

Пример валидного JSON запроса для схемы foo.json:

  curl --location --request POST -v 'reqv-ingressgateway.namespace.svc:8080/' \
  --header 'method: POST' \
  --header 'path: /' \
  --header 'x-foo-first: foo1' \
  --header 'foo: BAZZZ' \
  --header 'Content-Type: application/json' \
  --data-raw '{
      "configs": [
          {
              "@type": "type.googleapis",
              "last_updated": "2020-08-29T10:45:09.046Z",
              "bootstrap": {
                  "admin": {},
                  "dynamic_resources": {},
                  "node": {},
                  "static_resources": {},
                  "stats_config": {}
              }
          }
      ]
  }'

Проверка валидации запросов в режиме sidecar#

val.sch.png

Подключение валидатора как sidecar к отдельному сервису выполняется по аналогии с подключением к Ingress Gateway и Egress Gateway: добавление контейнера с валидатором в деплоймент сервиса. Обращение к сервису валидации выполняется по localhost:8787/check (порт зависит от предустановленного значения в конфигурации валидатора).

Запрос выполняется методом POST с обязательными заголовками: path и method , по которым будет выполнена выборка необходимой схемы валидации. Также, для корректного логирования и аудита необходимо включать заголовок x-request-id.

Пример запроса curl в сервис валидации из сервиса:

curl -X POST 'localhost:8787/check' \
--header 'path: /alone' \
--header 'method: POST' \
--header 'Content-Type: application/xml' \
--header 'x-request-id: xxx123xxx' \
--header 'BAR: 1223' \
--data-raw '<?xml version="1.0" encoding="UTF-8"?>
<address>
    <street1>Orchardroad</street1>
    <street-number>15</street-number>
    <city>Uusikaupunki</city>
    <zip>1313</zip>
    <country>Farawayistan</country>
</address>' -i

Для всех режимов работы валидатора предусмотрена возможность настройки допустимых значений (white list) для заголовков запросов. Для этого необходимо добавить в configMap validator-config следующий блок:

schemas:
  - name: 'xml-test'
    validate_headers:
      - key: BAR # имя заголовка
        required: true # если true, то заголовок должен обязательно присутствовать в запросе
        white_list: # при наличии white_list блока действует правило: все, что не разрешено - запрещено
          - pattern: ^([0-9]){4}$ 
          - pattern: ^abc$ 

В примере выше есть блок white_list с ключами pattern, в которых указываются регулярные выражения. По ним будет проверяться валидность заголовка BAR. Если хотя бы одно из регулярных выражений соответствует значению заголовка, то он считается валидным.

Добавление дочерних XSD схем#

Для использования дочерних XSD схем, содержащих дополнительные неймсмпейсы необходимо добавить их отдельными файлами в ConfigMap.

Пример использования неймспейсов в XSD схемах для валидации XML:

kind: ConfigMap
apiVersion: v1
metadata:
    name: validator-schemas
    labels:
    app: validator
data:
    foo.json: |
    {
        "$id": "http://json-schema.org/draft/2019-09/json-schema-core.html",
        ...
        "required": [
        "configs"
        ]
    }
    midi.xsd: |
    <?xml version="1.0" encoding="UTF-8" ?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     ...
    </xs:schema>

В основной XSD схеме включается название неймспейса (xmlns:midi="1") и импорт схемы с включаемым неймспейсом по ее абсолютному пути (<xs:import namespace="1" schemaLocation="file:///schemas/midi.xsd"/>).

Пример использования неймспейса в схеме: <xs:element name="Card" type="midi:note" />

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:midi="1">
    <xs:import namespace="1" schemaLocation="file:///schemas/midi.xsd"/>
    <xs:element name="address">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="street" type="xs:string"/>
                <xs:element name="street-number" type="xs:string"/>
                <xs:element name="city" type="xs:string"/>
                <xs:element name="zip" type="xs:string"/>
                <xs:element name="country" type="xs:string"/>
                <xs:element name="Card" type="midi:note" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Пример содержимого дополнительной схемы:

<?xml version="1.0" encoding="utf-8"?>
<xsx:schema elementFormDefault="qualified"
           xmlns:xsx="http://www.w3.org/2001/XMLSchema"
           targetNamespace="1">

    <xsx:complexType name="note">
        <xsx:sequence>
            <xsx:element name="CardNum" type="xsx:string"/>
        </xsx:sequence>
    </xsx:complexType>
</xsx:schema>

Пример валидируемого XML, включающий проверку неймспейсов:

<?xml version="1.0" encoding="UTF-8"?>
<address>
    <street>Orchardroad</street>
    <street-number>15</street-number>
    <city>Uusikaupunki</city>
    <zip>1313</zip>
    <country>Farawayistan</country>
    <Card>
        <midi:CardNum xmlns:midi="1">EXAMPLE</midi:CardNum>
    </Card>
</address>

Настройками схем валидации#

Узнать какая схема валидации была применена к запросу можно в debug режиме. Для этого в comfigMap validator-config меняем log_level с info на debug (только в целях тестирования). После выполнения запроса в логах валидатора будет сообщение с именем схемы, которая подошла под запрос:

DEBUG применяется схема валидации: имя схемы 

Если ни одна схема не подходит под запрос, код ответа будет 403 Forbidden, в логах валидатора увидим ошибку:

ERROR ошибка получения схемы для запроса 'POST:/': подходящая схема валидации для запроса 'POST:/' не найдена

Приоритет имеет первая схема в comfigMap validator-config соответствующая параметрам запроса. Например, если требуется пропустить все запросы с методом POST идущие на любой путь, то первой указываем схему с типом pass.

  - name: pass-request
    method: POST
    path: '/*'
    type: 'pass'

После выполнения запроса в логах видим сообщение:

 DEBUG применяется схема валидации: pass-request
 DEBUG пропуск запроса 'POST:/ping' без валидации (тип pass)

Если требуется валидировать определенные запросы, а все остальные, под которые не нашлось подходящей схемы пропускать - схему с типом pass нужно указать последней. Она будет иметь самый низкий приоритет и срабатывать в последнюю очередь.

Масштабирование#

Масштабирование сервиса валидации происходит посредством увеличения количества Pod экземпляров Ingress Gateway/Egress Gateway, а также отдельных сервисов, sidecar которых сервис валидации является.

Просмотр журнала событий приложения REQV#

Для просмотра и настройки логов необходимо:

  • Зайти в проект контрольной панели;

  • В меню выбрать пункт Workload/Pods ;

  • На странице найти нужный pod;

  • Перейти по сcылке в этот pod;

  • Перейти на вкладку (Logs). В консоли не должно быть ошибок.

События системного журнала#

Компонент REQV оснащен собственным системным журналом. Системный журнал находится по пути /opt/synapse/logs/general. Системный лог выводится в консоль контейнера приложения. Уровень логирования задается настройками в ConfigMap, где изменяется установкой параметров log_level и log_path. Подробнее указано в разделе "Настройками схем валидации" и "Общая настройка приложения" в ConfigMap документа «Руководство по системному администрированию».

Предусмотрены следующие уровни логирования событий системного журнала: "info", "warn", "error"… По умолчанию установлен режим "info". В данном режиме выводятся события уровней "info", "warn" и "error". Уровень логирования debug и trace не рекомендуется включать при промышленной эксплуатации REQV.

log внутри контейнера REQV и содержит записи формата JSON с полями:

{
"projectName": "Имя проекта",
"podSource": "Имя pods",
"event_timestamp": "Время записи",
"message": "Текст сообщения",
"information": "Дополнительная информация, если требуется",
"rqUID": "Уникальный идентификатор запроса",
"serviceReceiver": "Имя вызываемого сервиса (получателя)",
"operationName": "Название операции (корневого тега)",
"status": "Статус (описание)"
}

Список параметров в событиях системного журнала:

  • METHOD - используемый HTTP метод в запросе

  • PATH - путь запроса до конечного сервиса

  • VALIDATOR - название схемы валидации в конфигурационном файле

  • ERROR - описание ошибки

Событие

Тип события

Описание

поступил запрос '[METHOD:PATH]' на валидацию

INFO

В сервис валидации пришел запрос

ошибка получения схемы для запроса '[METHOD:PATH]': ERROR

ERROR

Ошибка получения схемы в контейнере приложения исходя из параметров запроса

пропуск запроса '[METHOD:PATH]' без валидации (тип pass)

INFO

В конфигурационном файле для данного типа запроса поставлен пропуск без валидации

не найден валидатор 'VALIDATOR' для запроса '[METHOD:PATH]': ERROR

ERROR

Ошибка получения настроек валидатора из конфигурационного файла

запрос '[METHOD:PATH]: ошибка валидации: ERROR

ERROR

Ошибка функционала валидации

запрос '[METHOD:PATH] не прошел валидацию: ERROR

WARN

Запрос не прошел валидацию

запрос '[METHOD:PATH]' прошел валидацию

INFO

Запрос прошел валидацию

События мониторинга#

Компонент REQV предоставляет метрики в формате Prometheus для регистрации основных событий валидации. Путь до метрик приложения находиться: localhost:9191/metrics. Для получения метрик по умолчанию назначен порт: 9191. Если нужно сменить порт, то это можно сделать в конфигурационном файле настроек ConfigMap, сменив значение параметра metrics на нужный порт. Пример настройки приведен в разделе Общая настройка приложения в ConfigMap.

Метрика

Описание

validator_header_field_missing

Счетчик, если отсутствует обязательное поле в header запроса

validator_header_field_notvalid

Счетчик, если поле из header запроса не соответствует regex

validator_body_notvalid

Счетчик, если body запроса не прошло валидацию по схеме

validator_not_found

Счетчик, если подходящий валидатор для запроса не найден

validator_validating_error

Счетчик, если случилась ошибка при применении схемы валидации к запросу

Каждая метрика включает теги:

  • mode — показывает режим работы сервиса валидации (ingress, egress, check).

  • type — тип обращения к сервису (response, request).

  • app — название приложения.

  • namespace — название проекта приложения.

  • pod — название Pod приложения.

  • node_name — название Node, где работает приложение.

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

Проблема

Пути решения

Ошибки в схеме валидации при приеме запроса

Схемы валидации в ConfigMap должны быть в формате XSD

Не найден валидатор

Запрос приходит без необходимых заголовков, указанных в документации, либо в конфигурационном файле сервиса не указаны корректные параметры выбора схем

В режимах Ingress Gateway и Egress Gateway запрос не перенаправляется в сервис валидации

Проверить EnvoyFilter на предмет корректного порта, на который поступает запрос и лейблов экземпляра Ingress Gateway/Egress Gateway.

Отсутствие прав

Необходимо иметь доступ к следующим артефактам Kubernetes для настройки и работы с приложением: ConfigMap, доступ к консоли Pod приложения, выполнять перезагрузку Pod приложения. Если один из этих уровней отсутствует, то необходимо обратиться к администраторам инфраструктуры платформы Kubernetes