× Install ThecoreGrid App
Tap below and select "Add to Home Screen" for full-screen experience.
B2B Engineering Insights & Architectural Teardowns

Alloy central gateway: как не уронить поток телеметрии

Alloy central gateway — это уже не sidecar, а критически важный инфраструктурный слой. Если он принимает metrics, logs и traces всей платформы, ошибка в sizing или monitoring быстро превращается в системную проблему.

Когда Alloy работает как одиночный sidecar, задача проста. Когда он становится централизованным gateway и принимает полный поток телеметрии enterprise-платформы, всё меняется: растут объёмы, увеличивается цена ошибки, а деградация начинает затрагивать сразу все команды. В исходном кейсе речь шла о десятках миллионов active series, терабайтах логов в день и десятках тысяч trace spans в секунду. Для такой схемы уже недостаточно «запустить и посмотреть». Нужны capacity planning, честное load testing и отдельный monitoring path, не зависящий от самого collector.

Проблема здесь архитектурная. Central gateway удобнее per-team sidecar deployments, поскольку он централизует приём данных от application teams через OTLP, Prometheus Remote Write и Loki write protocols. Alloy буферизует, группирует, обрабатывает и отправляет данные дальше в Grafana Cloud. Это упрощает эксплуатацию, но создаёт узкое место: если gateway начинает захлёбываться, это становится заметно всем. Поэтому подход к нему должен быть таким же строгим, как к любому другому production service.

В описанном внедрении команда сначала зафиксировала ожидаемый traffic profile. Для metrics планировалось около 17M active series, для logs — 1 TB/day с пиком 17,5 MB/s, для traces — около 1 TB/day с пиком примерно 23 MB/s. Важно, что это был не только текущий baseline, но и headroom для нескольких onboarding waves от новых команд. Это ключевой инженерный момент: Kubernetes autoscaling не успевает компенсировать внезапный рост такого масштаба, если нагрузка приходит сразу и без запаса.

Дальше начался sizing. Grafana рекомендует опираться на официальную документацию, и в этом кейсе такой baseline использовали как отправную точку. Итоговый ресурсный бюджет составил примерно 195 GB memory и 28 CPU cores. Вместо нескольких крупных pods выбрали большое количество smaller pods. Это прагматичный компромисс: так проще горизонтально наращивать fleet и быстрее реагировать на рост нагрузки. Для одного pod был задан memory request 6 GiB, но без CPU limit. Это было сделано осознанно, поскольку CPU throttling в Kubernetes может добавлять скрытую latency в high-throughput workload.

Затем архитектуру собрали в production-like форме. Центральный collector разместили за ingress controller в Kubernetes. Все входящие потоки — OTLP over HTTP/Protobuf, Prometheus Remote Write и Loki HTTP push — завершаются на ingress и распределяются между Alloy pod fleet. Это снижает сложность на стороне клиентов и создаёт единый входной контур. Но здесь есть важная оговорка: собственный monitoring Alloy вынесли на отдельный путь. Kubernetes Monitoring Helm chart скрапит /metrics endpoint и отправляет данные напрямую в Grafana Cloud, минуя центральный collector. Такой разнос потоков — не мелкая деталь, а защита от blind spot. Если сам gateway деградирует, его health metrics всё равно остаются видимыми.

Перед go-live команда провела нагрузочные тесты в pre-production среде, которая зеркалила production configuration. Для генерации трафика использовали k6 и xk6, а сами тесты распределяли на 10 Amazon EC2 m5.2xlarge instances. Вход в кластер шёл через тот же ingress controller, что и в production. Тестов было много, включая нагрузки на уровне ожидаемого production и выше него. Это важно: тестирование только по baseline не показывает, где начинается реальная деградация и каким будет failure mode.

Отдельно стоит отметить monitoring во время тестов. Он также шёл по независимому пути через Kubernetes Monitoring Helm chart. Это позволило видеть состояние collector в реальном времени даже тогда, когда test traffic создавал сильное давление. Для gateway-сценария это критично. Если health metrics проходят через ту же систему, которую вы проверяете, в момент сбоя вы теряете observability именно там, где она нужна больше всего.

После запуска в production схема выдержала onboarding новых deployments и рост ingestion waves. Fleet масштабировался от min 30 pods, а сама система на момент описания держала почти 17M active series, 20–30 MB/s logs ingestion и до 150 MB/s traces ingestion. Метрики показывали плавную работу HPA: базовый уровень, постепенный рост, без резких провалов. Данных об улучшении latency или throughput в источнике нет, поэтому здесь корректно говорить не об «ускорении», а о стабильной адаптации к росту нагрузки.

Но были и уроки, которые обычно всплывают только под стрессом.

Первый — WAL. Write-ahead log помогает не терять данные при restart, но при sustained high throughput и backpressure со стороны Grafana Cloud он может расти быстрее, чем успевает очищаться. В таком режиме WAL превращается в источник OOM kill.

Второй — GOMEMLIMIT. Go runtime сам по себе не учитывает Kubernetes memory limit так, как многие команды ожидают, поэтому soft ceiling примерно на уровне 80% от memory limit нужен как ранний сигнал для garbage collector. Если этот лимит срабатывает часто, CPU растёт — и это уже полезно: HPA по CPU успевает выполнить scale out раньше, чем memory станет критической.

Итог этого подхода можно описать без маркетинга. Central gateway на Alloy работает, если относиться к нему как к полноценной production system. Нужно планировать не под текущий baseline, а под ближайший рост. Нужно держать monitoring path вне основного data path. Нужно тестировать выше ожидаемого ceiling. И нужно понимать, что retry_on_failure, min-replica и запас по node capacity — это не украшения конфигурации, а механизмы, которые отделяют управляемую деградацию от потери данных.

Ознакомиться с источником

×

🚀 Deploy the Blocks

Controls: ← → to move, ↑ to rotate, ↓ to drop.
Mobile: use buttons below.