Мы используем куки и предполагаем, что вы согласны, если продолжите пользоваться сайтом
Понимаю и согласен
Close
Заявка на обратный звонок
Свяжемся с вами в течение рабочего дня
Нажимая кнопку, вы соглашаетесь на обработку ваших персональных данных согласно нашей политике конфиденциальности.
Блог Southbridge

Миграция высоконагруженного кластера Kubernetes — кейс рекламной сети HProfits


HProfits — это система монетизации сайтов, продажи и покупки трафика по принципу аукциона в реальном времени RTB. Как любая рекламная сеть, HProfits обрабатывает большой объём трафика, что создаёт высокую нагрузку на инфраструктуру проекта. Инженеры Southbridge помогли компании повысить быстродействие и отказоустойчивость инфраструктуры и внедрить новые практики CI/CD.

Технические вводные и особенности проекта


Kubernetes-кластер развернут на собственных трёх физических серверах. Кластер расположен за HAProxy хостера. Запросы принимает nginx, развернутый на базе Ingress-NGINX controller. В кластер поступает в среднем 30 000 запросов/сек. Пиковая нагрузка 2,5 млн RPM. 

Приложения внутри HProfits написаны на Golang. Для обработки очередей и хранения данных приложений используется Kafka и Aerospike, для аналитики — ClickHouse. 

Особенности проекта:
  • для приложений критически важна скорость обработки запросов, поэтому её постоянно оптимизируют, опираясь на большое число метрик;
  • метрики и логи хранят в большом объёме — за два месяца 3 Тб в Grafana Loki;
  • специфика проекта не позволяет разделить среды разработки на production, develop и stage;
  • персистентных данных бизнес-приложений нет, поэтому нет и распределённого хранилища (Ceph, NFS или других решений).

Штатный системный администратор HProfits уволился, и заниматься его задачами было некому. Заказчик хотел, чтобы мы взяли на себя базовую поддержку инфраструктуры, а также внедрили CI/CD и канареечный деплой.

Состояние кластера


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

Не было контроля над ключевыми образами. В качестве образа для Ingress-NGINX controller использовалась версия оригинального образа, изменённая бывшим сотрудником и хранящаяся в его Docker Hub. В его же публичном GitLab registry были расположены и некоторые инфраструктурные образы. В любой момент эти образы могли быть изменены или удалены, что привело бы к нарушению работоспособности кластера.

Персистентные данные хранились на LocalStorage.Для хранения метрик, логов, данных S3-хранилища, Grafana dashboards, Kafka, Aerospike и других использовалось локальное хранилище. При этом не были обеспечены механизмы отказоустойчивости на случай отказа одной из нод кластера. Данные Persistent Volume синхронизировались между нодами, но это не позволяло обеспечить высокую доступность в случае сбоев.. 

При выборке логов из Loki часто возникали ошибки из-за высокой сложности запросов. А Prometheus потреблял десятки гигабайт памяти на сбор метрик и обработку запросов.

Проблемы при переезде


CI\CD был написан не для всех приложений. Часть приложений разработчики деплоили с личных компьютеров и имели полный доступ к кластеру. Переезд же предполагал одновременный деплой бизнес-приложений в оба кластера с индивидуальными параметрами. 

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

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

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

Результат


✔️ Повысили отказоустойчивость кластера Kafka
  • Скорректировали helm-чарт: подняли версию Kafka, скорректировали ресурсы, правильно настроили affinity и antiaffinity.
  • Изменили настройки репликации таким образом, чтобы обеспечить баланс между отказоустойчивостью, скоростью работы и объемом хранимых данных. 
  • Добавили network policy, чтобы доступ к кластеру Kafka был только с серверов ClickHouse и компьютеров разработчиков.

✔️ Доработали CI/CD
  • Развернули свежую версию GitLab и Gitlab Runner, настроили автоматическое обновление и очистку registry.
  • Обсудили и внедрили удобную для разработчиков стратегию деплоя приложений.
  • Настроили канареечный деплой: новая версия приложения тестируется на небольшом объеме боевого трафика. Расширенное логирование и метрики позволяют принять решение об окончательном деплое.
  • В качестве Proxy для Go-модулей использовали проект Athens. Он позволяет существенно сократить время сборки.
  • Для сборки образов запланировали внедрить Kaniko (сейчас сборка идёт Docker-in-Docker). Это позволит повысить безопасность.

✔️ Оптимизировали хранение и обработку метрик, пересмотрели подход к алертингу
  • Обновлен Prometheus stack. В helm-чарты приложений добавлены service monitors, prometheus rules. Alertmanager интегрирован с нашей CRM, алерты из Grafana отправляются в Telegram и Discord клиента со скриншотом.
  • Для долгосрочного хранения метрик и обработки сложных запросов используется VictoriaMetrics. Задеплоена в кластерном режиме, что позволяет достигать необходимой скорости обработки запросов и отказоустойчивости.
  • Loki теперь развернут в distributed-режиме (microservice-mode) для увеличения отказоустойчивости и возможности точного тюнинга производительности. Логи перенесены в S3-хранилище хостера (это экономически выгоднее и надежнее), проведена оптимизация сборщиков логов.

✔️ Обеспечили надёжность хранения персистентных служебных данных
  • Grafana dashboards перенесены в git и теперь генерируются в configmap. Написан CI для их обновления. Таким образом достигается персистентность Grafana.
  • Хранилище minio убрали из кластера — переехали на S3 хостера.
  • Надежность вспомогательной базы Postgres обеспечивается Stolon и его бэкапами.


Kubernetes Кейсы клиентов DevOps