ADG Оставить заявку
Блог Управление и процессы 5 мин чтения

FinOps в отечественном облаке: биллинг через API, ClickHouse и дашборды по командам

Внедряем FinOps-практики для Selectel, VK Cloud, Яндекс Cloud: выгружаем биллинг через API, грузим в ClickHouse, строим дашборды. Где метрики расходятся с AWS-моделью.

Контекст момента

FinOps-практики адаптируются к отечественным облачным провайдерам: Selectel, VK Cloud, Яндекс Cloud

Когда несколько лет назад облачный биллинг в России был «AWS + пара сервисов для галочки», FinOps-практики переезжали сюда без особых адаптаций: качаешь Cost Explorer, грузишь в Athena или BigQuery, строишь дашборды. Сейчас у нас три-четыре крупных отечественных провайдера с принципиально разными API, несовместимыми моделями учёта ресурсов и биллингом, который местами ведёт себя неожиданно. Готовых инструментов на этот случай практически нет, поэтому пришлось собирать пайплайн самостоятельно.

Результат - работающий, но честный: примерно месяц инженерного времени и несколько специфических мест, которые сразу не очевидны.

Что хотели получить

Задача типичная для команды с несколькими продуктами в облаке: понять, кто сколько тратит, отловить аномалии до конца месяца, не ждать итоговый счёт как сюрприз. Дополнительное требование - аллокация по командам: у нас несколько продуктовых команд в одном облачном аккаунте, и «общий счёт» никого не устраивает.

В AWS для этого есть Cost Allocation Tags, Cost Explorer API, и целая экосистема инструментов. В отечественных облаках картина другая.

Как устроен биллинг у провайдеров

Яндекс Cloud - самый близкий к AWS по структуре. Есть биллинг API (billing.api.cloud.yandex.net), через который можно получить расходы в разбивке по сервисам и ресурсам за произвольный период. Метрики отдаются в JSON с достаточно понятной схемой: сервис, продукт, количество единиц, стоимость в рублях. Есть аналог Cost Allocation Labels - через теги ресурсов и проектов. Задержка биллинговых данных - 1-2 дня, что приемлемо для ежедневного мониторинга.

Нюанс: часть сервисов (managed-базы данных, некоторые networking-компоненты) выставляет расходы агрегировано за сутки, часть - с более высокой детализацией. Это нужно учитывать при построении временных рядов - иначе получаются «горбы» на графиках.

VK Cloud - API биллинга есть, документация существует, но полнота его на практике неравномерна. Основные compute-расходы выгружаются нормально. Object storage, сеть, часть managed-сервисов - периодически нет детализации ниже уровня «общий итог за месяц». Мы это обошли через комбинацию биллинг API + прямые метрики использования через Prometheus-экспортёры, но это костыль, а не архитектура.

Selectel - биллинг API сделан через личный кабинет: есть endpoint для выгрузки расходов по проектам, есть разбивка по категориям услуг. По детализации скромнее, чем Яндекс Cloud, но для базовых задач аллокации хватает. Отдельная история - у Selectel модель «проектов» является основным механизмом изоляции, и если у вас несколько команд в одном проекте, атрибуция расходов внутри проекта требует дополнительных усилий.

Пайплайн: API -> ClickHouse

Схема, которую мы реализовали:

Billing API (x3 провайдера)
        |
  Python-коллекторы (по одному на провайдера)
        |
  Нормализация в единую схему
        |
  ClickHouse (таблицы cloud_costs)
        |
  Grafana / Metabase

Коллекторы запускаются по cron ежедневно, тянут данные за предыдущие два дня с перекрытием (на случай догоняющих транзакций) и делают вставку через INSERT ... ON DUPLICATE KEY - точнее, через ReplacingMergeTree в ClickHouse, который дедуплицирует записи по составному ключу (provider, date, resource_id, billing_item).

Единая схема выглядит примерно так:

CREATE TABLE cloud_costs (
    provider       LowCardinality(String),
    date           Date,
    service        LowCardinality(String),
    billing_item   LowCardinality(String),
    resource_id    String,
    resource_name  String,
    team_label     LowCardinality(String),
    cost_rub       Decimal(18, 4),
    units          Float64,
    unit_type      LowCardinality(String),
    tags           Map(String, String)
) ENGINE = ReplacingMergeTree()
PARTITION BY toYYYYMM(date)
ORDER BY (provider, date, resource_id, billing_item);

Поле team_label - основа аллокации по командам. Заполняется из тегов ресурсов, которые команды обязаны проставлять при создании. Где теги не проставлены - попадает в «неаллоцировано», что само по себе является метрикой дисциплины.

Где метрики расходятся с AWS-моделью

Это самая содержательная часть, потому что именно здесь ломаются ожидания.

Единица биллинга - не всегда то, что кажется. AWS выставляет за vCPU-час, GB-час трафика, запросы. Отечественные провайдеры часто выставляют за «конфигурацию» - вы арендуете пресет типа s3-c4-m8, и биллинг идёт за инстанс в целом, а не за его компоненты. Это затрудняет сравнение эффективности использования: вы не можете легко посчитать «мы использовали 30% оплаченных CPU», потому что единица другая.

Reserved/commitment-скидки не всегда видны в детализации. В AWS reserved instances и savings plans видны в Cost Explorer как отдельные строки с amortized cost. У части отечественных провайдеров скидки применяются на уровне выставления счёта и в детализированных данных уже не выделяются. Вы видите сниженную цену, но не видите, за счёт чего. Это мешает корректному сравнению month-over-month.

Задержка данных непостоянна. Если AWS гарантирует появление данных в Cost Explorer с задержкой до 24 часов, у отечественных провайдеров это «до 2-3 дней», причём с вариативностью. Мы несколько раз сталкивались с тем, что данные за конкретный день «доезжали» с задержкой 4-5 дней. Для ежедневных дашборде это значит: смотришь на позавчера, а не на вчера.

Теги - это дисциплина, а не инфраструктура. В AWS есть SCP-политики, которые запрещают создавать ресурсы без обязательных тегов. В отечественных облаках такого механизма нет или он слабее. Значит, полнота аллокации по командам напрямую зависит от культуры в команде. У нас первый месяц «неаллоцировано» составляло около трети расходов - серьёзная проблема для осмысленных дашбордов.

Что получилось на выходе

Дашборды работают. Команды видят свои расходы в разбивке по провайдерам, сервисам и динамику неделя к неделе. Аномалии - резкий рост расходов по конкретному ресурсу - ловим через алертинг в Grafana с порогом «отклонение более 40% от среднего за последние 14 дней».

Полноту аллокации подняли с ~65% до ~90% за два месяца - просто показывая командам, сколько у них «неаллоцировано». Работает лучше, чем административные требования.

Что не решили: нет инструмента для rightsizing-рекомендаций, аналогичного AWS Compute Optimizer. Здесь либо строить свою аналитику на метриках использования, либо мириться с отсутствием. Пока у нас - периодический ручной анализ для крупнейших ресурсов.

Пайплайн поддерживаем в рамках DWH/BI-проектов - если у вас несколько отечественных провайдеров и нужна единая аналитика расходов, базовую архитектуру мы уже отработали.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.