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-проектов - если у вас несколько отечественных провайдеров и нужна единая аналитика расходов, базовую архитектуру мы уже отработали.