Русский
Русский
English
Статистика
Реклама

Блог компании x5 retail group

Одна Kafka хорошо, а несколько лучше

26.01.2021 20:09:19 | Автор: admin

Всем привет! Меня зовут Александр, я инженер команды, отвечающей за развитие централизованныхIT-сервисов, которыми пользуются продуктовые команды вX5RetailGroup.

В этой статье речь пойдёт обApacheKafkaи том, как этот продукт используется для обеспечения потребностей команд разработки. Статья не погружает в технические аспекты, но может быть полезна архитекторам и менеджерам, которые думают о том, чтобы попробовать использоватьKafka, но не знают, подойдёт ли она для их задач, а также разработчикам, которые могут открыть для себя новые инструменты для удобной работы с кластерами.

На момент написания статьи силами нашей команды развёрнуты и поддерживаются 14 продуктивных кластеров (1 централизованный и 13 у продуктовых команд) и 15 непродуктивных.

Централизованный кластер Kafka

Основной сценарий, в рамках которогоKafkaиспользует наша команда доставка логов вElasticsearch.

Немного цифр об этом кластере для начала:

  • брокеры - 5

  • топики 179

  • consumer группы 77

  • средний объем данных[1]в топиках 555.1 ГБ

[1] значение за последние 90 дней

Небольшое лирическое отступление. Многие сталкивались с ситуацией, когда в одно прекрасное утро ты видишь на графиках резкий рост количества логов, но не понимаешь, что именно стало причиной: новые команды не заезжали в сервис, новый функционал не планировался, и команды не предупреждали о том, что ожидается рост (потому что изначально команда закладывает вычислительные мощности под определенный объем данных). В результате расследования выясняется, что разработчики просто включили уровень логированияDebugилиTrace. Также, иногда, встречаются сложные системы, бизнес-логика которых требует сохранять максимально полную информацию, растущая, как снежный ком, с течением времени. Например,X5 использует в работе систему маркировки табачных изделий. В какой-то момент мы обнаружили, что размер одного сообщения с логами достигает порядка 600 кб, потому что вся информация о продукции и ее перемещении дополняется на всем пути до магазина.

Поэтому для нас также было важно обеспечить доступность сервиса и не позволить, чтобы поток логов перегрузил нашу систему до отказа в результате незапланированного роста количества данных.

На этапе проектирования сервиса сбора логов,командапоняла, чтонеобходимо гарантировать запись вElasticsearchвсех без исключения событий. Таким образом обеспечивается целостность данных, которые поступают от внешних систем, и команды всегда могут получить полную картину в том виде, в котором они пришли из внешних источников. Помимо этого, важно было иметь в виду, что количество команд будет расти со временем, а сервисы развиваться. Количество сообщений и информации в них будет увеличиваться, а для нас будет более затруднительно контролировать, какую информацию в логах пишут команды. Это значит, что мы должны сделать отказоустойчивую систему, которую можно сравнительно легко масштабировать в будущем.

Для достижения этих целей нам отлично подошло решениеApacheKafkaпо следующим причинам:

  • репликация и валидация записи.

    Kafkaимеет механизм валидации записи acknowledgements. С помощью параметраacks можно настроить, сколько брокеров (реплик) должны отправить наproducerподтверждение записи. Конечно, использованиеacks, особенно в случае, если мы хотим быть уверены, что данные реплицировались на все брокеры, добавляет небольшую задержку, которая требуется на репликацию. Но для нас важнее быть уверенными, что данные, которые мы хотим передавать дальше, будут записаны вKafka;

  • хранение сообщений в очереди.Если потребитель (в нашем случае этоLogstash, который забирает сообщения изKafka) по какой-то причине не успевает обрабатывать сообщения или просто недоступен, эти данные будут прочитаны и доставлены в конечную систему сразу после стабилизации работы потребителей;

  • хранение сообщений после прочтения.

    Kafkaне удаляет сообщения, а хранит в течение времени, которое описывается в параметрахretention. Это дает возможность восстановить данные в случае, если что-то случится с индексом вElasticsearchи данные станут недоступны;

  • партиционирование.

    За счет увеличения числа партиций топика можно увеличить пропускную способностьKafka, добавив дополнительных потребителей. Это увеличивает количество потоков, которые могут читать данные параллель и полезно в случае, когдаproducerгенерирует большое количество сообщений.

Изначально кластер был развернут натрехмашинах, но после роста числа команд мы масштабировали кластер, добавив ещё две ноды.

#

vCPU

RAM

Storage[2]

Kafka

Kafka Uptime

Zookeeper

ZK Uptime

1

4

16 ГБ

290 ГБ

+

1г1м

+

1г5м

2

4

16ГБ

270 ГБ

+

1г1м

+

1г5м

3

4

16ГБ

290 ГБ

+

1г1м

+

1г5м

4

4

16ГБ

270 ГБ

+

-

-

5

4

16ГБ

270 ГБ

+

1г1м

-

-

[2] учитывается объем, отведенный под данныеKafka

Мы видим, что последние 2 ноды были добавлены в кластер чуть более года назад, как раз в это время и произошел перезапуск сервиса на нодах 1-3, а на 4-й ноде перезапуск происходил позднее, скорее всего, проводились какие-то работы.

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

Управление доступами

Чтобы разграничить команды по топикам, мы используемKafkaSecurityManager (https://github.com/simplesteph/kafka-security-manager). Все правила доступа мы описываем в файле сACL. Выглядит это вот так:

User:projectprodwrite@srelogs,Topic,PREFIXED,projectprod,Create,Allow,User:projectprodread@srelogs,Topic,PREFIXED,projectprod,Read,Allow,User:projectprodread@srelogs,Group,PREFIXED,projectprod,All,Allow,

где:

UserCNсертификата, который используется для подключения,

srelogs имя кластера,

Topic/Group объект, которым управляет данная запись,

PREFIXED/LITERAL как будет применяться, относительно именем объекта вKafka(по префиксу или полное совпадение),

project_prod имя объекта и права, которые получает пользователь.

Producer/consumerавторизуются с помощьюSSLсертификатов, которые мы генерируем автоматически и храним вVault.

Интеграция в конвейер поставки логов

Подготовка всех необходимых компонентов выполняется с помощью ролейAnsible. В зависимости от окружения (продуктивное или непродуктивное), и прочих параметров, описанных в инвентаре, создается набор сущностей и конфигурируются нужные сервисы (индексы и тенанты вElasticsearch, пайплайны вLogstash)

После того, как все необходимые компоненты созданы и настроены, топики автоматически создаются, как только первые сообщения начинают отправляться вKafkaблагодаря параметруauto.create.topics.enable=True

Для обеспечения высокой производительности кластера, рекомендуется использоватьKafkaс сообщениями небольшого размера. По этой причине мы настоятельно рекомендуем командам следить за тем, чтобы в логи писалась только полезная информация, а дляElasticsearchпоставили ограничение на размер одного сообщения.

В целом, графики измеряющие поток входящих сообщений показывают нам стабильную и равномерную картину, однако, время от времени возникают неожиданные всплески (фиолетовые и желтые графики), которые создают команды разработки в топикахdevсред, предположительно, во время проведения тестов.

ИспользованиеKafkaв цепочке поставки логов позволяет нам контролировать поток входящих сообщений,Logstash(у каждой команды свой) будет равномерно вычитывать все, что попадает в топикKafka, а мы будем спокойны, что наш конвейер поставки логов не упадет от внезапно возросшей нагрузки. В случае, если нашconsumerстанет недоступен или не будет справляться с нагрузкой, все события так или иначе останутся в топике и будут прочитаны и отправлены вElasticsearchпосле восстановления работоспособностиLogstash.

Кластер для команды

Кроме большого кластера, который мы используем для гарантированной доставки логов, некоторые команды используют кластерыKafkaв своих проектах. При этом задачи, которые они решают с помощью этого продукта, схожи с нашими гарантированная запись данных, возможность обратиться к любым данным в течение времени их жизни в топике, отказоустойчивость и целостность.

У нас есть информационный ресурс, в котором описаны все сервисы, предоставляемые нашей командой, в том числе и параметры по умолчанию, которые устанавливаются для той или иной системы. Аналогичные дефолтные значения прописаны и для кластераKafka. Вот некоторые из них:

auto.create.topics.enable=Truedelete.topic.enable=Truelog.segment.bytes=1073741824log.retention.check.interval.ms=300000zookeeper.connection.timeout.ms=6000auto.leader.rebalance.enable=true

Нести в статью все, что описано в роляхAnsibleя не вижу смысла, но приведу некоторые примеры того, что используем мы вX5 .

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

- name: 01|Set Kafka replication factor  set_fact:    kafka_cfg_default_replication_factor: "{{  kafka_cfg_default_replication_factor | default(kafka_hosts|length) }}"    kafka_cfg_offsets_topic_replication_factor: "{{ kafka_cfg_offsets_topic_replication_factor | default(kafka_hosts|length) }}"    kafka_cfg_transaction_state_log_replication_factor: "{{ kafka_cfg_transaction_state_log_replication_factor | default(kafka_hosts|length) }}"  run_once: True- name: 01|Set kafka ISR  set_fact:    kafka_cfg_min_insync_replicas: "{{ kafka_cfg_min_insync_replicas | default([kafka_cfg_default_replication_factor|int - 1 , 1] | max) }}"    kafka_cfg_transaction_state_log_min_isr: "{{ kafka_cfg_transaction_state_log_min_isr | default([kafka_cfg_transaction_state_log_replication_factor|int - 1 , 1] | max) }}"  run_once: True

По умолчанию мы выставляем удаление всех событий старше 30 дней, обычно этого хватает командам:

log.retention.hours=720

В случае, если команде требуются иные значения, то изменить какие-то параметры несложно. Нужно просто описать параметры и их значения в инвентаре нужного проекта:

Project.yml---project: name. . .kafka_scala_version: "2.11"kafka_zk_chroot: '/'kafka_enable_protocol: ['PLAINTEXT']kafka_cfg_default_replication_factor: 2kafka_cfg_log_retention_hours: 6kafka_cfg_log_segment_bytes: 52428800

Как и в случае с общим кластером, для обеспечения безопасности, мы используем SSL сертификаты. По умолчанию предоставляем кластер с параметромkafkaenableprotocol: ['SSL'], что гарантирует возможность подключения к кластеру только тех, кто имеет соответствующие клиентские сертификаты.

- name: Lookup for ssl data in Vault  set_fact:    jks_b64: "{{ lookup('hashi_vault', 'secret=sre/{{ env }}/{{ project }}/kafka/{{ inventory_hostname }}:kafka.keystore.jks.b64') }}"- name: Copy keystore data from Vault  copy:    dest: "/opt/kafka/ssl/{{ inventory_hostname }}/kafka.keystore.jks"    content: "{{ jks_b64 | b64decode }}"

Для удобства управления мы заворачиваемKafkaиZookeeperв сервисы, поскольку не используем контейнеры. Пример шаблона сервисаKafka, которыйAnsibleприносит на виртуальную машину:

[Unit]Description=Kafka DaemonAfter=zookeeper.service[Service]Type=simpleUser={{ kafka_user }}Group={{ kafka_group }}LimitNOFILE={{ kafka_nofiles_limit }}Restart=on-failureEnvironmentFile=/etc/default/kafkaExecStart={{ kafka_bin_path }}/kafka-server-start.sh {{ kafka_config_path }}/server.propertiesExecStop={{ kafka_bin_path }}/kafka-server-stop.shWorkingDirectory={{ kafka_bin_path }}[Install]WantedBy=multi-user.target

Плюсытакогоразделения:

  • разграничение ресурсов.

    Каждая команда знает, сколько ресурсов выделено конкретно под их продукт, и не переживает о том, что проект-сосед может занять большой объем оперативной памяти, тем самым повлиять на производительность их системы. Помимо этого, мы можем предоставлять командам разработки дополнительные инструменты и не думать о том, что какие-то из их действий могут навредить кому-то еще кроме них самих;

  • гибкость управления.

    В случае, если необходимо изменить какие-то параметры и перезапустить Kafka, не требуется согласовывать работы с большим количеством команд.

Пример нагрузки на одном из кластеров, который использует система маркировки:

Видно, что нагрузка на систему держится примерно на одном уровне на протяжении любого периода времени (в примере это неделя).

Из минусов можно выделить то, чтоKafkaможет быть избыточна для команд, которым нужен простой брокер сообщений.

Дополнительные инструменты для работы с Kafka

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

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

jmx-exporter позволяет отслеживать состояниеJavaVirtualMachine,

kafka-exporter,zookeeper-exporter для того чтобы понимать, как себя чувствуют наши сервисы и получать поверхностную картину,

telegraf дает информацию о состоянии ноды, на которой крутитсяKafka.

Большинству команд этого хватает. Для тех, кому нужно чуть больше информативности, мы предлагаемkafka-minionexporter(https://github.com/cloudworkz/kafka-minion), который позволяет получать больше информации о том, что происходит с топиками, например, сколько групп потребителей подключены к топику и т.п.

Поскольку у команд нет прямого доступа на сервер сKafka, им нужно дать возможность просматривать содержимое и, например, быстро удалять топики, не дергая для этого каждый раз нас. Для решения этих задач мы предлагаем использоватьKafdrop (https://github.com/obsidiandynamics/kafdrop). Для оперативного предоставленияKafdrop, мы используем готовыйCIpipeline, который поднимает в окруженииOpenShiftдва пода:Kafdropиnginx. В результате мы получаемwebUIсbasicаутентификацией, настроенной средствамиnginx.

Помимо этого, точечно по запросам команд мы можем подготовить различные коннекторы, например, коннекторы для баз данных (PostgreSQLConnector,MongoDBKafkaConnector),ksqlDBилиKafkaC22CC23CC24Cдля взаимодействия с кластером черезRESTAPI.C25C

Заключение

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

Тем не менее, для команд не всегда этот инструмент подходит из-за возможной избыточности функционала и объема необходимых вычислительных ресурсов, что в свою очередь увеличивает затраты на бюджет проекта. Именно поэтому сейчас мы начинаем в пилотном режиме предоставлять командамRabbitMQ, но это уже совсем другаяистория.

Подробнее..

Что такое системы API Management

19.02.2021 18:05:42 | Автор: admin

Зачем они нужны и какие функции они выполняют.

Всем привет! Меня зовут Антон, я инженер команды, отвечающей за развитие централизованныхIT-сервисов, которыми пользуются продуктовые команды вX5RetailGroup.

В этой статье я расскажу осистемах класса API Management и в частности о APIM Gravitee (https://www.gravitee.io), том, что это за класс систем, как они используются для обеспечения потребностей команд разработки. Статья не погружает в технические аспекты, но может быть полезна архитекторам и менеджерам, которые думают о том, чтобы попробовать использоватьданный класс систем, но не знают, подойдут ли они для их задач, а также разработчикам, которые могут открыть для себя новые инструменты для удобной работы с API.

Что такое системы API Management

Определение

API Management - это процесс создания и публикации программных интерфейсов веб-приложений (API), обеспечения соблюдения их политик использования, контроля доступа, поддержки сообщества подписчиков, сбора и анализа статистики использования и отчетности о производительности.

С другой стороны, API Management - это набор инструментов и сервисов, которые позволяют разработчикам и компаниям создавать, анализировать, применять и масштабировать интерфейсы API в безопасных средах.

В данных вариантах определения понятия "API Management" мы видим, что это процессы и системы позволяющие публиковать внутренние API сервисов, прописывать им определенные политики обработки запросов и ответов, контролировать доступ и анализировать статистику использования и производительности. Также рядом могут располагаться несколько подсистем, которые организуют выполнение необязательных функций, но интересных с точки зрения других подразделений, например монетизация API.

Зачем еще один огород городить?

Необходимость этого класса систем возникла в связи с увеличением количества сервисов, которые могут предоставлять свое API как конечный продукт для других сервисов. Ничего не напоминает? Правильно - микросервисная архитектура. Для организации это возможность ускорения "цифровизации". Владельцы продукта публикуют API, документацию к ней и прочие документы типа: планов развития, лимиты и т.д. Также всем хочется контролировать качество работы API, а это уже анализ производительности, статистика использования, проведение все возможных маркетинговых исследований и простой мониторинг. Для коллег из информационной безопасности будет интересно осуществлять наблюдение за использованием API в части контроля доступа: авторизация, аутентификация, аудит, проверка по черным/белым спискам IP. Для аналитиков и тестировщиков возможно будет интересна функциональность проверки корректности запросов, проверка корректности JSON или динамическое изменение запросов, для DevOps инженеров возможность установки rate limit, чтобы не было DoS конечного сервиса, настройка кэша и возможность оптимизации сервиса под микросервисную архитектуру: Service Discovery, Load Balancing, Blue/Green или Canary deploy.

Архитектура сервиса

В архитектуру сервиса API Management обычно входят (см. рис. 1):

  1. Management Core: ядро системы, которое отвечает за формирование политик, планов, работу точками входа и выхода, настроек API Gateways и API, настройку CORS, Failover, Healthcheck, формирование запросов на отображение статистики использования API и логов.

  1. Web/Development Portal: отвечает за UI, отображение настроек, статистики использования API, healthcheck и логов, а также позволяет общаться разработчикам, администраторам и владельцам API.

  1. API Gateways: шлюзы или прокси, они отвечают за обработку запросов от клиентов сервиса согласно установленных настроек и политик, ведение логов запросов и ответов, а также запуск healthcheck по Backend API.

  1. Backend API: отвечает за обработку запросов согласно бизнес-логике конечного сервиса.

  1. Databases: в части сервиса API Management, хранят данные по настройке API, API Gateways, логи запросов клиентов и ответы backend, healthcheck, данные мониторинга практически всех компонентов API Management.

рис. 1 Архитектура сервиса API Managementрис. 1 Архитектура сервиса API Management

Плюсы и минусы систем API Management

У данных систем есть несколько преимуществ:

  • Абстракция: система упрощает сложность сервисов под ним и предоставляет клиентам единый опыт.

  • Аутентификация:система позволяет пройти аутентификацию, в том числе и через сторонние службы, например Keycloak.

  • Управление трафиком: система регулирует входящий и исходящий трафик API.

  • Мониторинг API: система может помочь в мониторинге запросов/ответов клиента.

  • Преобразования: система позволяет преобразовать запросы/ответы API.

К минусам можно отнести:

  • Увеличение Latency: шлюзу необходимо время для обработки запросов/ответов согласно настроенным политикам.

  • TCO: Совокупная стоимость владения для всей цепочки поставки ценности, естественно будет больше, чем просто установить nginx и выставить его наружу.

APIGateways

API Gateways работают как единая точка входа в ЦОД (центр обработки данных), группу распределенных служб или сервисов (см. рис. 2). Также API Gateways могут использоваться для связи между двумя продуктами/сервисами, развернутыми в одном ЦОД. API Gateways принимают вызовы от клиентов, обрабатывают их согласно политикам/правилам и направляют их в соответствующие сервисы. Чтобы API Gateways могли максимально быстро обрабатывать запросы от клиентов их делают максимально легковесными, с использованием асинхронных фреймворков. API Gateways, как правило, работают только на седьмом уровне (L7) модели OSI.

рис. 2рис. 2

ТипыAPI Gateways

С точки зрения расположения есть два места установки API Gateways:

  • Local API Gatewaysработают как шлюз для сервисов внутри организации.

  • DMZ API Gatewaysработают как шлюз для внешних потребителей и клиентов сервисов.

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

Наиболее распространенные системы

Name

Tags

APIGee

Enterprise

WSO2 API Manager

Enterprise/Open source

SAP API

Enterprise

3scale

Enterprise

IBM API Management

Enterprise

Kong

Enterprise/Open source

Mashery

Enterprise

Microsoft Azure API Management

Enterprise

Mule Soft

Enterprise

Централизованный сервис Gravitee

В X5 Retail Group в свое время выбрали для использования систему APIM Gravitee (https://www.gravitee.io). Основной сценарий использования нашими командами публикация API в локальной сети и в DMZ.

Немного цифр об этом сервисе на текущий момент:

  • 23 продуктивных команд зарегистрировано

  • 69 API Gateways для обслуживания запросов

  • 400 Гб логов за сутки

  • 350 RPS в среднем по больнице за сутки

  • 30 000 000+ запросов обрабатывается за сутки

Функциональность

Рассмотрим базовую функциональность, предоставленную системой APIM Gravitee.

  1. Identity provider: Аутентификация внешних пользователей можешь осуществляться на основе следующих систем и сервисов:

  1. MongoDB (по умолчанию для новых пользователей, которые приглашаются);

  2. In-memory (по умолчанию для пользователя admin);

  3. LDAP / Active Directory;

  4. OpenID Connect IdP (Azure AD, Google);

  1. Fetchers: стянуть настройки для новой версии API и документацию можно через:

  1. File (Swagger, OpenAPI);

  2. HTTP;

  3. GIT;

  1. Policies: политики предназначены для изменения поведения, обрабатываемых шлюзом запросов и ответов. Каждый запрос и ответ обрабатывается согласно настроенной цепочке политик. Политики можно рассматривать как прокси-контроллер, гарантирующий выполнение данного бизнес-правила во время обработки. Примеры политик:

  1. API Key - политика авторизации с использованием API-ключа;

  2. Rate-limiting - политика ограничения скорости или квот для предотвращения флудинга backend;

  3. Transform Headers/Transform Query Parameters - политика преобразований параметров заголовка или запроса;

  4. etc.

Политик обработки запросов в Gravitee Gateway более 30 штук и с каждой версией их число увеличивается. Так же можно сделать свои политики. Но стоит учитывать, что чем больше политик "навешано", тем медленнее будет обрабатываться запрос и тем больше ресурсов будет использовано.

  1. Reporters: сборщики логов используются экземпляром шлюза для сообщения о событиях. Типы сборщиков логов:

  1. Reporter file;

  2. Elasticsearch;

  3. Accesslog;

Типы событий, которые можно собрать:

  1. Метрики запроса/ответа например, время ответа, длина содержимого, api-ключ;

  2. Мониторинг метрик например, процессора, использования кучи, кол-во открытых файлов и т.д.;

  3. Показатели проверки работоспособности например, состояние, код ответа;

  1. Repositories: репозиторий - это подключаемый компонент хранилища для настройки API, конфигураций политик, аналитики, аудита и так далее. Можно использовать следующие репозитории:

  1. MongoDB (по умолчанию);

  2. Redis;

  3. Elasticsearch;

  4. PostgreSQL (коннектор через JDBC и надо использовать другой дистрибутив);

  1. Resources: ресурсы, которые можно использовать при работе:

  1. OAuth2 (подключение к OAuth2 как источнику данных для аутентификации);

  2. Cache (создание локального кэша на шлюзе);

  3. LDAP (подключение к LDAP как источнику данных для аутентификации);

  1. Services: сервисы, которые может предоставлять сам шлюз:

  1. Sync (Синхронизация состояния шлюза с конфигурацией из репозитория управления);

  2. local-registry (Локальный реестр используется для загрузки API в формате json из файловой системы. Таким образом, вам не нужно настраивать свой API с помощью веб-консоли или rest API (но вам нужно знать и понимать формат json API, чтобы он работал.));

  3. health-check (Сервис для проверки состояния других сервисов);

  4. monitor (Сервис извлекает метрики, такие как метрики os / process / jvm, и отправляет их в базовую службу отчетов);

  1. Notifiers: сервис нотификаций используется для отправки уведомлений. В настоящее время единственным доступным каналом является электронная почта, но в ближайшее время запланированы другие, включая Slack.

  1. Email;

  1. Alerts: оповещение используется для отправки триггеров или событий в механизм оповещений, которые могут быть обработаны для отправки уведомления с помощью настроенного плагина Notifier.

  1. Vertx;

А так как система с открытыми исходниками:https://github.com/gravitee-io, то при знании Java, можно написать свои собственные плагины и использовать как вздумается.

Настройки API

Настройка нового API проходит несколько этапов:

  1. Создание API

  1. Настройка планов

  1. Привязываем API к шлюзам

Создание API

На странице создания API можно выбрать, как и из чего создать скелет нового API

Вариантов немного, но выбор есть:

  1. Вручную накликал и можно работать!

  1. Импортировать из swagger файла.

  1. Импортировать из Gitа/URLа.

Рассмотрим ручной вариант настройки, выбираем "->"

Ручное создание API проходит 5 шагов

На первом шаге указываем имя API, версию, описание и уникальный путь, по которому это API будет доступно.

Второй шаг может быть в двух модификациях:

В Simple mode указываем только адрес нашего backend api, например:https://msk-dpro-sre000.x5.ru:8443/testbackend/

В Advanced mode необходимо указатьадрес нашего backend api, используемые tenant и sharding tags.

tenant- область выделенная в Elasticsearch для логов запросов и событий.

sharding tags- теги, согласно которым связываются API и Gateways

На третьем шаге можно указать Plan

Plan - это указание ограничений, которые будут влиять на обработку запросов, проходящих через данный Gateway.

Name -имяплана

Security type -типплана: Keyless(public), API Key, JWT, OAuth2

Description - просто описание плана и его особенностей

Rate limit - ограничение кол-ва запросов в секунду/минуту

Quota -ограничение кол-ва запросов в час/день/неделя/месяц

Path authorization - черный и белый список путей и методов к ним

Данный пункт можно пропустить и заполнить уже в созданном API.

На четвертом шаге можно загрузить файл документации по API

Поддерживается формат swagger.json

Данный пункт можно пропустить и заполнить уже в созданном API.

На пятом шаге мы проверяем все что заполнили

И выбираем либо "Создать API без установки на шлюз", либо "Создать и запустить API"

Нажимаем CREATE и получаем частично настроенный API для работы.

Настройки планов

План предоставляет собой уровень обслуживания и доступа между API и приложениями. У одного API может быть несколько планов, но только один без ключевой - "keyless". План определяет ограничения доступа, режимы проверки подписи и другие настройки для адаптации к конкретному приложению.

Основные настройки:

  1. Планы привязываются к конкретному шлюзу или группе шлюзов через Tags (см. рис. 3)

Рис. 3Рис. 3

2. В плане указывается какой тип Аутентификации будет использован (см. рис. 4)

Рис. 4Рис. 4

3. Можно сразу указать Rate и Quota лимиты и определить список разрешенных путей для запроса (см. рис. 5)

Рис. 5Рис. 5

4. В последней вкладке можно указать политики, которые будут отрабатывать на начальном этапе обработки запросов (см. рис. 6)

Рис. 6Рис. 6

Заключение

Итак, теперь вы знаете, что такое системы Management API, зачем они нужны и какой функциональностью обладают. Надеюсь, у вас сложилось понимание, какое место в архитектуре ИТ занимает данный класс систем и как их использовать с наибольшей отдачей.В следующей частия буду рассказывать и показывать, как поставить и настроить одну из систем класса Management API с нуля для тестового прогона.

Подробнее..

Как MCS и Х5 построили частное облако в энтерпрайзе, чтобы быстро получать готовые сервисы

07.06.2021 12:06:42 | Автор: admin


Castle in the sky by PiotrDura


Публичное и частное облако одного провайдера два разных продукта или одна и та же платформа, просто развернутая на разном оборудовании? На примере решения для Х5 Retail Group я, Илья Болучевский, технический директор Mail.ru Private Cloud, расскажу, в чем отличия и как построен процесс внедрения облака вендора в корпоративную инфраструктуру.


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


Кажется, что все просто: модульный подход, сборка из готовых компонентов, внедрение с экспертами. На самом деле частное облако никогда нельзя поставить из коробки: требуется кастомизация под корпоративные требования и интеграция с внутренними системами. Это долгий и сложный путь, который команде клиента приходится проходить вместе с нами.


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

Ниже о том, как двум опытным командам MCS и Х5 удалось построить гибкую облачную платформу во внутреннем контуре заказчика в предельно сжатые сроки, какие сложности и подводные камни ожидали нас на этом пути и как данное решение помогает компании достичь поставленных целей.



Почему Х5 пошли в частное облако и каких результатов достигли


Компания столкнулась с необходимостью обеспечить быстрое выделение ресурсов под внутренние проекты, а также запустить новые процессы: микросервисную разработку в новом формате, CI/CD-пайплайны на базе облака и Managed-сервисов, автоматизацию на уровне IaC.


Также на старой инфраструктуре больше времени занимало регулирование объема ресурсов под задачи, плавное наращивание мощности по мере развития проектов, управление стоимостью инфраструктуры. При запуске внутреннего проекта на старте зачастую приходилось перезакладываться по оборудованию для будущего роста, что экономически не всегда обоснованно. Также было необходимо более оперативно разворачивать тестовые среды под задачу, а потом схлопывать, сокращая потребление ресурсов. Все это сказывалось на сроке выпуска IT-продуктов компании на рынок.


Для решения этих проблем нам нужно было в сжатые сроки развернуть гибкую управляемую инфраструктуру вместе с командой Х5 Retail Group, организовать внедрение, а потом частично взять на себя эксплуатацию продукта, кастомизации, возникающие в процессе, и интеграцию новых сервисов под требования клиента.


Результаты. После внедрения облака значительно улучшились KPI: раньше ресурсы виртуализации выдавались внутренним заказчикам в течение нескольких дней, теперь за минуты. Командам компании стало удобнее запускать пилоты, среды разработки, пересоздавать их.


Также компания интегрировала с платформой собственную разработку, которая автоматизирует доступ к ресурсам для внутренних клиентов. Благодаря ей внутренние клиенты разработчики, тестировщики, проектные менеджеры получили больше прав для самостоятельной работы с сервисами. Раньше с задачами они шли в службу поддержки и заводили там заявку, которая двигалась по очереди между несколькими командами. Сейчас все работает как Self-Service: автоматически, без ручного труда. Внутренние заказчики могут выбирать сервисы, смотреть демо, рассчитывать стоимость инфраструктуры под проект, что значительно ускорило процесс согласования.


Кроме того, выгоднее стала платформа контейнеризации за счет особенностей лицензирования решения: компания внедрила Kubernetes как сервис, который построен на Open-Source-технологии. Он дает возможность внутренним заказчикам получать полноценные кластеры с возможностью автомасштабирования, что помогает гибко управлять ресурсами. Также для ряда задач в качестве платформы контейнеризации продолжают использовать OpenShift и ванильный Kubernetes.


Наше частное облако стало основой для дальнейшей автоматизации: действия на платформе можно совершать не только через UI, но и через API, что позволяет сделать слой инфраструктуры абсолютно прозрачным и работать через любые приложения.


В итоге внедрение частного облака позволило нашему клиенту ускорить Time-to-Market IT-продуктов компании. Однако достичь этого было непросто: ниже разберу, какие проблемы возникают в процессе и как мы их решаем.


Почему так сложно развернуть частное облако


Создание частного облака в существующем IT-ландшафте это как стыковка Союз Аполлон: нужно соединить две совершенно разные системы сложившуюся корпоративную и внешнюю, которую приносит провайдер частного облака. Даже имея готовые компоненты, нельзя взять публичное облако и развернуть такое же во внутреннем контуре компании, ничего не меняя. У каждой компании свои требования, требуются сложные кастомизации, интеграции и доработки.


Например, у нас в Mail.ru Cloud Solutions есть готовый Kubernetes aaS. Для Х5 Retail Group мы полностью переписали его под другую топологию сети не потому, что он чем-то плох, а потому, что корпоративное частное облако иначе работает. Фактически публичное облако приходится каждый раз частично пересоздавать под каждого клиента.


По мере наработки клиентской базы мы стали лучше работать с запросами клиентов. Большинству нужны одни и те же доработки: интеграция с ADFS, кастомизация образов, в том числе для баз данных, свои ролевые модели, SSO-интеграции. Есть уникальные требования вроде RBAC-модели по сетевым портам.


Сейчас мы понимаем, какие запросы повторяются, и добавляем в платформу новые опции. Но не все запросы имеет смысл автоматизировать то, что будет узкоспециализированным для существующих ITSM-процессов клиента, остается в обычном режиме. Такие ручные кастомизации усложняют процесс внедрения. Бывают и доработки публичного облака на основе работы с клиентом приватного так, RBAC пришел из приватного облака в наше публичное.


Другая сложность взаимодействие команд. Нужно сработать вместе: наша команда обладает компетенцией в своем продукте, Х5 компетенцией в своих системах. Нужно объединить компетенции, договариваться, чтобы достичь результата. В Х5 Retail Group работает квалифицированная команда, которая на равных участвовала в процессе интеграции и выстроила процессы работы изнутри.


На уровне взаимодействия команд могут быть подводные камни. Например, виртуализацию и облачные платформы не стоит путать, но такая путаница встречается в компаниях, которые внедряют частное облако. Любая облачная платформа отличается тем, что есть Self-Service, пулинг ресурсов. Некоторые инженеры пытаются работать с ней как с классической системой виртуализации, а далеко не все принятые в таком случае подходы применимы к облаку.


Также мы используем сильно кастомизированную платформу OpenStack, а большой энтерпрайз часто привык к VMware и похожим решениям, то есть сотрудникам надо быть готовыми администрировать новый тип платформы. OpenStack администрируется через пользовательский интерфейс иначе, чем VMware: много командной строки, конфигурационных файлов и параметров. Иногда это встречает сопротивление у компаний, которые годами использовали другие технологии. Для решения этой проблемы у нас есть обучающий курс, а также наши сотрудники постоянно в контакте с менеджерской командой клиента.


В случае с Х5 не было сложностей с взаимодействием команд, но нам пришлось реализовать много технических доработок, чтобы получить инфраструктуру в соответствии с требованиями клиента.


Какую инфраструктуру мы построили для Х5


В Х5 Retail Group сейчас развернута облачная инфраструктура с единой консолью администрирования, маркетплейсом приложений и порталом самообслуживания для внутренних заказчиков. Им доступны платформенные сервисы, в которых у компании была потребность в момент внедрения, аналогичные таким же из нашего публичного облака. Компания получила наш Kubernetes как сервис и облачные базы данных, которые прошлые платформы не предоставляли: ранее их запускали в IaaS руками, на внутренней системе виртуализации.


В состав платформы входят следующие наши сервисы:


  • инфраструктурные сервисы (IaaS) виртуальные машины в различных конфигурациях, диски, балансировщики нагрузки, настройки Firewall;
  • PaaS кластеры Kubernetes как базовая платформа контейнеризации, набор баз данных PostgreSQL, Redis, MongoDB, MySQL, чтобы внутренние заказчики могли выбрать СУБД под потребности проекта/продукта. Все сервисы адаптированы под требования информационной безопасности компании;
  • отказоустойчивые хранилища на базе CEPH с тройной репликацией данных и интеграцией с СХД клиента;
  • маркетплейс, который в X5 используют для размещения нужных внутренним заказчикам приложений.

В нашем публичном облаке реализован биллинг потребляемых ресурсов/сервисов по модели pay-as-you-go на базе платформы in-memory вычислений Tarantool. Для Х5 в него внесены изменения: в частном облаке это не биллинг оплаты провайдера, а система внутренней отчетности и планирования ресурсов. Она нужна, чтобы мониторить мощности, которые использует каждый проект, контролировать соблюдение лимитов по квотам ресурсов, формировать финансовую отчетность для точной оценки расходов по каждому проекту. Это в том числе требуется и для финансового планирования на старте проекта: использование внутренней инфраструктуры не бесплатно, подсчет расходов на нее позволяет точнее оценить ROI проекта. В такой форме решение может быть адаптировано и для других клиентов MCS.


Также у нас есть отдельный инструмент маркетплейс, это витрина с SaaS-приложениями, которые можно использовать внутри платформы. Х5 применяют его как витрину приложений для внутренних клиентов: там размещены приложения для разработки и DevOps.


Мы провели обучение для команды компании, как паковать приложения с помощью Git. Теперь специалисты Х5 Retail Group сами его наполняют приложениями, которые нужны внутренним заказчикам. По сути, идут в SaaS-историю, используя платформу как оркестратор и витрину, ориентируясь на востребованность сервисов, добавляя то, что будет использовано продуктовыми командами.


С платформой интегрирована внутренняя разработка X5, созданная инженерами компании и позволяющая автоматизировать доступ к ресурсам для внутренних клиентов. Благодаря ей и возможностям облака разработчики, тестировщики, проектные менеджеры получили больше прав для самостоятельной работы с сервисами. Раньше с задачами они шли в службу поддержки и заводили там заявку, которая двигалась по очереди между несколькими командами. Сейчас все работает как Self-Service: автоматически, без ручного труда. Где-то процессы доступа были упразднены, а где-то согласование осталось, но было автоматизировано. Внутренние заказчики могут выбирать сервисы, смотреть демо, рассчитывать стоимость инфраструктуры под проект, что значительно ускорило процесс согласования.


Чтобы получить готовое к работе частное облако, нужно пройти как минимум 10 шагов.


Какие этапы надо пройти, чтобы внедрить частное облако


Работа над проектом Х5 Retail Group до приема в эксплуатацию заняла у нас около трех месяцев: два месяца на установку и месяц на основные кастомные интеграции. На этом работа еще не закончена, мы делаем дальнейшие кастомизации. Но остальные доработки это уже работа на эксплуатируемой инфраструктуре.


Вот из каких этапов состоит процесс внедрения частного облака:


  1. Определяем бизнес-задачи первый шаг с нашей стороны: понять, что нужно бизнесу от облака, от этого зависят дальнейшие действия.
  2. Определяем ограничения они могут быть по технологиям, которые компания может использовать или нет, по информационной безопасности и по бюджету.
  3. Разрабатываем общую архитектуру решения из каких компонентов будет состоять, какие сервисы будут использованы.
  4. Выясняем специфику реализации сервисов сетевая архитектура, потребность в информационной безопасности.
  5. Прорабатываем интеграции по архитектуре интеграция состоит из двух частей: на стороне облака и на стороне целевой корпоративной системы. Здесь большая часть связана с ролевыми моделями и правами пользователей.
  6. Составляем финансовую модель биллинг, что и как считается, как это учитывать при планировании проектов.
  7. Устанавливаем и настраиваем оборудование подготовка инфраструктуры для облака. В отличие от многих провайдеров мы можем развернуть облако на оборудовании клиента, если оно подходит по параметрам. Это позволяет переиспользовать оборудование, которое освобождается после ухода от традиционной инфраструктуры.
  8. Реализуем кастомные доработки и разворачиваем решение тут, как правило, проявляется все, что не учли на предыдущих этапах, вплоть до возврата назад и переработки архитектуры решения.
  9. Проходим приемо-сдаточные испытания (ПСИ) решения и вводим его в эксплуатацию.
  10. Дорабатываем в процессе использования.

Далее расскажу про некоторые этапы подробнее. Начнем с того, как мы вместе с Х5 готовили инфраструктуру к внедрению нашей облачной платформы.


Как мы с Х5 готовились к внедрению частного облака


На этапе пресейла мы либо получаем от клиента готовое ТЗ, либо выясняем, какие у него потребности, чтобы формализовать их в рамках ТЗ. Уточняется, какая инфраструктура в наличии, какое подходящее оборудование уже есть от старой инфраструктуры, что нужно дозакупить или поставить. Вместе с клиентом рисуем Best Practice-инфраструктуру. После чего все требования формализуются в рамках ТЗ, из которого выписывается ЧТЗ частное техническое задание, то есть как будет выглядеть реализация по ТЗ.


Когда мы все согласовали и подписали контракт, начинается этап предподготовки инфраструктуры, которым занимаемся мы или клиент по нашим требованиям. В последнем случае мы тесно взаимодействуем с командой компании, как это было на проекте Х5.


Инженеры Х5 Retail Group готовили оборудование, проводили необходимую коммутацию, настраивали сеть, создавали структуры в AD, DNS, предустанавливали операционные системы под гипервизоры, выдавали деплой-ноды, создавали необходимые технические учетные записи, согласовывали доступы, настраивали интеграцию с системами ИБ, проводили кастомизацию портала самообслуживания платформы.


Команда инженеров Х5 очень оперативно сработала и создала окружение, в котором могло работать наше решение. Примерно за две недели они подготовили инфраструктуру для начала деплоя.


Теперь мы могли приступить к развертыванию нашей платформы.


Как происходило развертывание приватного облака


После того как команда Х5 подготовила инфраструктуру, в дело вступили наши инженеры.


Процесс развертывания выглядит так:


  1. Сначала мы создаем деплой-ноду это нода, с которой устанавливается все остальное облако и распределяются роли по всем остальным серверам и серверам хранения.
  2. Затем начинается деплой IaaS-части, которая позволяет запускать виртуальные машины: она включает менеджмент, гипервизоры, подсистемы хранения.
  3. Поверх нее разворачиваем PaaS: Kubernetes, базы данных, большие данные в зависимости от требования клиента по ТЗ какие-то сервисы могут быть не нужны. В Х5 мы разворачивали Kubernetes aaS и облачные СУБД.

Сейчас у нас идет речь о модульном подходе: все компоненты готовы, отработаны на публичном облаке и мы можем их передать клиенту. Такая работа по деплою IaaS и PaaS заняла у нас 45 недель.


При этом, как правило, мы не можем развернуть наши готовые сервисы в том виде, в котором они используются в публичном облаке. Их нужно доработать под потребности клиента, а это непростая задача.


Как мы дорабатываем PaaS под требования клиента


К процессу развертывания PaaS в Х5 были требования, связанные с информационной безопасностью. Также нужно было, чтобы разворачиваемый образ сразу попадал в мониторинг.


Например, у нас есть готовый запакованный сервис баз данных, который мы можем просто поставить, но внутренняя служба DB, отвечающая за эксплуатацию баз данных, просит соблюдать корпоративные стандарты. База данных должна автоматически регистрироваться в Zabbix, должен быть организован доступ для инженеров компании, на нее нужно поставить специальные версии и использовать внутренние репозитории. В этом случае наша команда PaaS полностью пересобирает исходные образы согласно требованиям это нетривиальная работа.


Другой яркий пример: PaaS при скачивании репозиториев используют наши сервисные сети, которые связаны с интернетом. В большинстве приватных облаков интернета нет, поэтому приходится переделывать сервисы так, чтобы они обращались к внутренним репозиториям. При этом надо поддерживать и обеспечивать внутренний репозиторий актуальными версиями.


К Kubernetes как сервису могут быть разные требования со стороны клиентов. Например, заранее прописанный Docker Registry или устаревшая версия Kubernetes: в публичном облаке самая младшая версия 16, можно взять 14, если компания ее использует. Для Х5 мы серьезно переделали KaaS, что было связано с особенностями топологии сети частного облака.


Такие требования к кастомизации PaaS возникают почти всегда. Когда клиент берет сервис в приватное облако, он может попросить добавить любые опции в соответствии с корпоративными требованиями.


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


Какие кастомные интеграции облачной платформы необходимы для On-premises


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


Я уже говорил, что требования корпоративных клиентов редко совпадают с коробочным решением. На этом этапе мы проводим интеграции с существующими ITSM-процессами и технологиями компании: попадание виртуальных машин в DNS, интеграция с AD, кастомная пересборка образов для авторизации через их AD, кастомная сборка образов под базы данных, интеграция с CMDB, S3-хранилищем, настройка резервного копирования на наш менеджмент.


Такие интеграции отличаются у разных клиентов это кастомная работа, автоматизировать ее в большинстве случаев нельзя. В случае Х5 Retail Group также были существующие системы типа AD, CMDB, DNS и так далее, со всем этим пришлось интегрироваться.


Также был запрос по работе биллинга: публичное облако заточено под мультитенантную модель, а приватные облака сделаны так, что один отдел отвечает за утилизацию облака; нужны были специальные типовые отчеты сразу по всем тенантам, то есть проектам. Из-за этого пришлось дописывать кусок биллинга, который бы учитывал требования. То же самое связано с некоторыми лицензиями сторонних вендоров: наш биллинг заточен на одни лицензии, в Х5 используют свои виды лицензий, пришлось эту логику также переделать.


Интеграцию команда Х5 делала по принципу вызовов через API: на нашей платформе для интеграции делается вызов по определенному формату, дальше обработку вызова и реализацию специалисты компании реализуют самостоятельно, что позволяет им использовать нужные сервисы более гибко.


Эти кастомные доработки стандартные и не слишком сложные, однако на любом проекте возникают настоящие вызовы. В Х5 Retail Group таким вызовом для нас стала переделка всей сетевой топологии, частично затронувшая PaaS.


Самое сложное: переделка сетевой топологии


Для Х5 Retail Group нам пришлось переделывать всю сетевую топологию приватного облака на лету это катастрофически сложная кастомизация. В компании сеть сделана по энтерпрайз-формату, архитектура такой сети не вполне совместима с инсталляцией публичного облака.


В публичном облаке используется топология сети, позволяющая применять internal-сети внутри проектов и публикации в интернете через external-сеть, используя для этого floating IP (белые адреса).


В приватном облаке сеть выглядит иначе: она плоская, поделена на сегменты, которых нет в публичном облаке, архитектурно реализована по-другому. Любая виртуальная машина сразу попадает во Vlan, нет никаких floating IP и серых адресов, есть только блок плоских адресов.


Из-за этой топологии нам пришлось переделывать половину сервисов и половину фронта. Исчезло такое понятие, как виртуальный роутер, пришлось переделывать логику работы балансировщика как сервиса, исключать некоторые сервисы типа VPN и так далее. То есть такая простая вещь, как переделка топологии сети, повлекла за собой переделку почти половины сервисов внутри облака.


В приватном облаке, так как там нет выхода в интернет, мы указываем другие эндпоинты и репозитории, которые всю нужную информацию для запуска PaaS-сервисов содержат внутри локальной сети клиента. Мы это поддерживаем, храня всю информацию внутри частного облака, она не уходит за его периметр.


С сетевой топологией была связана и самая большая переделка нашего Kubernetes aaS. По дефолту мы создавали его во внутренних сетях с балансировкой через наш балансировщик в публичном облаке MCS, имеющий выход во внешнюю сеть. Пришлось переделать всю логику работы, потому что Kubernetes надо было создавать в плоской сети и завязывать работу балансировщика, находящегося в частной сети.


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


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


Как мы выполнили требования информационной безопасности клиента


Приватное облако в Х5 отчасти выбрали из-за внутренних правил ИБ. Для компании мы выполнили интеграцию с ArcSight. Это SIEM-система: управление информацией о безопасности и событиями о безопасности. Все действия, которые происходят в инфраструктуре, должны регистрироваться в ней.


Например, произошел ресайз или удаление виртуальной машины SIEM фиксирует, во сколько была удалена ВМ и каким пользователем. Такую интеграцию с ArcSight используют многие клиенты. Некоторые используют другие SIEM-системы, но у всех крупных компаний они есть.


Также мы настраивали EFK и Zabbix это базовые системы, их ставим всегда, но в этом случае накатывали не наши стандартные, а специальные шаблоны, которые требовали наши коллеги. Они покрывают более широкий охват того, что должно логироваться и мониториться.


Также сотрудники службы безопасности Х5 провели несколько раундов пентестов нашей информационной системы проверяли, как и с помощью каких обходных решений можно проникнуть в нее, какие версии ПО используются, какие порты открыты и так далее. После этого обновили все доступы по двухфакторной авторизации.


В целом после кастомизации начинается целый раунд проверок информационной безопасности, а также проверок согласно программной методике испытаний, когда проверяются все кейсы по запуску.


В проверки ПМИ входят тесты: высокая доступность (High Availability, HA), тесты отказоустойчивости, стресс-тесты выхода той или иной ноды или группы узлов, при которых все должно сохранить рабочее состояние. HA достаточно капризная, ее нам приходится долго и тонко настраивать с учетом всех кастомизаций.


Эти процессы заняли у нас много времени: месяц подготовки и проверок, потом доработки и устранение замечаний. В итоге через 2 месяца смогли предложить Х5 Retail Group решение, которое компания смогла взять в эксплуатацию, часть улучшений еще находится в процессе доработки.


Кастомные доработки сервисов и платформы первая сложность, соблюдение требований ИБ вторая, но есть еще и третья. В процессе внедрения нам еще надо преодолеть те технические ограничения, которые возникают у клиента. В случае с Х5 они были некритичными.


Технологические ограничения, которые пришлось учесть в процессе внедрения


Технологические ограничения в проекте для Х5 Retail Group были разнообразные, расскажу про пару примеров.


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


Также в инфраструктуре Х5 есть ограничения по количеству используемых сетей, так как нет приватных сетей и создание любого сервиса приводит к созданию новых сетевых портов. Сильно утилизируется сеть, периодически кончаются адреса, внутренняя команда вынуждена расширять сеть либо вычищать порты.


Такие некритичные ограничения достаточно легко преодолеваются, но требуют времени, экспертности и совместной работы команд.


Итоги


После ввода проекта в эксплуатацию Х5 Retail Group увеличили скорость вывода на рынок новых продуктов. Наша команда получила бесценный опыт внедрения частного облака в энтерпрайзной коммерческой структуре и готовые решения, которые мы можем далее использовать в инфраструктурах других клиентов.


Что еще почитать:


  1. Как реализуется отказоустойчивая веб-архитектура в платформе Mail.ru Cloud Solutions.
  2. Как выбрать облачную систему хранения данных, чтобы получить лучшую производительность и оптимизировать стоимость.
  3. Наш телеграм-канал об IT-бизнесе и цифровой трансформации.
Подробнее..

Автозаказ как сделать так, чтобы нужные продукты сами попадали на полки 17000 магазинов по всей стране

17.06.2021 18:06:38 | Автор: admin

В школе все мы решали задачки вида едет из пункта А в пункт Б. Речь преимущественно шла о скорости и времени как быстро доберётся транспортное средство? Реальность, однако, подбрасывает задачки значительно интереснее: Существует масштабная ритейл-сеть по продаже товаров, которой необходимо, чтобы огромное количество номенклатурных позиций доезжало в каждый из 17000 магазинов, расположенных на половине площади самой большой страны в мире, вовремя и в нужном количестве. Для решения такой задачи в X5 Group существует ряд реализованных решений, и одним из самых важных является процесс автозаказа товаров.

Техническую поддержку этого направления в X5 Group обеспечивает команда 2-SAP Логистики.

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

Автозаказ это комплекс процессов управления запасами и заказами

Поддержание объемов товарных запасов на установленном уровне, который обеспечивает постоянное наличие товара при оптимальных запасах в системе. Это достигается путем автоматического выполнения процессов:

Планирование заказа.

Формирование заказа.

Отправка заказа.

Экономическое обоснование поддерживаемого уровня.

Контроль за состоянием запасов.

Управление ассортиментом.

Для этого используются разные механизмы прогнозирования в зависимости от формата магазина и гибких настроек в системе.

Прогноз продаж, построенный SAP это прогноз спроса на период 42 дня, который строится на исторических данных по продажам. Период анализа продаж и модель прогноза определяется из настройки Профиля прогноза.

В периоде анализа продажи могут быть Плановые регулярные продажи и Внеплановые промо продажи.

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

Модель прогноза определенный алгоритм расчета прогноза, который устанавливается для каждого товара в магазине.

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

Около 04:30 эти данные по потребности из JDA поступают в SAP, где обрабатываются фоновым заданием с интервалом запуска каждые 15 минут, в результате чего создаются Автозаказы.

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

Большую роль этот функционал играет для персонала магазинов магазинах, так как он исключает необходимость формировать заказы вручную. За исключением отдельных случаев всё происходит в автоматическом режиме с учетом большого количества факторов и сложных расчетов. Автозаказ облегчает ежедневный труд тысяч сотрудников по всей стране от Калининграда до Новосибирска.

Через автозаказ пополняется до 80% основного ассортимента магазинов, а ручное пополнение выполняется для товаров in-out.

Схема реализации товара:

Классическое пополнение происходит примерно в таком виде: представим, что есть некий товар, допустим, это пакет молока, который поставляется напрямую от внешнего поставщика в магазин торговой сети Пятёрочка.

Так выглядит децентрализованная цепочка:

- в 00:00 стартует задание по АЗ, в период его работы по нашему товару рассчиталась потребность, сформировался автозаказ, и он бы отправлен из SAP в программу магазина GK(Пятёрочка), там у сотрудников магазина есть время отредактировать рассчитанное кол-во (в большую или меньшую сторону) до наступления времени автосогласования (например, до 11 утра, время зависит от тайминга поставщика, т.е. до какого момента он должен получить заказ, чтобы собрать и вовремя привезти заказ в магазин);

- после внесения корректировок эти изменения отправляются в SAP, и дальше происходит процесс автосогласования заказ согласовывается и автоматически отправляется поставщику по почте или его провайдеру (в зависимости от того, по какой схеме поставщик работает). Например, если поставщик работает по EDI (через электронный документооборот), то после доставки заказа в его систему, нам провайдер передает информацию о размещении заказа в своем ПО и в системе ER2 заказ переходит в статус Размещен;

- далее нам поступает буфер приемки, который мы передаем в ПО магазина. По этому буферу магазин осуществит приемку товара от поставщика. После осуществления приемки поставщику отправляется информация об этом. На этом путь закончен, сотрудникам магазина остается выставить на полки товар и продать его счастливым покупателям.

Автозаказ (Ночной профиль) фоновое задание, имеющее внутри себя несколько шагов, выполняющих определённые функции. Результатом задания является создание заказов на закупку товаров. Запускается параллельно по магазинам.

На ежедневной основе автозаказ формирует более 400 000 тысяч заказов для магазинов, как на распределительные центры, так и внешним поставщикам.

  • Продажи за период в прошлом

  • Прогноз на период в будущее (на основании продаж строится прогноз SAP)

  • Остатки на объекте получателе (остаток в SAP на момент расчёта)

  • Открытые заказы (заказы на поставку и возвраты)

Продажи приходят из магазинов каждый вечер до расчёта фонового задания Автозаказа.

Факт получения продаж запускает расчет Автозаказа. Если до 03:00 продажи не получены SAP ERP, то происходит безусловный запуск задания Автозаказа.

Автозаказ формируется строго по графику заказа/поставки согласованному с поставщиком, так категории FRESH и ULTRA FRESH, как правило, заказываются и поставляются в магазины ежедневно.

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

Для того, чтобы заказать оптимальное кол-во товара, учитывается прогноз, который строится в SAP в момент расчета Автозаказа.

Если по этому товару уже есть запас или размещенный заказ, который еще не закрыт, то система также учтёт это при определении размера финального заказа.

Автозаказ определяет цепочку и поставщика по каждому товару для каждого магазина, согласно записей книги источников поставок (смежный функционал, автоматизирован, и ведется также в SAP) и формирует заказ.

Запускается задание ежедневно в 00:00. Первыми выполняются расчеты по регионам Сибирь и Урал, далее по регионам Волга, ЮГ, Москва, Центральные регионы и Северо-запад. Последовательность выполнения крайне важна, т.к. наши магазины расположены в разных часовых поясах, и пока в Москве все сладко спят, в Сибири уже в разгаре рабочий день.

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

Для этого мы реализовали различные системы мониторинга, инструменты для анализа, а в случае необходимости и возможность отправки в магазины резервных шаблонов заказа.<o:p>

Такие ситуации практически исключены, но мы готовы к любому повороту событий, и, если вдруг в системе случился какой-то сбой и автозаказ не сформировался, мы можем запустить программу по выгрузке в магазин шаблонов заказов. Шаблон заказа это по- сути прайс-лист в рамках ассортимента магазина на определенного поставщика, но без предложенного количества. Такой шаблон позволяет магазинам сделать заказ самостоятельно на необходимое количество товара в случае форс-мажора.

Также предусмотрен инструмент для выгрузки резервных заказов, рассчитанных накануне, в случае сбоев в системе JDA по прогнозированию и пополнению магазинов больших форматов Перекрёсток и Карусель.

Подробнее..

Экстракция данных из SAP HCM в non-SAP хранилища данных

23.09.2020 16:18:12 | Автор: admin
Как известно, компания SAP предлагает полный спектр программного обеспечения, как для ведения транзакционных данных, так и для обработки этих данных в системах анализа и отчетности. В частности платформа SAP Business Warehouse (SAP BW) представляет собой инструментарий для хранения и анализа данных, обладающий широкими техническими возможностями. При всех своих объективных преимуществах система SAP BW обладает одним значительным недостатком. Это высокая стоимость хранения и обработки данных, особенно заметная при использовании облачной SAP BW on Hana.

А что если в качестве хранилища начать использовать какой-нибудь non-SAP и желательно OpenSource продукт? Мы в Х5 Retail Group остановили свой выбор на GreenPlum. Это конечно решает вопрос стоимости, но при этом сразу появляются вопросы, которые при использовании SAP BW решались практически по умолчанию.



В частности, каким образом забирать данные из систем источников, которые в большинстве своем являются решениями SAP?

HR-метрики стал первым проектом, в котором необходимо было решить эту проблему. Нашей целью было создание хранилища HR-данных и построение аналитической отчетности по направлению работы с сотрудниками. При этом основным источником данных является транзакционная система SAP HCM, в которой ведутся все кадровые, организационные и зарплатные мероприятия.

Экстракция данных


В SAP BW для SAP-систем существуют стандартные экстракторы данных. Эти экстракторы могут автоматически собирать необходимые данные, отслеживать их целостность, определять дельты изменений. Вот, например, стандартный источник данных по атрибутам сотрудника 0EMPLOYEE_ATTR:



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



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

Первой возникла идея о возможности их переиспользования. К сожалению, это оказалось неосуществимой задачей. Большая часть логики реализована на стороне SAP BW, и безболезненно отделить экстрактор на источнике от SAP BW не получилось.

Стало очевидно, что потребуется разработка собственного механизма извлечения данных из SAP систем.

Структура хранения данных в SAP HCM


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

Большинство данных в SAP HCM хранится в плоских SQL таблицах. На основании этих данных приложения SAP визуализируют пользователю оргструктуры, сотрудников и прочую HR информацию. Например, вот так в SAP HCM выглядит оргструктура:



Физически такое дерево хранится в двух таблицах в hrp1000 объекты и в hrp1001 связи между этими объектами.

Объекты Департамент 1 и Управление 1:



Связь между объектами:



Как типов объектов, так и типов связи между ними может быть огромное количество. Существуют как стандартные связи между объектами, так и кастомизированные для собственных специфичных нужд. Например, стандартная связь B012 между оргединицей и штатной должностью указывает на руководителя подразделения.

Отображение руководителя в SAP:



Хранение в таблице БД:



Данные по сотрудникам хранятся в таблицах pa*. Например, данные о кадровых мероприятиях по сотруднику хранятся в таблице pa0000



Мы приняли решение, что GreenPlum будет забирать сырые данные, т.е. просто копировать их из SAP таблиц. И уже непосредственно в GreenPlum они будут обрабатываться и преобразовываться в физические объекты (например, Отдел или Сотрудник) и метрики (например, среднесписочная численность).

Было определено порядка 70 таблиц, данные из которых необходимо передавать в GreenPlum. После чего мы приступили к проработке способа передачи этих данных.

SAP предлагает достаточно большое количество механизмов интеграции. Но самый простой способ прямой доступ к базе данных запрещен из-за лицензионных ограничений. Таким образом, все интеграционные потоки должны быть реализованы на уровне сервера приложений.
Следующей проблемой было отсутствие данных об удаленных записях в БД SAP. При удалении строки в БД, она удаляется физически. Т.е. формирование дельты изменений по времени изменения не представлялось возможным.

Конечно, в SAP HCM есть механизмы фиксация изменений данных. Например, для последующей передачи в системы получатели существуют указатели изменений(change pointer), которые фиксируют любые изменения и на основании которых формируются Idoc (объект для передачи во внешние системы).

Пример IDoc изменения инфотипа 0302 у сотрудника с табельным номером 1251445:



Или ведение логов изменений данных в таблице DBTABLOG.

Пример лога удаления записи с ключом QK53216375 из таблицы hrp1000:



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

Следующей серьезной проблемой были кластерные таблицы. Данные оценки времени и расчета зарплаты в RDBMS версии SAP HCM хранятся в виде набора логических таблиц по каждому сотруднику за каждый расчет. Эти логические таблицы в виде двоичных данных хранятся в таблице pcl2.

Кластер расчета заработной платы:



Данные из кластерных таблиц невозможно считать SQL командой, а требуется использование макрокоманд SAP HCM или специальных функциональных модулей. Соответственно, скорость считывания таких таблиц будет достаточно низка. С другой стороны, в таких кластерах хранятся данные, которые необходимы только раз в месяц итоговый расчет заработной платы и оценка времени. Так что скорость в этом случае не столь критична.

Оценивая варианты с формированием дельты изменения данных, решили так же рассмотреть вариант с полной выгрузкой. Вариант каждый день передавать гигабайты неизменных данных между системами не может выглядеть красиво. Однако он имеет и ряд преимуществ нет необходимости как реализации дельты на стороне источника, так и реализация встраивания этой дельты на стороне приемника. Соответственно, уменьшается стоимость и сроки реализации, и повышается надежность интеграции. При этом было определено, что практически все изменения в SAP HR происходят в горизонте трех месяцев до текущей даты. Таким образом, было принято решение остановиться на ежедневной полной выгрузке данных из SAP HR за N месяцев до текущей даты и на ежемесячной полной выгрузке. Параметр N зависит от конкретной таблицы
и колеблется от 1 до 15.

Для экстракции данных была предложена следующая схема:



Внешняя система формирует запрос и отправляет его в SAP HCM, там этот запрос проверяется на полноту данных и полномочия на доступ к таблицам. В случае успешной проверки, в SAP HCM отрабатывает программа, собирающая необходимые данные и передающая их в интеграционное решение Fuse. Fuse определяет необходимый топик в Kafka и передает данные туда. Далее данные из Kafka передаются в Stage Area GP.

Нас в данной цепочке интересует вопрос извлечения данных из SAP HCM. Остановимся на нем подробнее.

Схема взаимодействия SAP HCM-FUSE.



Внешняя система определяет время последнего успешного запроса в SAP.
Процесс может быть запущен по таймеру или иному событию, в том числе может быть установлен таймаут ожидания ответа с данными от SAP и инициация повторного запроса. После чего формирует запрос дельты и отправляет его в SAP.

Данные запроса передаются в body в формате json.
Метод http: POST.
Пример запроса:



Сервис SAP выполняет контроль запроса на полноту, соответствие текущей структуре SAP, наличие разрешения доступа к запрошенной таблице.

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

Внешняя система в случае ошибки регистрирует ее в журнале. В случае успешного ответа передает id сессии и имя таблицы по которой был сделан запрос.

Внешняя система регистрирует текущую сессию как открытую. Если есть другие сессии по данной таблице, они закрываются с регистрацией предупреждения в журнале.

Фоновое задание SAP формирует курсор по заданным параметрам и пакет данных заданного размера. Размер пакета максимальное количество записей, которые процесс читает из БД. По умолчанию принимается равным 2000. Если в выборке БД больше записей, чем используемый размер пакета после передачи первого пакета формируется следующий блок с соответствующим offset и инкрементированным номером пакета. Номера инкрементируются на 1 и отправляются строго последовательно.

Далее SAP передает пакет на вход web-сервису внешней системы. А она система выполняет контроли входящего пакета. В системе должна быть зарегистрирована сессия с полученным id и она должна находиться в открытом статусе. Если номер пакета > 1 в системе должно быть зарегистрировано успешное получение предыдущего пакета (package_id-1).

В случае успешного контроля внешняя система парсит и сохраняет данные таблицы.

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

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

Так же и в обратном случае, когда внешняя система возвращает ошибку, она логируется и прекращается передача пакетов.

Для запроса данных на стороне SAP HСM был реализован интеграционный сервис. Сервис реализован на фреймворке ICF (SAP Internet Communication Framework help.sap.com/viewer/6da7259a6c4b1014b7d5e759cc76fd22/7.01.22/en-US/488d6e0ea6ed72d5e10000000a42189c.html). Он позволяет производить запрос данных из системы SAP HCM по определенным таблицам. При формировании запроса данных есть возможность задавать перечень конкретных полей и параметры фильтрации с целью получения необходимых данных. При этом реализация сервиса не предполагает какой-либо бизнес-логики. Алгоритмы расчёта дельты, параметров запроса, контроля целостности, и пр. также реализуются на стороне внешней системы.

Данный механизм позволяет собирать и передавать все необходимые данные за несколько часов. Такая скорость находится на грани приемлемой, поэтому это решение рассматривается нами как временное, позволившее закрыть потребность в инструменте экстракции на проекте.
В целевой картине для решения задачи экстракции данных прорабатываются варианты использования CDC систем типа Oracle Golden Gate или ETL инструментов типа SAP DS.
Подробнее..

Продолжаем знакомство с APIM Gravitee

27.05.2021 20:23:24 | Автор: admin

Всем привет! Меня всё ещё зовут Антон. В предыдущейстатьея провел небольшой обзор APIM Gravitee и в целом систем типа API Management. В этой статье я расскажу,как поднять ознакомительный стенд APIM Gravitee (https://www.gravitee.io), рассмотрим архитектуру системы, содержимое docker compose file, добавим некоторые параметры, запустим APIM Gravitee и сделаем первую API. Статья немного погружает в технические аспекты и может быть полезна администраторам и инженерам, чтобы начать разбираться в системе.

Архитектура

Для ознакомительного стенда будем использовать простейшую архитектуру

Все в докере, в том числе и MongoDB и Elasticsearch. Чтобы сделать полноценную среду для тестирования крайне желательно компоненты MongoDB и Elasticsearch вынести за пределы Docker. Также для простоты манипулирования настройками можно вынести конфигурационные файлы Gateway и Management API: logback.xml и gravitee.yml.

docker-compose.yml

Среду для начальных шагов будем поднимать, используяdocker-compose file, предоставленный разработчиками наgithub. Правда,внесемнесколькокорректив.

docker-compose.yml# Copyright (C) 2015 The Gravitee team (<http://gravitee.io>)## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##<http://www.apache.org/licenses/LICENSE-2.0>## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.#version: '3.5'networks:frontend:name: frontendstorage:name: storagevolumes:data-elasticsearch:data-mongo:services:mongodb:image: mongo:${MONGODB_VERSION:-3.6}container_name: gio_apim_mongodbrestart: alwaysvolumes:- data-mongo:/data/db- ./logs/apim-mongodb:/var/log/mongodbnetworks:- storageelasticsearch:image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-7.7.0}container_name: gio_apim_elasticsearchrestart: alwaysvolumes:- data-elasticsearch:/usr/share/elasticsearch/dataenvironment:- http.host=0.0.0.0- transport.host=0.0.0.0- xpack.security.enabled=false- xpack.monitoring.enabled=false- cluster.name=elasticsearch- bootstrap.memory_lock=true- discovery.type=single-node- "ES_JAVA_OPTS=-Xms512m -Xmx512m"ulimits:memlock:soft: -1hard: -1nofile: 65536networks:- storagegateway:image: graviteeio/apim-gateway:${APIM_VERSION:-3}container_name: gio_apim_gatewayrestart: alwaysports:- "8082:8082"depends_on:- mongodb- elasticsearchvolumes:- ./logs/apim-gateway:/opt/graviteeio-gateway/logsenvironment:- gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000- gravitee_ratelimit_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000- gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200networks:- storage- frontendmanagement_api:image: graviteeio/apim-management-api:${APIM_VERSION:-3}container_name: gio_apim_management_apirestart: alwaysports:- "8083:8083"links:- mongodb- elasticsearchdepends_on:- mongodb- elasticsearchvolumes:- ./logs/apim-management-api:/opt/graviteeio-management-api/logsenvironment:- gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000- gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200networks:- storage- frontendmanagement_ui:image: graviteeio/apim-management-ui:${APIM_VERSION:-3}container_name: gio_apim_management_uirestart: alwaysports:- "8084:8080"depends_on:- management_apienvironment:- MGMT_API_URL=http://localhost:8083/management/organizations/DEFAULT/environments/DEFAULT/volumes:- ./logs/apim-management-ui:/var/log/nginxnetworks:- frontendportal_ui:image: graviteeio/apim-portal-ui:${APIM_VERSION:-3}container_name: gio_apim_portal_uirestart: alwaysports:- "8085:8080"depends_on:- management_apienvironment:- PORTAL_API_URL=http://localhost:8083/portal/environments/DEFAULTvolumes:- ./logs/apim-portal-ui:/var/log/nginxnetworks:- frontend

Первичные системы, на основе которых строится весь остальной сервис:<o:p>

  1. MongoDB - хранение настроек системы, API, Application, групп, пользователей и журнала аудита.

  2. Elasticsearch(Open Distro for Elasticsearch) - хранение логов, метрик, данных мониторинга.

MongoDB

docker-compose.yml:mongodb

mongodb:image: mongo:${MONGODB_VERSION:-3.6}<o:p>container_name: gio_apim_mongodb<o:p>restart: always<o:p>volumes:<o:p>- data-mongo:/data/db<o:p>- ./logs/apim-mongodb:/var/log/mongodb<o:p>networks:<o:p>- storage<o:p>

С MongoDB всё просто поднимается единственный экземпляр версии 3.6, если не указано иное, с volume для логов самой MongoDB и для данных в MongoDB.<o:p>

Elasticsearch

docker-compose.yml:elasticsearch

elasticsearch:image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-7.7.0}<o:p>container_name: gio_apim_elasticsearchrestart: alwaysvolumes:- data-elasticsearch:/usr/share/elasticsearch/dataenvironment:- http.host=0.0.0.0- transport.host=0.0.0.0<o:p>- xpack.security.enabled=false- xpack.monitoring.enabled=false- cluster.name=elasticsearch- bootstrap.memory_lock=true- discovery.type=single-node- "ES_JAVA_OPTS=-Xms512m -Xmx512m"ulimitsmemlock:soft: -1hard: -1nofile: 65536networks:- storage

elasticsearch:

elasticsearch:image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-7.7.0}container_name: gio_apim_elasticsearchrestart: alwaysvolumes:- data-elasticsearch:/usr/share/elasticsearch/data<o:p>environment:- http.host=0.0.0.0- transport.host=0.0.0.0- xpack.security.enabled=false- xpack.monitoring.enabled=false- cluster.name=elasticsearch- bootstrap.memory_lock=true- discovery.type=single-node- "ES_JAVA_OPTS=-Xms512m -Xmx512m"ulimits:memlock:soft: -1hard: -1nofile: 65536networks:- storage

С Elasticsearch также всё просто поднимается единственный экземпляр версии 7.7.0, если не указано иное, с volume для данных в Elasticsearch. Сразу стоит убрать строки xpack.security.enabled=false и xpack.monitoring.enabled=false, так как хоть они и указаны как false, Elasticsearch пытается найти XPack и падает. Исправили ли этот баг в новых версиях не понятно, так что просто убираем их, или комментируем. Также стоит обратить внимание на секцию ulimits, так как она требуется для нормальной работы Elasticsearch в docker.<o:p>

Дальше уже поднимаются компоненты сервиса:

  1. Gateway

  2. Management API

  3. Management UI

  4. Portal UI

Gateway/APIM Gateway

docker-compose.yml:gatewaygateway:image: graviteeio/apim-gateway:${APIM_VERSION:-3}container_name: gio_apim_gatewayrestart: alwaysports:- "8082:8082"depends_on:- mongodb- elasticsearchvolumes:- ./logs/apim-gateway:/opt/graviteeio-gateway/logs      environment:    - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000      - gravitee_ratelimit_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000- gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200networks:- storage- frontend<o:p>

С Gateway всё несколько сложнее поднимается единственный экземпляр версии 3, если не указано иное. Если мы посмотрим, что лежит наhub.docker.com, то увидим, что у версий 3 и latest совпадают хеши. Дальше мы видим, что запуск данного сервиса, зависит от того, как будут работать сервисы MongoDB иElasticsearch. Самое интересное, что если Gateway запустился и забрал данные по настроенным API из mongodb, то дальше связь с mongodb и elasticsearch не обязательна. Только в логи будут ошибки сыпаться, но сам сервис будет работать и соединения обрабатывать согласно той версии настроек, которую последний раз закачал в себя Gateway. В секции environment можно указать параметры, которые будут использоваться в работе самого Gateway, для переписывания данных из главного файла настроек: gravitee.yml. Как вариант можно поставить теги, тенанты для разграничения пространств, если используется Open Distro for Elasticsearch вместо ванильного Elasticsearch. Например, так мы можем добавить теги, тенанты и включить подсистему вывода данных о работе шлюза.

environment:- gravitee_tags=service-tag #включаемтег: service-tag- gravitee_tenant=service-space #включаемтенант: service-space- gravitee_services_core_http_enabled=true # включаем сервис выдачи данных по работе Gateway  - gravitee_services_core_http_port=18082 # порт сервиса- gravitee_services_core_http_host=0.0.0.0 # адрес сервиса- gravitee_services_core_http_authentication_type=basic # аутентификация либо нет, либо basic - логин + пароль  - gravitee_services_core_http_authentication_type_users_admin=password #логин: admin,пароль: password  Чтобы к подсистеме мониторинга был доступ из вне, надо ещё открыть порт 18082.ports:- "18082:18082"Management API/APIM APIdocker-compose.yml:management_apimanagement_api:image: graviteeio/apim-management-api:${APIM_VERSION:-3}container_name: gio_apim_management_apirestart: alwaysports:- "8083:8083"links:- mongodb- elasticsearchdepends_on:- mongodb- elasticsearchvolumes:- ./logs/apim-management-api:/opt/graviteeio-management-api/logsenvironment:- gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000  - gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200 networks:    - storage- frontend

ManagementAPI это ядро всей системы и предоставляет службы для управления и настройкиAPI, логи, аналитики и веб-интерфейсовManagementUIиPortalUI. Зависит от MongoDB и Elasticsearch. Также можно через секцию environment указать параметры, которые будут использоваться в работе самого ядра системы. Дополним наши настройки:

environment:- gravitee_email_enable=true # включаем возможность отправлять письма- gravitee_email_host=smtp.domain.example # указываем сервер через который будем отправлять письма- gravitee_email_port=25 # указываем порт для сервера- gravitee_email_username=domain.example/gravitee #логиндлясервера- gravitee_email_password=password #парольдлялогинаотсервера  - gravitee_email_from=noreply@domain.example # указываем от чьего имени будут письма- gravitee_email_subject="[Gravitee.io] %s" #указываемтемуписьма

Management UI/APIM Console

docker-compose.yml:apim_consolemanagement_ui:image: graviteeio/apim-management-ui:${APIM_VERSION:-3}container_name: gio_apim_management_uirestart: alwaysports:- "8084:8080"depends_on:- management_apienvironment:- MGMT_API_URL=http://localhost:8083/management/organizations/DEFAULT/environments/DEFAULT/      volumes:    - ./logs/apim-management-ui:/var/log/nginxnetworks:- frontend

Management UI предоставляет интерфейс для работы администраторам и разработчикам. Все основные функции можно осуществлять и выполняя запросы непосредственно к REST API. По опыту могу сказать, что в переменной MGMT_API_URL вместоlocalhostнадо указать IP адрес или название сервера, где вы это поднимаете, иначе контейнер не найдет Management API.

Portal UI/APIM Portaldocker-compose.yml:apim_portalportal_ui:image: graviteeio/apim-portal-ui:${APIM_VERSION:-3}container_name: gio_apim_portal_uirestart: alwaysports:- "8085:8080"depends_on:- management_apienvironment:- PORTAL_API_URL=http://localhost:8083/portal/environments/DEFAULTvolumes:- ./logs/apim-portal-ui:/var/log/nginxnetworks:- frontend

Portal UI это портал для менеджеров. Предоставляет доступ к логам, метрикам и документации по опубликованным API. По опыту могу сказать, что в переменной PORTAL_API_URL вместоlocalhostнадо указать IP-адрес или название сервера, где вы это поднимаете, иначе контейнер не найдет Management API.<o:p>

Теперь соберем весь файл вместе.

docker-compose.yml

# Copyright (C) 2015 The Gravitee team (<http://gravitee.io>)## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##         <http://www.apache.org/licenses/LICENSE-2.0>## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.#version: '3.5'networks:  frontend:    name: frontend  storage:    name: storagevolumes:  data-elasticsearch:  data-mongo:services:  mongodb:    image: mongo:${MONGODB_VERSION:-3.6}    container_name: gio_apim_mongodb    restart: always    volumes:      - data-mongo:/data/db      - ./logs/apim-mongodb:/var/log/mongodb    networks:      - storage  elasticsearch:    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-7.7.0}    container_name: gio_apim_elasticsearch    restart: always    volumes:      - data-elasticsearch:/usr/share/elasticsearch/data    environment:      - http.host=0.0.0.0      - transport.host=0.0.0.0      - cluster.name=elasticsearch      - bootstrap.memory_lock=true      - discovery.type=single-node      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"    ulimits:      memlock:        soft: -1        hard: -1      nofile: 65536    networks:      - storage  gateway:    image: graviteeio/apim-gateway:${APIM_VERSION:-3}    container_name: gio_apim_gateway    restart: always    ports:      - "8082:8082"      - "18082:18082"    depends_on:      - mongodb      - elasticsearch    volumes:      - ./logs/apim-gateway:/opt/graviteeio-gateway/logs    environment:      - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000      - gravitee_ratelimit_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000      - gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200         - gravitee_tags=service-tag # включаем тег: service-tag         - gravitee_tenant=service-space # включаем тенант: service-space         - gravitee_services_core_http_enabled=true # включаем сервис выдачи данных по работе Gateway         - gravitee_services_core_http_port=18082 # порт сервиса         - gravitee_services_core_http_host=0.0.0.0 # адрес сервиса          - gravitee_services_core_http_authentication_type=basic # аутентификация либо нет, либо basic - логин + пароль         - gravitee_services_core_http_authentication_type_users_admin=password # логин: admin, пароль: password    networks:      - storage      - frontend  management_api:    image: graviteeio/apim-management-api:${APIM_VERSION:-3}    container_name: gio_apim_management_api    restart: always    ports:      - "8083:8083"    links:      - mongodb      - elasticsearch    depends_on:      - mongodb      - elasticsearch    volumes:      - ./logs/apim-management-api:/opt/graviteeio-management-api/logs    environment:      - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000      - gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200         - gravitee_email_enable=true # включаем возможность отправлять письма         - gravitee_email_host=smtp.domain.example # указываем сервер через который будем отправлять письма         - gravitee_email_port=25 # указываем порт для сервера         - gravitee_email_username=domain.example/gravitee # логин для сервера         - gravitee_email_password=password # пароль для логина от сервера         - gravitee_email_from=noreply@domain.example # указываем от чьего имени будут письма          - gravitee_email_subject="[Gravitee.io] %s" # указываем тему письма    networks:      - storage      - frontend  management_ui:    image: graviteeio/apim-management-ui:${APIM_VERSION:-3}    container_name: gio_apim_management_ui    restart: always    ports:      - "8084:8080"    depends_on:      - management_api    environment:      - MGMT_API_URL=http://localhost:8083/management/organizations/DEFAULT/environments/DEFAULT/    volumes:      - ./logs/apim-management-ui:/var/log/nginx    networks:      - frontend  portal_ui:    image: graviteeio/apim-portal-ui:${APIM_VERSION:-3}    container_name: gio_apim_portal_ui    restart: always    ports:      - "8085:8080"    depends_on:      - management_api    environment:      - PORTAL_API_URL=http://localhost:8083/portal/environments/DEFAULT    volumes:      - ./logs/apim-portal-ui:/var/log/nginx    networks:      - frontend

Запускаем

Итоговый файл закидываем на сервер с примерно следующими характеристиками:

vCPU: 4

RAM: 4 GB

HDD: 50-100 GB

Для работы Elasticsearch, MongoDB и Gravitee Gateway нужно примерно по 0.5 vCPU, больше только лучше. Примерно тоже самое и с оперативной памятью - RAM. Остальные сервисы по остаточному принципу. Для хранения настроек много места не требуется, но учитывайте, что в MongoDB еще хранятся логи аудита системы. На начальном этапе это будет в пределах 100 MB. Остальное место потребуется для хранения логов в Elasticsearch.

docker-compose up -d # если не хотите видеть логиdocker-compose up # если хотите видеть логи и как это все работает

Как только в логах увидите строки:

gio_apim_management_api_dev | 19:57:12.615 [graviteeio-node] INFO  i.g.r.a.s.node.GraviteeApisNode - Gravitee.io - Rest APIs id[5728f320-ba2b-4a39-a8f3-20ba2bda39ac] version[3.5.3] pid[1] build[23#2f1cec123ad1fae2ef96f1242dddc0846592d222] jvm[AdoptOpenJDK/OpenJDK 64-Bit Server VM/11.0.10+9] started in 31512 ms.

Можно переходить по адресу: http://ваш_адрес:8084/.

Нужно учесть, что Elasticsearch может подниматься несколько дольше, поэтому не пугайтесь если увидите такое "приглашение":

Надо просто ещё немного подождать. Если ошибка не ушла, то надо закапываться в логи и смотреть, что там за ошибки. Видим такое приглашение отлично!

Вводим стандартный логин и пароль: admin/admin и мы в системе!

Первичная настройка

Настройки самой системы

Переходим в менюSettings PORTAL Settings

Здесь можно настроить некоторый параметры системы. Например: доступные методы аутентификации наших клиентов: Keyless, API_KEY, Oauth2 или JWT. Подробно их мы рассмотрим скорее всего в третьей статье, а пока оставим как есть. Можно подключить Google Analytics. Время обновления по задачам и нотификациям. Где лежит документация и много ещё чего по мелочи.

Добавление tags и tenant

ПереходимвменюSettings GATEWAY Shardings Tags

Здесь надо добавить теги, по которым у нас будут различаться шлюзы. Нажимаем "+" и добавляем тег и его описание.

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

ПереходимвменюSettings GATEWAY Tenants

То же самое и с настройкой тенантов. Только тут нет кнопки "+", но есть серенькая надпись "New tenant", которую надо нажать для добавления нового тенанта. Естественно, данный тенант должен быть создан в Open Distro for Elasticsearch, и к нему должны быть выданы права.

Добавление пользователей

Переходим вSettings USER MANAGEMENT Users

Здесь можно добавлять пользователей, вот только работать это будет, если у нас настроена рассылка по email. Иначе новым пользователям не придёт рассылка от системы со ссылкой на сброс пароля. Есть ещё один способ добавить пользователя, но это прям хардкод-хардкод!

В файле настроек Management API: gravitee.yml есть такой кусочек настроек:

security:  providers:  # authentication providers    - type: memory      # password encoding/hashing algorithm. One of:      # - bcrypt : passwords are hashed with bcrypt (supports only $2a$ algorithm)      # - none : passwords are not hashed/encrypted      # default value is bcrypt      password-encoding-algo: bcrypt      users:        - user:          username: admin          password: $2a$10$Ihk05VSds5rUSgMdsMVi9OKMIx2yUvMz7y9VP3rJmQeizZLrhLMyq          roles: ORGANIZATION:ADMIN,ENVIRONMENT:ADMIN

Здесьперечисленытипыхранилищдляпользователей: memory, graviteeиldap.Данные из хранилищаmemoryберутся из файла настроек:gravitee.yml. Данные из хранилищаgraviteeхранятся вMongoDB. Для хранения пользовательских паролей, по умолчанию используется тип хеширования BCrypt с алгоритмом $2a$. В представленных настройках мы видим пользователя: admin с хешированным паролем: admin и его роли. Если мы будем добавлять пользователей через UI, то пользователи будут храниться в MongoDB и тип их будет уже gravitee.

Создание групп пользователей

Переходим вSettings USER MANAGEMENT Groups

При нажатии на "+" получаем возможность добавить группу и пользователей в эту группу.

Проверка доступных шлюзов

При переходе в меню Gateways у нас отображаются все шлюзы, которые у нас есть в доступе.

Здесь мы видим настройки шлюза. В частности, Sharding tags и Tenant. Их мы добавили чуть раньше.

Естественно, есть возможность мониторинга состояния шлюза. Данные по мониторингу хранятся в Elasticsearch в отдельном индексе.

Публикация первого API

Для публикации первого API нам сначала потребуется сделать какой-нибудь backend с API.

BackEnd с API, балеринами и Swagger.

Возьмём FastAPI и сделаем простейшее backend с API.

#!/bin/env python3import uvicornfrom fastapi import FastAPIapp = FastAPI()@app.get('/')@app.get('/{name}')def read_root(name: str = None):    """    Hello world    :return: str = Hello world    """    if name:        return {"Hello": name}    return {"Hello": "World"}@app.get("/items/{item_id}")@app.post("/items/{item_id}")@app.put("/items/{item_id}")def gpp_item(item_id: str):    """    Get items    :param item_id: id    :return: dict    """    return {"item_id": item_id}if __name__ == "__main__":    uvicorn.run(app, host="0.0.0.0", port=8000)

Это иAPIможно назвать с трудом, но для примера работы вполне хватит.

Теперь запустим его! Можно даже на том же сервере.

python3 main.py

Теперь, если мы зайдем на этот серверhttp://backend_server:8000/,мы увидим приветствие миру! Если подставим своё имя, типа так:http://backend_server:8000/Anton, то приветствовать уже будут вас! Если же хотите познать всю мощьFastAPI, то сразу заходите на адрес:http://backend_server:8000/docsилиhttp://backend_server:8000/redoc. На этих страницах можно найти все методы, с которым работает данное API и также ссылку на swagger файл. Копируем URL до swagger файла.

В прошлый раз мы создавали наш план вручную. Было несколько утомительно. Сегодня мы сделаем все быстрее, через импорт swagger файла!

На главном экране Gravitee нажимаем большой "+", выбираем "IMPORT FROM LINK", вставляем URL и нажимаем "IMPORT".

Получается как-то так

Нажимаем "IMPORT"!

Почти полностью сформированный API! Теперь немного доработаем напильником...

Для начала нажимаем "START THE API" чтобы API запустить.

Переходим в "Plans" и нажимаем "+".

Создаем тестовый план.

Тип аутентификации выбираем Keyless (public) и нажимаем "NEXT".

Ограничения по количеству запросов и путям пропускаем. Нажимаем "NEXT".

Политики нам тоже пока не нужны. Нажимаем "SAVE".

План создан, но пока находиться в стадии "Staging"

Нажимаем на кнопку публикации плана - синее облачко со стрелочкой вверх! Подтверждаем кнопкой "PUBLISH"

И получаем опубликованный план и какую-то желтую полоску с призывом синхронизировать новую версию API.

Нажимаем "deploy your API" и подтверждаем наше желание "OK"

Переходим вAPIs Proxy Entrypoints

Здесь можно указать точки входа для нашего API и URL пути. У нас указан только путь "/fastapi". Можно переключиться в режим "virtual-hosts" и тогда нам будет доступен вариант с указанием конкретных серверов и IP. Это может быть актуально для серверов с несколькими сетевыми интерфейсами.

ВAPIs Proxy GENERAL CORSможнопроизвестинастройкиCross-origin resource sharing.

ВAPIs Proxy GENERAL Deploymentsнадоуказатьвсеsharding tags,которыебудутиспользоватьсяэтимAPI.

ВAPIs Proxy BACKEND SERVICES Endpointsможно указать дополнительные точки API и настроить параметры работы с ними.

Сейчас нас интересуют настройки конкретной Endpoint, поэтому нажимаем на нижнюю шестеренку.

Исправляем "Target" на http://backend_server:8000/, устанавливаем tenant, сохраняем и деплоим!

ВAPIs Proxy Deploymentsнадо указать те sharding tags, которые могут использовать данное API. После этого необходимо вернуться в созданный план и в списке Sharding tags выбрать тег "service-tag".

ВAPIs Designможно указать политики, которые будут отрабатывать при обработке запросов.

ВAPIs Analytics Overviewможно смотреть статистику по работе данного конкретного API.

ВAPIs Analytics Logsможно настроить логи и потом их смотреть.

ВAPIs Auditможно посмотреть, как изменялись настройки API.

Остальное пока рассматривать не будем, на работу оно не влияет.

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

Переходим наhttp://gravitee_host:8082/fastapi/ , и вам покажется приветствие миру:

Также сразу можно заглянуть вAPIs Analytics Overview/Logsдля просмотра статистики обработки запросов.

Заключение

Итак, поздравляю всех, кто дочитал до сюда и остался в живых! Теперь вы знаете, как поднять ознакомительный стенд APIM Gravitee, как его настроить, создать новое API из swagger файла и проверить, что всё работает. Вариантов настройки шлюзов, точек входа и выхода, сертификатов, балансировок нагрузки и записи логов много. В одной статье всего и не расскажешь. Так что в следующей статье я расскажу о более продвинутых настройках системы APIM Gravitee. В Телеграмме есть канал по данной системе:https://t.me/gravitee_ru, вопросы по нюансам настройки можно задавать туда.

Подробнее..

Коллектор логов на старом железе или встречаите Vector 32bit

15.12.2020 00:22:12 | Автор: admin
В любой большой компании, и X5 не исключение, имеется старое железо которое успешно работает и работает хорошо, но приходит время и с него тоже необходимо начать забирать логи и метрики. В нашем случае это машины c x86_32 Debian 9.5 и 512Мб оперативной памяти.

Небольшой Disclaimer


Автор статьи не является экспертом по языку Rust и соответственно любые улучшения, и конкретные рекомендации от гуру приветствуются. Статья не является рекламой Vector и автор никак не связан с компанией Timber и ее контрибуторами. Все ниже описанное является чистым DIY экспериментом с целью показать, что нет непреодолимых барьеров, если очень хочется.

Итак, начнем


Речь пойдет о Vector версии 0.10.0, хотя модный и хайповый лог коллектор только недавно обновился до версии 0.11.0, возможно этот способ подойдет и для него.

Нам в компании X5 нравится Vector и мы хотели его попробовать на архитектуре x86_32. Тогда как из коробки он доступен для почти любых операционок в двух архитектурах x86_64 и ARM7.

Собирать будем в Docker на основе рекомендаций, изложенных тут.

Описание по ссылке выше подходит только частично, так как нам нужна некая i686-unknown-linux-gnu конфигурация для Rust, как показывает великий Гугл. Собирать будем в докере целевой системы (x86_32 Debian 9.5) потому что я понял, что компиляция 32bit Rust в 64bit окружении мне не под силу.

FYI: Да, до этого я попробовал i686-unknown-linux-musl и мне не удалось заставить ее работать.

Магия Docker


Копируем файлы из репозитория на github:

mkdir -p vector && \  curl -sSfL --proto '=https' --tlsv1.2 https://api.github.com/repos/timberio/vector/tarball/v0.10.0 | \  tar xzf - -C vector --strip-components=1

В директории vector/scripts/ci-docker-images создаем папку builder-i686-unknown-linux-gnu, базовый Dockerfile берем из vector/scripts/ci-docker-images/builder-x86_64-unknown-linux-gnu и начинаем править.

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

FROM i386/debian:9.5 as builder# This is formatted "$UID:$GID" by the docker-compose/scripts.ARG USERRUN apt-get update && \    apt-get -y upgradeRUN apt-get install -y \        make libssl-dev cmake git \        build-essential sudo curl        RUN curl -L https://cpanmin.us | perl - App::cpanminusRUN cpanm File::Rename \ && rename --versionRUN cd /tmp && \  git clone https://github.com/github/cmark-gfm && \  cd cmark-gfm && \  git checkout 0.29.0.gfm.0 && \  make install INSTALL_PREFIX=/usr && \  ldconfig && \  cd .. && \  rm -rf cmark-gfm && \  cmark-gfm --versionRUN sudo adduser runnerRUN sudo usermod -aG sudo runnerUSER runnerRUN curl https://sh.rustup.rs -sSf | sh -s -- --no-modify-path --default-host i686-unknown-linux-gnu -yENV PATH=/home/runner/.cargo/bin:$PATHRUN echo "export PATH=/home/runner/.cargo/bin:$PATH" >> ~/bashrcENV LIBRARY_PATH /usr/local/lib:$LIBRARY_PATHENV LD_LIBRARY_PATH /usr/local/lib:$LD_LIBRARY_PATHRUN rustup update stableRUN rustup run stable cargo install cargo-deb --target=i686-unknown-linux-gnu --version '^1.24.0'CMD ["bash"]

Также пришлось поправить файл vector/Makefile.

Добавив и описав build-i686-unknown-linux-gnu в нескольких местах и сделав ее единственным вариантом сборки.

Кусочек файла vector/Makefile для примера:

#build-all: build-x86_64-unknown-linux-musl build-armv7-unknown-linux-musleabihf build-aarch64-unknown-linux-musl  ## Build the project in release mode for all supported platformsbuild-all: build-i686-unknown-linux-gnu.package-archive-i686-unknown-linux-gnu: build-i686-unknown-linux-gnu ## Build the x86_32 archive$(RUN) package-archive-i686-unknown-linux-gnu

Конфигурация зависимостей Rust лежит в файле vector/Cargo.toml. Туда была добавлена секция profile.release:

[profile.release]opt-level = 'z'  # Optimize for size.debug = falsedebug-assertions = falselto = truecodegen-units = 1

Это было сделано из соображений оптимизации, т.к. первые собранные бинарники были размером с чугунный мост ~ 60Мб, что не приемлемо. Размер оригинальных бинарников с сайта примерно 7Мб.

Вдохновение навеяно на мой взгляд великолепным описанием методик уменьшения размеров бинарников Rust от @johnthagen тут: https://github.com/johnthagen/min-sized-rust

В стремлении сэкономить на размере в секциях sources, transforms закомментированы
logplex|splunk_hec и aws_ec2_metadata|lua соответсвенно, что позволило без секции profile.release сэкономить примерно 10Мб в собранном состоянии.

# Sourcessources = [  "sources-docker",  "sources-file",  "sources-generator",  "sources-http",  "sources-internal_metrics",  "sources-journald",  "sources-kafka",  #"sources-logplex",  "sources-prometheus",  "sources-socket",  #"sources-splunk_hec",  "sources-statsd",  "sources-stdin",  "sources-syslog",  "sources-tls",  "sources-vector",]# Transformstransforms = [  "transforms-add_fields",  "transforms-add_tags",  "transforms-ansi_stripper",  #"transforms-aws_ec2_metadata",  "transforms-coercer",  "transforms-concat",  "transforms-dedupe",  "transforms-field_filter",  "transforms-filter",  "transforms-geoip",  "transforms-grok_parser",  "transforms-json_parser",  "transforms-log_to_metric",  "transforms-logfmt_parser",  #"transforms-lua",  "transforms-merge",  "transforms-regex_parser",  "transforms-remove_fields",  "transforms-remove_tags",  "transforms-rename_fields",  "transforms-sampler",  "transforms-split",  "transforms-swimlanes",  "transforms-tag_cardinality_limit",  "transforms-tokenizer",  "transforms-reduce",]

Сборка


Запускаем все это дело командой:

PASS_FEATURES=default-cmake ./scripts/docker-run.sh builder-i686-unknown-linux-gnu make build

В процессе сборки могут вываливаться ошибки вроде этой:

error: Input/output error (os error 5)warning: build failed, waiting for other jobs to finish...    Building [===>                                                    ] 40/537: regex-syntax                                                                                                             error: build failedMakefile:156: recipe for target 'build' failedmake: *** [build] Error 101

Унывать не советую, перезапускаем make и после бесконечного cargo downloading component, Updating crates.io index и Updating git repository сборка продолжается с того места, на котором прервалась. Кстати если кто-то знает, как это прекратить и заставить cargo и crates использовать локальный кэш было бы супер)

На macbook pro i5 8gb этот процесс длится примерно 2 часа, из них сама сборка минут 50.

После сборки файлик можно сжать UPXом:

upx --best --lzma target/release/vector

На этом все.

Репозиторий github с исправленными файлами и Vector 0.10.0 тут
Собранный бинарник 8,7Мб, сжатый UPX тут
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru