Перейти к содержанию
  1. Статьи/

Production-кластер на трех Raspberry Pi 5

·1547 слов·8 минут

Как я сэкономил 1 млн рублей и перестал зависеть от чужих правил #

444 дня аптайма. Bare-metal Kubernetes в домашней локалке c внешним доступом. Разбор архитектуры, математики и факапов инженера, который просто устал платить “налог на облака”.


Философия: Почему свое железо дает больше спокойствия, чем AWS #

В 2026 году облачные провайдеры и SaaS-подписки превратились в “налог на дыхание” для разработчиков. Каждый месяц — billing alert, каждый квартал — повышение цен, каждое геополитическое событие — риск блокировки аккаунта. А еще не забудьте подписки на LLM, если у вас нет 12GB видеопамяти.

Я построил production-кластер на трех Raspberry Pi 5 в домашней локалке. И вот парадокс: физический сервер в шкафу вызывает у меня меньше стресса, чем SLA корпорации, особенно после начала затягивания Яндексом и ко - удавки на шее в виде ограничений доступа к данным.

Почему? Потому что контроль. Я знаю, где лежит каждый бит моих данных. Я не завишу от чужих правил, чужих API rate limits и чужих “санкционных списков”.

Час у психолога стоит 5 000 ₽. Час у психиатра — 7 000 ₽. Если self-hosted инфраструктура экономит мне хотя бы пару визитов к специалисту в месяц (потому что я не параною о блокировках), это уже +150 000 ₽ за два года чисто на психологическом комфорте.

Это не про экономию. Это про цифровой суверенитет.


Анатомия сетапа: Почему RPi 5 и ARM? #

Когда я начинал проектировать кластер, встал выбор: б/у корпоративные микро-ПК (Dell Micro / Lenovo Tiny) или Raspberry Pi 5 с NVMe.

Выбрал RPi 5. Причина — энергоэффективность.

Даже б/у мини-ПК потребляют 30-50 Вт каждый. Три Raspberry Pi 5 под нагрузкой едят 70 Вт на весь кластер. За 24 месяца это разница в ~20 000 ₽ только на электричестве.

flowchart TB subgraph Cluster["Bare-Metal K3s Cluster (3× RPi 5)"] direction TB subgraph Perimeter["Периметр"] MetalLB["MetalLB
192.168.0.192-196"] Ingress["Ingress Nginx
+ Cert-Manager"] end subgraph Storage["Распределенный Storage"] Longhorn["Longhorn
3-way replication
on NVMe"] end subgraph Data["Data Layer"] CNPG["CloudNativePG
PostgreSQL + Replica"] Valkey["Valkey
Redis Master/Replicas"] end subgraph Apps["Business Apps"] Gitea["Gitea
(Self-hosted GitHub)"] Nextcloud["Nextcloud
(Private Cloud)"] end subgraph Obs["Observability"] Prom["Prometheus"] Graf["Grafana"] end end Client["Клиенты / CI"] --> Perimeter Perimeter --> Apps Apps --> Data Data --> Storage Prom --> Cluster Graf --> Prom

Архитектурные решения:

  • Longhorn — распределенный сторейдж с 3-way репликацией на NVMe. Если одна нода умрет, данные живы.
  • CloudNativePG — Kubernetes-оператор для PostgreSQL с автоматической репликацией и бэкапами.
  • MetalLB — LoadBalancer для bare-metal, пробрасывает внешние IP в локалку.
  • Ingress Nginx + Cert-Manager — автоматические Let’s Encrypt сертификаты.

Подводные камни ARM:

Не все Docker-образы имеют ARM64-версии. Пришлось искать альтернативы или пересобирать образы. Но для стандартного стека (Postgres, Redis, Gitea, Nextcloud) проблем не возникло — все крупные проекты давно поддерживают ARM.


Инцидент с Bitnami: Как геополитика сломала мне базу #

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

Я начинал с Helm-чартов Bitnami — удобные, готовые решения для PostgreSQL, Redis и других сервисов. Все работало стабильно.

Пока не пришел день обновления.

Я запустил helm upgrade, и… база просто не поднялась. Логи показывали ошибки при попытке скачать образы. Оказалось, Bitnami ввел геоблокировки для российских IP. Мои серверы физически не могли скачать Docker-образы с их registry.

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

Решение: Переход на CloudNativePG — нативный Kubernetes-оператор, написанный на Go. Образы хостятся на Docker Hub и GitHub Container Registry, которые (пока) не блокируют РФ. Оператор сам управляет репликацией, бэкапами, failover’ом.

Вывод: Если ваша инфраструктура зависит от проприетарных Helm-чартов или managed-сервисов одного вендора — вы не владеете своей инфраструктурой. Вы ее арендуете.


Математика выгоды: TCO за 24 месяца #

Давайте посчитаем до копейки, сколько стоит мой кластер.

Затраты (CapEx + OpEx):

  • Железо (3× RPi 5 + NVMe): 32 000 ₽
  • Электричество (70 Вт × 24 мес × 720 ч = 1 209,6 кВт⋅ч): ~8 900 ₽
  • Домены + MinIO/S3 для бэкапов: ~3 000 ₽
  • ИТОГО: 44 000 ₽ ($420)

Стоимость на человека:

Инфраструктурой пользуется вся семья (4 человека): Nextcloud для файлов, Gitea для кода, почтовый сервер, мессенджер. Делим 44 000 ₽ на 4 = 11 000 ₽ на человека за 2 года, или 458 ₽/мес.

Дешевле, чем одна подписка на Spotify.

Сколько я сэкономил:

  • Прямая экономия на Яндекс.Облаке: 10 176 ₽ (за пользователя)
  • Если бы использовал Managed AWS/Azure: Аналогичный стек (3 инстанса, managed PostgreSQL с репликацией, 500GB блочного хранилища, managed Redis) стоит минимум $400/мес. За 24 месяца = $9 600 (~1 000 000 ₽).
%%{init: { 'theme': 'base', 'themeVariables': { 'primaryColor': '#2563eb', 'primaryTextColor': '#1a1a1a', 'primaryBorderColor': '#1e40af', 'lineColor': '#1a1a1a', 'secondaryColor': '#dc2626', 'tertiaryColor': '#16a34a', 'xyChart': { 'titleColor': '#1a1a1a', 'xAxisTitleColor': '#1a1a1a', 'xAxisLabelColor': '#1a1a1a', 'xAxisLineColor': '#1a1a1a', 'xAxisTickColor': '#1a1a1a', 'yAxisTitleColor': '#1a1a1a', 'yAxisLabelColor': '#1a1a1a', 'yAxisLineColor': '#1a1a1a', 'yAxisTickColor': '#1a1a1a', 'plotColorPalette': '#2563eb, #dc2626, #16a34a, #ea580c' } } }}%% xychart-beta title "TCO за 24 месяца (₽)" x-axis ["Bare-Metal RPi", "Яндекс.Облако", "Managed AWS/Azure", "Психолог (антистресс)"] y-axis "Затраты (₽)" 0 --> 1200000 bar [44000, 50000, 1000000, 150000]

ROI (окупаемость):

  • Если сравнивать с Яндекс.Облаком — окупилось на 10-й месяц.
  • Если сравнивать с AWS/Azure — окупилось на 2-й месяц.
  • Дальше — чистая прибыль для бизнеса. В моем случае — экономия на нервах.

Fallback на случай апокалипсиса #

Когда все мессенджеры откажут (а они откажут — вопрос времени), у семьи останется связь:

  • Почтовый сервер — внешний, работает даже если локальный кластер упал. Аварийный канал для критических сообщений.
  • Talk в Nextcloud — self-hosted мессенджер с видео/аудио звонками. Работает внутри кластера, не зависит от Telegram/WhatsApp.
  • Nextcloud — 500GB семейного архива: документы, фотографии, резервные копии. Если облако забанят — всё останется у нас.

Это не паранойя. Это стратегия 3-2-1 в действии: 3 копии данных, 2 разных носителя, 1 копия оффсайт (MinIO на другом конце Москвы).

Когда WhatsApp (который теперь запрещен) упал на 6 часов в 2021 году, миллионы людей потеряли связь. Моя семья продолжала общаться через Talk. Когда Telegram заблокируют (а это вопрос геополитики, не технологий, простите РКН, не могу этого замалчивать) — у нас останется почта и Nextcloud.

Цена спокойствия? 458 ₽/мес на человека. Дешевле, чем чашка кофе. И ключи от ваших данных, в ваших собственных руках.

“1 час в месяц”: Как это работает #

Многие думают, что self-hosted = постоянная возня с серверами. На практике я трачу около 1 часа в месяц на поддержку всего кластера.

Стек автоматизации:

  • Ansible — для обновления самого железа (ОС, пакеты, K3s).
  • Helm — для деплоя приложений. Правлю манифесты, запускаю helm upgrade.
  • GitOps (в планах) — сейчас тестирую Flux/ArgoCD, чтобы все изменения автоматически применялись из Git-репозитория.

Типовой процесс обновления:

  1. Запускаю Ansible-плейбук для обновления K3s на всех нодах (rolling update).
  2. Проверяю kubectl get nodes — все в статусе Ready.
  3. Обновляю Helm-чарты приложений (Nextcloud, Gitea и т.д.).
  4. Смотрю в Grafana — метрики в норме, ошибок нет.
  5. Готово.

Как коллеги отреагировали на переезд:

Никак. Для разработчиков, которые со мной работают, изменился только origin/main в Git — теперь это мой Gitea, а не GitHub. CI/CD пайплайны работают так же, пулл-реквесты создаются так же. Просто теперь все данные лежат на моем железе, а не в дата-центре Microsoft.


Disaster Recovery: MinIO на другом конце Москвы #

Что будет, если завтра в доме пожар? Или отключат электричество на неделю?

У меня есть план: стратегия 3-2-1 (3 копии данных, 2 разных носителя, 1 копия оффсайт).

Как это работает:

  1. Longhorn делает снапшоты PVC раз в месяц.
  2. CloudNativePG делает бэкапы БД (WAL-архивы) непрерывно.
  3. Все бэкапы отправляются на MinIO, который стоит в другом доме на другом конце Москвы.
  4. Связь между домами — WireGuard-туннель, который включается только в момент репликации (для безопасности).
sequenceDiagram participant Cluster as Home K3s Cluster participant LB as Longhorn Backup participant CNPG as CNPG Backup participant WG as WireGuard Tunnel participant MinIO as MinIO (другой конец Москвы) participant DR as DR Site (Аренда) Cluster->>LB: Снапшот Longhorn (ежемесячно) Cluster->>CNPG: Бэкап БД (WAL непрерывно) LB->>WG: Отправка через WireGuard WG->>MinIO: Доставка снапшотов CNPG->>WG: Отправка через WireGuard WG->>MinIO: Доставка WAL-архивов Note over Cluster,DR: 🚨 Инцидент: Пожар в доме DR->>MinIO: Запрос бэкапов через WireGuard MinIO->>DR: Снапшоты + WAL-архивы DR->>DR: Разворачивание K3s (Ansible) DR->>DR: Восстановление Longhorn из снапшотов DR->>DR: Восстановление CNPG из WAL Note over DR: ✅ RTO = 4 часа. Бизнес работает.

RTO (Recovery Time Objective) = 4 часа.

За это время я:

  1. Арендую виртуальные серверы в любом ДЦ.
  2. Разворачиваю K3s через Ansible.
  3. Восстанавливаю Longhorn из снапшотов.
  4. Восстанавливаю PostgreSQL из WAL-архивов.
  5. Бизнес снова работает. (Или не бизнес - а что-то приватное)

Это не теория. Это протестированный план.


Бонус: Умный дом на том же кластере #

На этом же кластере крутится и умный дом:

  • MQTT-брокер (Mosquitto) для сбора метрик с датчиков температуры, влажности, движения.
  • InfluxDB для хранения time-series данных с интервалом 1 минута.
  • Grafana для визуализации — дашборды показывают потребление электричества, температуру в комнатах, статус устройств.

Всё это работает на тех же трёх RPi 5, не мешая production-сервисам. Resource quotas в Kubernetes гарантируют, что умный дом не “съест” ресурсы у Gitea или Nextcloud.

Но это тема для отдельной статьи. Подписывайтесь на канал, расскажу подробнее.


Заключение #

Self-hosted инфраструктура в 2026 году — это не про сисадминство и не про экономию. Это про свободу инженера и безопасность бизнеса.

Моя лаборатория на трех Raspberry Pi 5 выросла в полноценный production-кластер с 444 днями аптайма. Я трачу 1 час в месяц на поддержку, не завишу от чужих правил и знаю, что мои данные под контролем.

Если вам интересно посмотреть на реальные Ansible-плейбуки, манифесты CNPG и Longhorn, или обсудить архитектуру — залетайте в мой Telegram-канал. Там я выложу ссылки на инфраструктуру и гайд, и продолжу делиться кейсами, помимо этой площадки.

P.S. CD/CI пайплайны сейчас как раз тестирую при развороте этого блога. Если интересно, как я настрою автоматический деплой из Git — дайте знать в комментариях.

Автор
lissnikk
DevOps-инженер. Bare-metal энтузиаст. Строю кластеры с HA