В статье расскажу про serverless computing — «бессерверные вычисления»: зачем это нужно, какие есть Open Source-реализации self-hosted-фреймворков с поддержкой Kubernetes, об их возможностях и ограничениях. Еще поделюсь опытом нашего клиента, который использует одно из таких решений (OpenFaaS). Идея обзора как раз и возникла в процессе изучения этого кейса.
Кратко про serverless computing
Serverless-архитектура — стратегия, ориентированная на дробление продукта на мелкие части и их исполнение в инфраструктуре в качестве самостоятельных единиц: функций. Отсюда и термин FaaS, function-as-a-service. Сторонники serverless-подхода рассматривают его как следующую эволюционную ступень разработки: монолит → микросервисы → функции.
Самый простой пример того, что может легко переехать в serverless, — REST API. Он stateless, то есть зависит только от клиентских данных в запросе. Для расширения функционала API достаточно создать дополнительные мини-приложения (функции) для каждой точки входа и поместить их в некую среду, которая умеет обрабатывать клиентские запросы. В итоге формируется единая система, которая легко масштабируется под нагрузкой и достаточно просто модернизируется.
Из плюсов FaaS-сервисов — простота запуска, динамическое масштабирование worker’ов, которые обрабатывают клиентские запросы, возможность платить только за потребленные ресурсы.
Есть и минусы:
Холодный запуск. При изменении нагрузки требуется некоторое время для запуска или увеличения числа worker’ов.
Stateless only, т.е. невозможность хранить состояние конкретной функции, а это подходит не для всех задач.
Vendor lock и особенности реализации для конкретного облака подразумевают функциональные и — потенциально — финансовые ограничения. К первым можно отнести, например, ограниченное время исполнения функции.
Первопроходцы
Пионером в serverless стала AWS, которая в 2014 году представила платформу Lambda. Несмотря на некогда ограниченный стек языков, Lambda не просто доказала жизнеспособность подхода, но и стала лидером направления. Согласно отчету CNCF State of Cloud Native development, по состоянию на первый квартал 2021-го ее используют 54% респондентов.
В 2016 году Microsoft представила свое решение — Azure Functions (35% респондентов, по данным того же опроса). В 2017-м появился Google Cloud Functions (41% респондентов). Сейчас AWS Lambda, Google Cloud Functions и Azure Functions — это зрелые решения категории production-ready, которые активно используются бизнесом.
Естественно, появились и свободные альтернативы — self-hosted serverless frameworks. Им и посвящен этот обзор.
Self-hosted-решения
Появление serverless-фреймворков, которые можно размещать на произвольной инфраструктуре, удачно совпало с ростом популярности сначала Docker, а потом и Kubernetes. Бум пришелся на 2016—2018 годы. Например, в 2016-м появились Iron Functions, Funktions и OpenFaaS; в 2017-м — Kubeless; в 2018-м — Knative и OpenWhisk.
Self-hosted-фреймворки призваны решить некоторые из минусов hosted-решений вроде vendor lock’а и ограничений на используемые языки программирования. Их также можно использовать на своем «железе».
Технически логика работы self-hosted-фреймворка предполагает, что функция собирается в Docker-образ, после чего она работает на платформе оркестрации в виде контейнера. Это дает универсальность, но в то же время добавляет некоторые ограничения. Например, нивелируется основная идея serverless — быстрое масштабирование: у пользователя всегда должны быть наготове ресурсы, которые можно отдать функциям. Также многие отмечают усложнение разработки и обслуживания по сравнению с микросервисной архитектурой.
Проверку временем прошли не все self-hosted-решения:
Kubeless, Iron Functions, Space Cloud, OpenLambda, Funktion и Fn Project «мертвы» или близки к этому состоянию.
OpenWhisk скорее жив, однако не радовал релизами с ноября 2020-го. Фреймворк мало упоминается, особенно в контексте self-hosted-решения для Kubernetes (его используют 3% среди пользователей serverless по данным отчета CNCF за 2020-й год).
OpenFaaS жив и используется сообществом (10% пользователей).
Knative активно развивается и в целом кажется, что чувствует себя лучше всех (27% пользователей). В ноябре 2021 г. вышла версия 1.0.
Fission регулярно выпускает релизы (последний был 29 декабря 2021 г.), но используется не очень активно (2% пользователей).
Проект Nuclio имеет Open Source-версию, однако в ней нет возможности auto-scaling вообще и scaling в ноль в частности, поэтому в сравнении не участвует.
Посмотрим внимательнее на актуальные фреймворки.
OpenFaaS — «мальчик», который выжил
Один из самых старых проектов, который практически полностью развивается на энтузиазме его создателя — Alex Ellis. Об истории создания фреймворка можно узнать из нашей переводной статьи.
Помимо бесплатной версии OpenFaaS его автор предлагает премиум-подписку и профессиональную поддержку. За прошедшие пять лет проект набрал более 21 000 звезд на GitHub. Интенсивность его разработки несколько снизилась, но она по-прежнему продолжается.
Управляется OpenFaaS через собственную утилиту faas-cli и через веб-интерфейс. С помощью утилиты можно управлять самим OpenFaaS, а также работать с репозиториями функций, создавая-изменяя свои или используя общедоступные.
Внутри Kubernetes-кластера OpenFaaS работает благодаря faas-netes. Это OpenFaaS-провайдер, который обеспечивает взаимодействие OpenFaaS и непосредственно кластера. Также faas-netes может работать в режиме оператора, обслуживающего собственные CRD — Functions. Если режим оператора не включен, OpenFaaS оперирует стандартными объектами, такими как Service и Deployment.
Возможности и преимущества:
Поддерживает разные языки программирования. Можно запускать бинарники (например,
sha512sum
) — главное, чтобы они использовали стандартные stdin/stdout.Автомасштабирование — для этого используется Prometheus (сбор метрик) и Alertmanager (который обеспечивает автомасштабирование на основе собранных метрик). Умеет автомасштабировать в ноль (но с оговорками — об этом ниже).
Работает с Docker Swarm и Kubernetes.
Поддерживает Ingress на входе.
Ограничения:
Автомасштабирование: необходимо держать на постоянной основе хотя бы один контейнер с каждой функцией либо ждать запуска контейнера при первом обращении (со всеми вытекающими последствиями).
Не умеет ограничивать ресурсы, потребляемые функциями.
В списке пользователей OpenFaaS есть в том числе известные компании — например, VMware и DigitalOcean.
Knative — перспективный новичок
Изначально Knative запустили в Google при поддержке IBM, Red Hat, VMware и SAP. С октября 2020 года Knative находится в свободном плавании и управляется сообществом. Проект активно развивается: в его разработке участвуют 600+ человек.
Похоже, что в Knative все больше верят крупные вендоры. Red Hat включила поддержку Knative в «коробку» с OpenShift. В ноябре 2021 года Google запросила CNCF добавить Knative в список проектов инкубатора CNCF, но решение до сих пор не принято (есть интересная статья про подоплеку этого дела).
Управляется Knative через консольный клиент kn. С его помощью можно взаимодействовать с CRD проекта: Serving (постоянно живущими сервисами) и Eventing (работающими по запросу).
Внутри кластера фреймворк поддерживается силами Knative operator, который использует Serving и Eventing, чтобы создавать необходимые объекты в Kubernetes — например, Pod’ы.
Возможности и преимущества:
Из коробки полноценно умеет автомасштабировать в ноль. Разработчики утверждают, что практически решили проблему с холодным стартом, функции начинают полноценно работать за 2 с.
Поддерживает разные языки программирования: Node, Java, Python, Ruby, C#, PHP, Go. Есть готовые шаблоны, поэтому можно не возиться с написанием Dockerfile.
На борту есть свой сбор метрик и логов.
Оповещает о событиях в Slack, GitHub и не только.
Умеет ограничивать ресурсы, потребляемые функциями.
Совместим с Google Cloud Run, а значит — возможна простая миграция.
Умеет работать как с постоянно работающими сервисами, так и с событийно-ориентированными.
Ограничения:
Сложная логика автомасштабирования.
Ориентирован на работу только с Kubernetes.
На входе работает с Istio, что может усложнить внедрение. От Istio можно отказаться, однако авторы настоятельно рекомендуют его использовать.
Среди известных пользователей проекта: Puppet, deepc, Outfit7.
OpenWhisk
Фреймворк ранее поддерживала IBM, а теперь — Apache Software Foundation. Аналогично OpenFaaS, проект развивается, но не очень активно. В то же время сама IBM предлагает в своем облаке IBM Cloud Functions, что основывается на наработках проекта OpenWhisk. По данным уже упомянутого отчета CNCF за 2021 год, Functions от IBM выбирают 15 % респондентов, и это почти вдвое больше, чем в 2020-м (8 %).
Работа с OpenWhisk организована через консольный клиент wsk, который управляет необходимыми примитивами Kubernetes.
Возможности и преимущества:
Поддерживает Kubernetes, Docker Swarm и Apache Mesos.
Поддерживает из коробки Go, Java, NodeJS, .NET, PHP, Python, Ruby, Rust, Scala, Swift. Может запускать произвольно собранные контейнеры.
Автомасштабирование.
Сбор метрик и логов.
Из коробки есть REST API.
Интеграция со Slack (через плагин).
Умеет ограничивать ресурсы, потребляемые функциями.
Ограничения:
Аналогично OpenFaaS не пытается решить вопрос холодного старта, хотя автомасштабирование поддерживается.
Для работы в Kubernetes требуется Docker — не понятно, как быть, когда от Docker окончательно откажутся.
Fission
Фреймворк был создан в 2018 году облачным провайдером Platform9, который поддерживает его и по сей день. В GitHub также упоминается, что в его разработке участвуют DigitalOcean и InfraCloud, но я не смог найти его явных упоминаний от них самих. Выглядит так, что сама Platform9 и является крупнейшим пользователем фреймворка. В целом информации по Fission не очень много, что является то ли причиной, то ли следствием малого числа его пользователей.
Фреймворк управляется через одноименную консольную утилиту. Каких-то особенных CRD он не приносит, а оперирует примитивами Kubernetes.
Возможности и преимущества:
Поддерживает из коробки Node.js, Python, Ruby, Go, PHP, Bash. Может запускать произвольно собранные контейнеры.
Автомасштабирование.
Сбор метрик и логов.
Поддерживает WebHooks из коробки.
С помощью нового движка NewDeploy решает проблему холодного старта (обещают до 100ms на запуск).
Ограничения:
Ориентирован на работу только с Kubernetes.
На входе работает с Istio, что может усложнить внедрение.
Автомасштабируется только на основе CPU usage (обещают добавить custom metrics в дальнейшем).
Не умеет ограничивать ресурсы, потребляемые функциями.
Опыт нашего клиента
Среди наших клиентов нашелся всего один, который применяет self-hosted serverless framework. Эта компания специализируется на виртуальных ассистентах и использует OpenFaaS.
OpenFaaS был выбран потому, что он ускоряет развертывание и тем самым облегчает жизнь разработчику. Однако это работает только тогда, когда нужно быстро сделать кусок API, работу с внешним источником, что-нибудь для обращения партнера и т. д.
Переносить же ключевую функциональность в OpenFaaS клиент не планирует, так как не видит в этом смысла и преимуществ.
Из отмеченных неудобств:
авторизация OpenFaaS не умеет разграничивать права, поэтому в некоторых функциях у клиента две авторизации: одна — на входе в OpenFaaS, другая — внутри самой функции.
Несколько раз возникали проблемы из-за невозможности ограничить ресурсы: одна из функций «съедала» всю оперативную память узла.
Резюмируя, наш клиент признался, что использует фреймворк только из-за удобств для разработчиков. Остальные особенности ему неинтересны.
Заключение
На рынке serverless вырисовывается следующая картина:
Serverless-подход сам по себе живет и здравствует, в том числе благодаря CNCF Serverless Working Group. Хотя интересно, что, согласно упомянутому отчету CNCF за 2021 год, количество вовлеченных в serverless разработчиков за период 2020-2021 снизилось с 27 до 24%. Как предполагают авторы отчета, это произошло из-за опасений vendor lock и ограничений FaaS в целом.
Self-hosted-решения либо еще не распробованы, либо так и останутся уделом энтузиастов.
Выводы по рассмотренным фреймворкам:
OpenFaaS и Fission живут за счет энтузиазма своих создателей (одного человека или целой компании соответственно).
OpenWhisk живет скорее по инерции.
Knative живет за счет вклада Google и большей интеграции с K8s. Со временем проект стал интересен крупным вендорам, так что видны его перспективы.
P.S.
Читайте также в нашем блоге:
Akuma
А для НЕ-google-like пользователей есть смысл и реальные примеры использований serverless?
Я вот не могу придумать ситуации, когда оно будет выгоднее чем некая фиксированная машина (пусть даже с запасом мощности на всплески).
ivanovdev
Привет! Вот пример из реально жизни.
Есть сервис, который ставит цифровые подписи на пдф. Подписи начинают ставить ближе к вечеру. Днем нагрузки вообще нет.
Серверлесс помогает в трех ситуация.
Вы не потребляете ресурсов, когда нет нагрузки. То есть нет документов на подпись зачем крутить целый сервис? Учитывая, что многие компании сейчас начинают экономить ресурсы - это несравнимый плюс.
Когда запросов становится очень много, система начинает плодить новые инстансы функции, чтобы справится с запросами. И это все из коробки, ничего не надо самому накручивать.
Удобство для разработчика. Мне как разработчику нужно написать только метод, который получает байтовый массив и еще какие параметры и отдает документ с подписью. А уже на уровне инфраструкруты мы настраиваем откуда нам попадают эти параметры - через http, очередь или файл с диска. То есть я пишу только бизнеслогику, не заморачиваясь маштабированием, подключением к источникам данных и т.д.
Akuma
Я примерно так это и представлял, но интересуют реальные цифры все же, потому что:
Сервис, который ничего не делает и так не потребляет ресурсов, пусть крутится.
"Очень много" - это так много, что все свободные "другие" ресурсы не справятся? А точно? А проверяли? А каждый раз так?
Мне лично нравится работать с со всем стеком целиком, но тут вкусовщина конечно.
Само-собой, в теории, потребление "только вечером" будет дешевле. Но вот на практике, условная дополнительная VDS на bare-metal k8s кластере будет обходиться в несколько раз дешевле, чем реальное облако. Плюс безлимитный трафик.
P.S. Мои наблюдения относятся к "земным" потреблениям. Если у вас миллионный трафик, возможно разница в затратах будет не такая существенная конечно.
Fulborg
Есть плюс в том, что проблемы reliability остаются за кадром и не нуждаются в отдельной обработке приложением.
Это наверное не так актуально для http-функций, но например для функций которые обрабатывают сообщения проходящие из условной очереди - это позволяет не думать о том что подписка на очередь может внезапно оборваться из за проблем с сетью. Или лок на партишен не переосвободится из за рестарта процесса.
С точки зрения функции - ей на вход просто приходит одно сообщение, которое надо обработать, а вся инфраструктура и работа по преобразованию «источник данных => входные параметры» остаётся за кадром.
Можно ли это обеспечить своими силами на голом железе? Можно, однозначно, вопрос только в объёме работы. Retry, DLQ, Throughput limiter. Обо всем этом надо вспомнить и подумать на этапе проектирования/разработки и корректор сделать. А в случае Azure Functions - это все есть из коробки и позволяет сосредоточиться на бизнес-логике.