Создание NaaS-платформы: оркестрация нод, K8s, биллинг

Запуск блокчейн-ноды руками — простая задача для одной ноды. Когда их становится сотня, это уже инфраструктурный проект с K8s, StatefulSet, snapshot bootstrap и биллингом. Мы занимаемся Node-as-a-Service разработкой под ключ и построили не одну такую платформу: от выбора клиентов (Ethereum, Solana,

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1450
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1308
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1003
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1269
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    717
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1008

Запуск блокчейн-ноды руками — простая задача для одной ноды. Когда их становится сотня, это уже инфраструктурный проект с K8s, StatefulSet, snapshot bootstrap и биллингом. Мы занимаемся Node-as-a-Service разработкой под ключ и построили не одну такую платформу: от выбора клиентов (Ethereum, Solana, BNB) до production-grade API Gateway с rate limiting и compute units. Из нашей практики: один из клиентов Fortune 500 заменил ручное управление нодами на NaaS — затраты на инфраструктуру снизились на 40%, что принесло экономию $15 000 в месяц, а годовая экономия превысила $180 000. Свяжитесь с нами — оценим ваш проект за 2 дня.

Как работает Node-as-a-Service платформа?

NaaS-платформа предоставляет клиентам единый RPC-эндпоинт, за которым скрыта оркестровка десятков и сотен нод. Каждая нода запускается в K8s как StatefulSet с собственным PersistentVolumeClaim. Для бюджетного сегмента ноды разделяются между клиентами (shared), для требовательных — выделяются целиком (dedicated) или кластерами с балансировкой (node clusters).

Почему стандартный Kubernetes не подходит для блокчейн-нод?

Обычный Deployment в K8s не учитывает специфику блокчейн-нод, поэтому Kubernetes для блокчейн-инфраструктуры требует использования StatefulSet. Ноды требуют stateful-хранилища (сотни гигабайт), фиксированных P2P-портов и защиты от перезапусков без потери синхронизации. Используем StatefulSet с PVC и headless service — это гарантирует, что при сбое под не пересоздастся на другом узле, а данные останутся привязанными к storage.

Пример конфигурации StatefulSet для Ethereum ноды:

apiVersion: apps/v1 kind: StatefulSet metadata: name: ethereum-geth spec: serviceName: "geth" replicas: 1 selector: matchLabels: app: ethereum-geth template: spec: containers: - name: geth image: ethereum/client-go:v1.13.14 args: ["--datadir=/data", "--http", "--http.addr=0.0.0.0", "--http.vhosts=*", "--http.api=eth,net,web3,txpool", "--ws", "--ws.addr=0.0.0.0", "--maxpeers=50", "--cache=4096"] ports: - containerPort: 8545 - containerPort: 8546 - containerPort: 30303 protocol: TCP - containerPort: 30303 protocol: UDP volumeMounts: - name: data mountPath: /data resources: requests: memory: "16Gi" cpu: "4" limits: memory: "32Gi" cpu: "8" volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] storageClassName: "fast-nvme" resources: requests: storage: 3Ti 

Проблемы, которые решаем

Snapshot bootstrapping

Синхронизация Ethereum mainnet с нуля (snap sync) занимает 12–24 часа, а архивная нода (archive node) — до 5 недель. Для NaaS это критично: клиент платит с первой минуты. Мы используем snapshot distribution: каждые 7 дней создаём актуальную копию базы данных, инкрементальные дифы — ежедневно. Bootstrap ноды из snapshot занимает 10–15 минут.

Сравнение режимов синхронизации нод Ethereum:

Режим Размер данных Время синхронизации RPC-доступность
Snap sync ~500 GB 12–24 ч Full
Full sync ~1.2 TB 3–5 дней Архив
Archive (архивная нода) ~15 TB 5–7 недель Архив + трассировка

Изоляция клиентов

В одной платформе могут работать как стартапы с free tier, так и enterprise с гарантиями SLA. Разделяем ресурсы через три модели мультитенантности, каждая со своим подходом к биллингу блокчейн-инфраструктуры.

Модель Изоляция Типичный кейс Пример ценообразования
Shared Низкая (один процесс) Free tier, тестовые проекты Оплата за CU
Dedicated Высокая (выделенная нода) Production, стабильный RPC Фиксированная ставка
Node cluster Максимальная (реплики + LB) Enterprise, HA Индивидуальный расчёт

Для биллинга блокчейн-инфраструктуры используем compute units — каждый RPC-метод имеет вес в CU: eth_blockNumber — 10 CU, eth_call — 26 CU, trace_replayTransaction — 75 CU.

Как мы это делаем: стек и кейсы

RPC-прокси с интеллектуальной маршрутизацией

Кастомный прокси на Go фильтрует опасные методы (например, debug_* только для premium), распределяет запросы между archive и full нодами и кеширует ответы (TTL — 1 секунда для eth_blockNumber). Rate limiting реализован через Redis sliding window — он точнее token bucket для RPC-нагрузок.

// Пример RPC прокси с routing logic package proxy type RPCRouter struct { archivePool NodePool fullNodePool NodePool cacheClient *redis.Client } var archiveMethods = map[string]bool{ "eth_getBalance": true, "eth_call": true, "eth_getStorageAt": true, "trace_call": true, "trace_replayTransaction": true, } func (r *RPCRouter) Route(req *RPCRequest) NodePool { if archiveMethods[req.Method] { if req.RequiresHistoricalBlock() { return r.archivePool } } return r.fullNodePool } func (r *RPCRouter) Handle(w http.ResponseWriter, req *RPCRequest, apiKey string) { cacheKey := req.CacheKey() if cached, err := r.cacheClient.Get(ctx, cacheKey).Bytes(); err == nil { w.Write(cached) return } pool := r.Route(req) node := pool.GetHealthyNode() resp := node.Forward(req) if req.IsCacheable() { r.cacheClient.Set(ctx, cacheKey, resp, req.CacheTTL()) } r.billing.RecordRequest(apiKey, req.Method, resp.ComputeUnits()) w.Write(resp) } 

Health checking с учётом состояния ноды

Ping не гарантирует, что нода обрабатывает запросы. Используем проверку синхронизации: если SyncProgress не nil или блок старше 2 минут — нода исключается из пула. Health проверки запускаем каждые 15 секунд.

type NodeHealthChecker struct { client *ethclient.Client } func (h *NodeHealthChecker) IsHealthy(ctx context.Context) (bool, error) { syncing, err := h.client.SyncProgress(ctx) if err != nil { return false, err } if syncing != nil { return false, fmt.Errorf("node is syncing: %d/%d", syncing.CurrentBlock, syncing.HighestBlock) } header, err := h.client.HeaderByNumber(ctx, nil) if err != nil { return false, err } blockAge := time.Since(time.Unix(int64(header.Time), 0)) if blockAge > 2*time.Minute { return false, fmt.Errorf("block too old: %v", blockAge) } return true, nil } 

Rate limiting на Redis

func (rl *RateLimiter) Allow(ctx context.Context, apiKey string, rps int) (bool, error) { now := time.Now().UnixMilli() window := int64(1000) pipe := rl.redis.Pipeline() pipe.ZRemRangeByScore(ctx, apiKey, "0", strconv.FormatInt(now-window, 10)) pipe.ZCard(ctx, apiKey) pipe.ZAdd(ctx, apiKey, redis.Z{Score: float64(now), Member: now}) pipe.Expire(ctx, apiKey, 2*time.Second) results, err := pipe.Exec(ctx) count := results[1].(*redis.IntCmd).Val() return count < int64(rps), nil } 

Биллинг на основе compute units

CREATE TABLE api_keys ( id UUID PRIMARY KEY, customer_id UUID NOT NULL, key_hash BYTEA NOT NULL, tier VARCHAR(20) NOT NULL, rate_limit_rps INTEGER NOT NULL, monthly_cu_limit BIGINT, node_type VARCHAR(20) NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE usage_records ( id BIGSERIAL PRIMARY KEY, api_key_id UUID NOT NULL REFERENCES api_keys(id), method VARCHAR(100) NOT NULL, chain_id INTEGER NOT NULL, compute_units INTEGER NOT NULL, response_time_ms INTEGER, recorded_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_usage_billing ON usage_records (api_key_id, recorded_at); 

Как мы строим NaaS-платформу: этапы и сроки

  1. Аналитика и аудит (1–2 недели): определяем целевые блокчейны, модель мультитенантности, требования к SLA и региону.
  2. Проектирование архитектуры (1–2 недели): выбираем клиенты (Geth, Reth, Erigon, Solana Agave), готовим схемы K8s, API Gateway, биллинга.
  3. Реализация core infrastructure (4–6 недель): StatefulSet templates, snapshot bootstrap pipeline, health checker.
  4. Разработка API Gateway и биллинга (6–8 недель): RPC прокси, rate limiting, compute units, интеграция Stripe.
  5. Observability и self-service portal (6–9 недель): Prometheus + Grafana, alerting, веб-интерфейс для управления ключами и просмотра метрик.
  6. Тестирование и деплой (2–3 недели): нагрузочное тестирование, security audit, запуск в production.

Итого: от 16 до 23 недель до production-ready платформы. Если вы хотите ускорить этап, свяжитесь с нашими инженерами — мы предложим подходящий темп.

Что входит в работу

  • Документация: архитектурная схема, инструкции по добавлению новых цепей, runbook для on-call.
  • Доступы: репозиторий с шаблонами, CI/CD pipeline, мониторинг (Grafana dashboards).
  • Обучение: 2–3 сессии для вашей команды (DevOps и backend).
  • Поддержка: 3 месяца после запуска (багфикс, консультации).

Типичные ошибки при разработке NaaS

  • Использование hostNetwork для P2P портов — теряется изоляция. Лучше NodePort или LoadBalancer с фиксированным портом на ноду.
  • Отсутствие кеширования частых RPC-методов (eth_chainId, eth_blockNumber) — увеличивает нагрузку на ноду и биллинг.
  • Health check только по TCP — нода может быть живой, но отставать от сети на сотни блоков.

Если вы столкнулись с подобными проблемами или хотите избежать их, закажите разработку NaaS-платформы у нас. Подробнее о StatefulSet. Мы накопили 10+ лет опыта в блокчейн-инфраструктуре и реализовали 50+ проектов, включая платформы для Fortune 500. Свяжитесь с нами — оценим вашу задачу и предложим оптимальное решение.