Привет, Хабр!
Меня зовут Павел, и я руковожу группой автоматизации и интеграции в банке РНКБ. Сегодня я хочу рассказать о том, как мы переводили множество интеграционных сервисов на новые рельсы. В нашем банке большинство сервисов самописные и разрабатываются штатными разработчиками, в связи с чем возникла необходимость адаптировать работу существующих сервисов для использования современных подходов разработки. В качестве пилота было выбрано направление «Интеграционные сервисы» (можно просто ИС). ИС – это не что иное, как приложения, обрабатывающие запросы к автоматизированной банковской системе (сокращенно – АБС).
Проблема
Много ИС, написанных на стеке Java, которые крутятся на разных виртуальных машинах. Какие-то завернуты в Docker, остальные работают на хосте ВМ. Хотелось получить единообразность деплоя, единообразность управления, унифицированную подготовку таких сервисов, удобный мониторинг и логирование. Именно с такими требованиями к нам пришли команды разработки и сопровождения ИС.
Инфраструктурное решение или готовим новые рельсы
Так как нам нужна управляемость (оркестрация), а в идеале изоляция сервисов в качестве целевой платформы, был выбран Kubernetes, архитектурно все сервисы в таком случае деплоились бы как контейнеры, что добавляет нам унификацию.
Так как кластер предварительно не предполагался большим, выбрали Rancher K3S.
Основной причиной выбора подобного стека была легковесность решения на базе k3s, в отличие от классического k8s. Весь дистрибутив k3s состоит из одного бинарника размером 60 мегабайт, который можно запускать как в режиме мастер-ноды, так и в режиме воркер-ноды, и архива размером 160 мегабайт с дополнительными образами. Для запуска мастера требуется всего 512 мегабайт ОЗУ, а для воркер-инстанса и того меньше – 75 мегабайт ОЗУ, при этом дискового пространства потребуется всего 250 мегабайт.Ребята из Rancher очень здорово постарались и выпилили из ванильного кубера самые тяжелые части, при этом полностью сохранив его функциональность.Также стоит отметить, что у k3s очень простая процедура обновления: достаточно загрузить на сервер новый бинарник с архивом и перезапустить сервис k3s. Бонусом k3s легко позволяет нам готовить локальные среды для разработки.Еще один несомненный плюс – k3s из коробки поддерживает air-gap – установку в изолированных контурах. Для установки и запуска кластера достаточно просто положить на сервер два файла (бинарник и архив) и запустить бинарник с требуемыми параметрами.
СNI мы выбирали между Сaliсo и Сilium. Flannel нам не подошел, так как в нем нет необходимого нам функционала Network Policy, а связка с Kube-Router нам не понравилась. Потому выбор пал на Cilium ввиду ее наблюдаемости и безопасности, ну а также eBPF-плюшек.
Мы долго определялись, что использовать в качестве Persistent storage для Stateful сервисов. На рынке существует огромное количество решений. Так как рассматривали небольшой кластер, монстров типа СEPH или GlusterFS использовать не хотелось ввиду их прожорливости на ресурсы и трудоемкости администрирования. Нужно было что-то простое, но надежное.
Поначалу тестировали решение от тех же Rancher – Longhorn. Но производительность и некоторые баги нас не устроили. По итогу мы пришли к решению использования Linstor (Piraeus Operator), так как под капотом старый добрый DRBD, у нас с ним есть опыт, он не ест так много ресурсов и показывает отличную производительность. Также сейчас тестируем Mayastor OpenEBS.
Для запуска трафика в кластер и его балансировки мы внедрили связку Kube-Vip, Ingress Nginx, Cert-manager. Несмотря на то что в k3s есть встроенный механизм балансировки ServiceLB он менее функционален, поэтому мы его отключаем. Kube-Vip нам также позволяет делать единый loadbalanced ip для подключения воркер-нод к kube-api.
Также для удобства администрирования внедрили инструменты:
Descheduler — помогает балансировать нагрузку на воркер ноды, шедуля поды по заданным правилам;
Reloader — позволяет нам обновлять ConfigMaps и Secrets без использования хешей.
Деплой сервисов или смазываем рельсы
Ключевой узел инфраструктуры разработки – система контроля версий. Мы используем программный комплекс для коллективной работы GitLab. Такой выбор был сделан не в последнюю очередь из-за существования GitLab CI/CD. Работать с ПО из одной экосистемы намного удобнее, чем интегрировать между собой разные продукты.
В качестве инструмента для деплоя непосредственно в k8s мы выбрали утилиту СI/CD Werf.
Выбор обусловлен:
Сборка как из Dockerfile, так и из своего формата сборки контейнеров Stapel (подробней о различиях и преимуществах коллеги писали здесь);
Имеет встроенную интеграцию с Gitlab CI/CD;
Для описания манифестов использует Helm;
Умеет хранить секретные данные в репозитории в зашифрованном виде;
Умеет как в push так и в pull модель деплоя;
Работает для хранения артефактов с различными container registry (мы используем корпоративный Nexus);
Умеет интегрироваться с ArgoCD
Так как сервисы плюс-минус единообразны, мы написали для них универсальный Helm Сhart, gitlab-ci.yml, werf.yaml и вынесли их в отдельный репозиторий. Провели обширный митап с разработчиками, рассказали, где и что поправить, чтобы соответствовать https://12factor.net. Также написали обширную инструкцию, что править в werf.yaml и values.yaml для того, чтобы запустить конкретный сервис в кластере. На текущий момент пишем с коллегами утилиту на Go, которая позволит генерировать конкретный репозиторий со всеми файлами под конкретный сервис.
Мониторинг и логирование, или следим за качеством рельс
У нас есть централизованная система мониторинга, выстроенная на связках Victoria Metrics+Grafana и др. инструментов. Для того, чтобы мониторить кластер, мы выбрали подход с использованием Prometheus agent + Remote Write. Как я уже говорил, мы написали универсальный Helm-chart, и это позволяет нам прямо с сервисом добавлять необходимые ServiceMonitor, то есть легко поставлять сервис на мониторинг. Таким образом мы можем добавить в наш кластер Grafana и смотреть активные метрики за 2 часа. Все долговременные метрики мы смотрим в централизованной Grafana.
Для отправки и анализа логов из кластера мы воспользовались замечательным opensource инструментов от DataDog – Vector. Он очень гибкий в настройке и достаточно легковесный в плане ресурсов. В принципе Vector может отправлять и метрики из Prometheus, но мы не стали смешивать логи и метрики.
Итог
Мы написали Ansible Playbook со всей обвязкой для разворачивания подобного вида кластеров. Это стало для нас ценным опытом, а также позволило создать инструмент создания k3s кластеров для небольших проектов. Также позволило нам автоматизировать большое количество процессов, и теперь скорость и степень удобства разработки новых сервисов значительно возросли. Сейчас мы пишем централизованную платформу, которая нам позволит управлять и создавать как маленькие кластеры на основе k3s, так и высоконагруженные на основе k8s.
onegreyonewhite
Блин, ничего себе! Вы умудрились собрать весь мой любимый DevOps стек: k3s, werf, gitlab, victoria metrics, argo. Прям страйк в самое сердечко, ребят.
Вопрос: вы взяли ArgoCD только из-за werf operator'а?
dnbstd Автор
Werf - это утилита сI/cd, у нее нет оператора. Она умеет интегрироваться с Argo CD, но мы это редко используем, ибо Werf сама по себе закрывает наши «хотелки». Подробней можно почитать здесь.
onegreyonewhite
Ну вообще есть, через патчинг самого арго - почитайте доку у верфи. Но я вас услышал.
Лично мне у верфи converge не зашёл из-за гитерменизма, поэтому выкатываю бандлы, а самописным оператором (исходники открыты, бандл тоже есть для удобства) выкатываю их с переменными на разных окружениях.
Тогда если вы ArgoCD не пользуете почти, что мешало управлять всем через Rancher Server? У них даже своя CD есть, управление чартами и весьма гуёвенько. К тому же обновлять k3s можно по клику.