
Наткнулся на интересный материал про тестирование GitOps на масштабируемость и нагрузку. Его целых три недели проводила компания IITS Consulting. Оригинал читать не меньше 40 минут, поэтому сократил его, сохранив все самое важное, — и теперь делюсь со всеми обитателями Хабра.
Если совсем нет времени читать, то вот коротко: управление кластерами тестировали на основе Argo CD, vCluster, kubara и Sveltos. В итоге контроллер приложений Argo CD начинал сталкиваться с OOM-завершениями примерно при 15 000–20 000 кешированных объектов на хаб. Развернутые манифесты помогали, настройка помогала лишь частично. При этом Sveltos обрабатывал сценарии развертывания типа аддонов при значительно меньшем потреблении памяти — примерно 2 ГБ против 21 ГБ. Основной вывод: при очень больших масштабах архитектура важнее тонкой настройки.
А теперь подробности.
Что хотели выяснить
Большинство платформ Kubernetes и инструментов GitOps предназначены для работы с 10–300 кластерами. Но периферийным сетям, розничной торговле, телекоммуникациям, супермаркетам и другому бизнесу требуется от 1 000 до 10 000 кластеров. Выдержит ли инфраструктура? Сколько кластеров вообще можно обслуживать осмысленным образом?
Поступил амбициозный запрос: поддержать работу более 15 000 кластеров и свыше 75 000 приложений во всем мире. Для этого в iits-consulting разработали фреймворк GitOps под названием kubara. Он основан на архитектуре «хаб-и-спицы». С его помощью хотели понять ограничения в большом масштабе, чтобы принимать более правильные архитектурные решения и для меньших сред.
Как создали среду
Тестовую среду запустили на управляемом кластере Kubernetes от STACKIT. Сервис основан на Gardener и называется STACKIT Kubernetes Engine (SKE). Кластер работал на версии Kubernetes 1.35.4. Использовали несколько пулов узлов.

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

Что происходит на этой диаграмме:
Kubara создавал каталог компонентов платформы на основе общих (umbrella) Helm-диаграмм.
Он инициализировал Argo CD и позволял ему управлять собой через этот каталог.
Подключение к Vault устанавливалось через External Secrets Operator (ESO).
На основе меток и генератора кластеров ApplicationSet Argo CD развертывал и управлял различными компонентами платформы: Traefik, cert-manager, external-dns.
Затем эту конфигурацию расширили: создали общие (umbrella) Helm-диаграммы для vCluster и vCluster Platform и добавили их как компоненты платформы.

Идея была простой — поставить метку на хаб- или дочерний кластер, чтобы движок GitOps развернул в нем нужное приложение. На этом этапе все стало немного интереснее — тестировщикам нужно было придумать, как делать три вещи:
1. Развертывать любое количество кластеров по требованию.
2. Подключать любое количество кластеров.
3. Развертывать любое количество приложений в этих кластерах.
Для решения первой задачи расширили среду с помощью паттерна App of Apps. Его суть в том, чтобы создать много приложений Argo CD и развертывать их одновременно.

Вторую задачу можно было решить двумя путями. Первый — получить kubeconfig, отправить его в Vault, создать ExternalSecret, добавить метки и позволить Argo CD развертывать приложения на основе полученных генераций. Это трудоемко.
Второй вариант — использовать vCluster Platform вместе с Argo CD Connector. Тогда платформа будет создавать виртуальные кластеры из пользовательского ресурса VirtualClusterInstance.
Это удобнее, потому что коннектор автоматически устанавливает соединение между Argo CD и созданными виртуальными кластерами. Конечная точка при этом защищается интеграцией с Tailscale.
В итоге серия тестов показала, где находится предел для open-source-версии Argo CD в архитектуре «хаб-и-спицы». Вот так она выглядела:

Как это работало
К описанной выше среде на базе kubara добавили несколько скриптов для имитации различных сценариев поведения. Первый шаг — создание vCluster. Для этого использовали уже известный паттерн App of Apps и сгенерированные Argo CD приложения.

./scripts/1-create-applications.sh 5 Generating 5 Argo CD Application manifests from scripts/app-vcluster-template.yaml vcluster-1 -> apps/vcluster-1.yaml vcluster-2 -> apps/vcluster-2.yaml vcluster-3 -> /Users/artemlajko/git/15-04-2025/new/demos/scale-tests-with-1000-vclusters-based-on-kubara-2026/apps/vcluster-3.yaml vcluster-4 -> /Users/artemlajko/git/15-04-2025/new/demos/scale-tests-with-1000-vclusters-based-on-kubara-2026/apps/vcluster-4.yaml vcluster-5 -> apps/vcluster-5.yaml Generated 5 manifests in apps
Как альтернативу можно создать ресурсы VirtualClusterInstance.
./scripts/1-create-applications.sh --virtual 5 Generating 5 VirtualClusterInstance manifests from /scripts/virtualclusterinstance-template.yaml vcluster-1 -> /apps/virtualclusterinstance-1.yaml vcluster-2 -> /apps/virtualclusterinstance-2.yaml vcluster-3 -> /apps/virtualclusterinstance-3.yaml vcluster-4 -> /apps/virtualclusterinstance-4.yaml vcluster-5 -> /apps/virtualclusterinstance-5.yaml Generated 5 manifests in /apps
Второй шаг — получить файлы kubeconfig и отправить их в Vault.

./scripts/2-sync-vclusters.sh 5 Logging in to Vault... Received Vault token Processing vClusters from 1 to 5 (parallelism=1) [vcluster-1] Generating kubeconfig via vcluster-1.controlplane-dev.stackit.run [vcluster-1] Kubeconfig generated [vcluster-2] Generating kubeconfig via vcluster-2.controlplane-dev.stackit.run ... [vcluster-4] Kubeconfig generated [vcluster-5] Generating kubeconfig via vcluster-5.controlplane-dev.stackit.run [vcluster-5] Kubeconfig generated Reading current Vault secret my_clusters Writing 5 kubeconfig(s) to Vault secret my_clusters Synchronized 5 vClusters
Этот шаг требуется, только когда vCluster развертываются с помощью поставщика Helm-диаграмм.
Третий шаг — подключить кластеры к Argo CD и развернуть приложения на основе меток.

./scripts/3-generate-values.sh 5 > customer-service-catalog/helm/controlplane/argo-cd/values.yaml
Остальное берет на себя kubara. Он создает ExternalSecrets с необходимыми метками, извлекает kubeconfig-файлы и позволяет Argo CD использовать их для целевого развертывания.
При использовании vCluster Platform второй шаг можно пропустить. Argo CD Connector автоматически устанавливает соединение с vCluster. В этом случае нужно лишь добавить метки.

./scripts/12-argocd-deploy-applications.sh "kro=enabled" Excluded: cluster-vcluster-platform.controlplane-dev.stackit.run-52690538 Dry run: false Applying labels: - kro=enabled argocd/cluster-vcluster-platform.controlplane-dev.stackit.run-3735921280 argocd/cluster-vcluster-platform.controlplane-dev.stackit.run-3752698899 argocd/cluster-vcluster-platform.controlplane-dev.stackit.run-3769476518 argocd/cluster-vcluster-platform.controlplane-dev.stackit.run-3836586994 argocd/cluster-vcluster-platform.controlplane-dev.stackit.run-3853364613
Вот так это выглядит в пользовательском интерфейсе Argo CD.

Пользовательский интерфейс Argo CD, отображающий ресурсы vCluster и VirtualClusterInstance
Также эту идею протестировали со Sveltos.
./scripts/4-register-sveltos-clusters.sh 5 [vcluster-1] Merging kubeconfig [vcluster-1] Registering in namespace vcluster-1 cluster vcluster-1 successfully registered/updated in namespace vcluster-1. [vcluster-2] Generating kubeconfig via vcluster-2.controlplane-dev.stackit.run [vcluster-2] Merging kubeconfig [vcluster-2] Registering in namespace vcluster-2 cluster vcluster-2 successfully registered/updated in namespace vcluster-2. [vcluster-3] Generating kubeconfig via vcluster-3.controlplane-dev.stackit.run ... [vcluster-5] Merging kubeconfig [vcluster-5] Registering in namespace vcluster-5 cluster vcluster-5 successfully registered/updated in namespace vcluster-5. Registered 5 vClusters in Sveltos (parallelism=1)
Чтобы проверить, работает ли — использовали это:
kubectl get clustersummaries.config.projectsveltos.io -A -o wide NAMESPACE NAME AGE HELMCHARTS KUSTOMIZEREFS POLICYREFS vcluster-1 cert-manager-sveltos-vcluster-1 85s Provisioned vcluster-2 cert-manager-sveltos-vcluster-2 83s Provisioned vcluster-3 cert-manager-sveltos-vcluster-3 82s Provisioned vcluster-4 cert-manager-sveltos-vcluster-4 78s Provisioned vcluster-5 cert-manager-sveltos-vcluster-5 78s Provisioned
Результаты тестирования
Non-HA- и HA-конфигурации
В начальных Non-HA-тестах (одна реплика контроллера; лимит памяти — 12 ГБ) первые ошибки OOM-завершения появлялись на шестой итерации. Зафиксировали такой результат:
30 vCluster, 186 приложений, 6 300 объектов и 420 долго работающих подов, включая рабочие нагрузки и vCluster. Этого уже достаточно для многих целей. Если вы работаете в меньшем масштабе или хотите сэкономить, вам не обязательно сразу использовать HA-конфигурацию.
Использование WET YAML-манифестов показало себя лучше, чем использование DRY Helm-диаграмм: нагрузка на репо-сервер была существенно ниже.

В HA-конфигурации с тремя репликами контроллера, автоматическим масштабированием и лимитом 12 ГБ памяти удалось выйти на такой результат: 150 vCluster, 742 приложения и 16 700 объектов. После этого появлялись ошибки OOM-завершения.
Снятие лимитов памяти лишь отсрочило проблему: контроллеры потребляли до 21 ГБ RAM, затем кластер становился нестабильным.
Тесты показали: проблема не в количестве кластеров или приложений, а в количестве объектов, которое Argo CD кеширует и обрабатывает. Барьер — примерно 15 000–17 000 объектов.
Тонкая настройка (Finetuning)
Вот что сделали тестировщики для оптимизации:
Увеличили число воркеров (--status-processors=50, --operation-processors=25).
Использовали алгоритм шардирования consistent-hashing.
Настроили переменные окружения для управления кешем и пакетной обработкой событий.
Увеличили количество шардов с трех до шести.
Так получилось улучшить пропускную способность и глубину очередей, но фундаментально проблема не решилась. При достижении 18 000–20 000 объектов один из контроллеров неизбежно сталкивался с ошибкой OOM-завершения. Другие не брали на себя его работу, и его шард переставал синхронизироваться.

Это значит, что для масштаба более 1 000 кластеров и 5 000–10 000 тяжелых приложений один хаб Argo CD не подходит просто из-за архитектурных ограничений. Поэтому для таких задач лучше разделять нагрузку между несколькими хабами или использовать энтерпрайз-решения вроде Akuity Platform или Octopus Deploy.
Sveltos
Sveltos — контроллер для управления аддонами, который работал поверх Argo CD. Он брал на себя развертывание приложений на целевых кластерах, а Argo CD управлял только самим Sveltos и его ресурсами.
Результаты впечатлили. При развертывании 600 приложений на 150 vCluster Sveltos использовал около 2 ГБ памяти. В то же время Argo CD в аналогичных тестах потреблял до 21 ГБ. И это притом что Sveltos работал с одной репликой.

Вот результаты тестов Sveltos с увеличением нагрузки:
1 000 приложений (250 кластеров) — около 70 минут (в DRY-режиме с Helm).
1 000 приложений с шардированием — время сократилось примерно до 35 минут.
1 000 приложений в WET-режиме (сгенерированные манифесты) — около 17 минут.
2 000 приложений (500 кластеров) — приблизительно 36–43 минуты.
5 000 приложений (1000 кластеров) — тест остановили примерно на 4 300 приложениях из-за нехватки бюджета. Инфраструктура стоила уже больше 120 000 евро, но Sveltos продолжал работать.
Безусловно, Sveltos гораздо эффективнее. Технически контроллер способен управлять более чем 15 000 кластеров и более чем 75 000 приложений с одного хаба, но такая архитектура нецелесообразна из соображений надежности. А вот комбинация Argo CD и Sveltos — вполне перспективный подход для крупномасштабных сред.
kubara

Начальная настройка kubara — отличная отправная точка, но, когда растет число кластеров и приложений, возникает множество узких мест. Следует пересмотреть ресурсы и архитектуру не только для Argo CD, но и для мониторинга, External Secrets Operator, сетевых контроллеров и других компонентов.
Дело в том, что архитектура важнее тонкой настройки. Попытка заставить один хаб управлять всем приводит к ошибкам OOM-завершения и простою. Решит проблему разделение нагрузки на 5–10 хабов по географическому, организационному или иному принципу.
Что это значит на практике
Так как конечная цель — не просто создать 15 000 кластеров, а сделать их работу безопасной и предсказуемой, имеет смысл проектировать систему на основе 5–10 хабов. Их можно сгруппировать по бизнес-юнитам, регионам или этапам жизненного цикла. Это снизит риски, упростит операции и оставит пространство для роста.
Что важно помнить:
Объекты — главный враг масштаба. Их количество имеет большее значение, чем число кластеров или приложений.
У тонкой настройки есть пределы. Если вы уперлись в архитектурный потолок, она не поможет.
Гибридные подходы работают. Использовать Argo CD для платформы и Sveltos для приложений — разумно при масштабировании.

