Статья будет полезна тем, кто использовал свой дата-центр или классический хостинг, но затем столкнулся с миром публичных облачных платформ. Если не продумали все детали при планировании, то проблемы почти неизбежны. Рассккажу, как их избежать.
Что такое публичное облако
Gartner называет публичными облаками Cloud Infrastructure and Platform Service Providers, т. е. компании, которые делают инфраструктурные и платформенные сервисы. Лидеры рынка — Amazon, Google и Microsoft. Есть ещё небольшие международные игроки. В России облачные платформы — Yandex Cloud, VK (в прошлом Mail.ru) Cloud Solutions, SberCloud — начали развиваться относительно недавно.
Компания Intricately изучила основных игроков и покупателей рынка облачных сервисов и сделала вывод, что больше всего денег на облака тратят SaaS-сервисы, медиасервисы и internet-facing-ресурсы. Мы провели в Yandex Cloud небольшое исследование и выяснили, что в России результаты похожи: 50% основных больших игроков — это internet-facing-сервисы, в первую очередь SaaS. И ещё 50% — это аналитические enterprise-приложения, для которых требуется поднимать тяжёлые кластеры баз данных и кластеры Kubernetes.
Облако в первую очередь выбирают, чтобы уменьшить time to market сервисов. Современное микросервисное веб-приложение — это очень много технологий. У вас есть три варианта:
- Поднимать всё самостоятельно на железе — и вы потратите на подготовку инфраструктуры примерно 2/3 времени разработки продукта.
- Взять виртуальные машины — тогда потратите 1/2 времени.
- Выбрать платформенные сервисы — и вы сразу начнёте писать код, который зарабатывает деньги, а потом уже решите, стоит ли разворачивать инфраструктуру самим.
Публичное облако позволяет поднимать инфраструктуру автоматически (вручную, с помощью скриптов, кода, Terraform) и обслуживать её не как традиционные железные серверы, а, например, как код. А благодаря автоматическому масштабированию вы потратите ровно столько денег, сколько нужно именно сейчас. Облако позволяет быстро получить очень много ресурсов, а потом схлопнуть их.
Что придётся менять в облаках
Подход к масштабированию
В on-prem, если вам не хватает ресурсов, вы просто покупаете сервер помощнее. В облаке возможно вертикально масштабироваться, но всегда есть предел: платформы обычно закупают однотипные серверы с ограничением по CPU и оперативной памяти. Поэтому размывайте нагрузки горизонтально. Со stateless это очень просто: фронтенд и бэкенд обычно масштабируются горизонтально. Сложности обычно возникают с stateful, базами данных.
Рекомендации:
- Разделите workloads на stateless и stateful:
- Stateless workloads автомасштабируются горизонтально.
- Stateful workloads обычно вручную масштабируются вертикально.
Зоны доступности
Традиционно вы с точностью до сервера и стойки знаете, где находятся ваши виртуальные машины и другие ресурсы. В облаке это можно сделать только с точностью до дата-центра. Подобные дата-центры называются зонами доступности и часто объединяются в регионы, чтобы вы могли создать сервис, который переживёт отказ дата-центра. У нас в Yandex Cloud три региона в Центральной России, которые объединены в сеть.
Что важно понимать про дата-центры и зоны доступности? Зональные сервисы (например, диски виртуальных машин) не уйдут дальше зоны. Региональные сервисы (например, Object Storage у всех вендоров и сервис-провайдеров) привязаны к региону. Глобальные сервисы (например, у Amazon есть Route 53, их DNS глобален по всему миру) не зависят от конкретных дата-центров.
Рекомендации:
- Изучите scope сервисов, которые вы планируете использовать. У сервисов бывают разные зоны доступности и разные режимы работы.
Отказоустойчивость
В облаке при определённых масштабах у вас могут возникнуть новые сценарии отказа, да и старые никуда не уйдут. Возможны:
- Каскадные сбои.
- DDoS от мониторинга.
- Апдейты в зоне доступности.
Рекомендации:
- Закладывайте сценарии отказа в сайзинг проекта.
Квоты
В облаке вы можете получить много ресурсов, но вы ограничены квотой. Квота — объём ресурсов, которые можно использовать. Обычно квота повышается достаточно быстро, полуавтоматически, но сложные варианты требуют согласований. Если вы не подготовитесь к резкому росту — то упрётесь в квоты и у вас не хватит ресурсов, чтобы справиться с нагрузкой.
Рекомендации:
- Внимательно читайте раздел о квотах и лимитах сервисов, которые планируете использовать.
- Постоянно следите за квотами, чтобы избежать инцидентов.
Чек-лист для IaaS
Теперь перейдём к конкретным сервисах и их реализации в облаках. Начнём с IaaS.
Виртуальные машины
Виртуальная машина — это сущность зоны доступности, то есть некий абстрактный контейнер. У неё есть диск и сетевая карта, которые обычно не уходят дальше зоны доступности.
Отказоустойчивость. Поэтому, если вам нужна отказоустойчивость, то разместите сервис в нескольких зонах доступности или как минимум подключите однотипные виртуальные машины в разные стойки.
Переподписка. Например, у нас типы инстансов с 5/20/50% либо 100% гарантии. Что здесь важно? Если вы делаете тесты на процессорах с переподпиской, то ожидаете, что, например, один такой процессор примет 100 RPS и так будет работать неделю, две, три. А потом кто-то на этот процессор сядет — и у вас резко упадёт производительность. Поэтому выбирайте для продакшена процессоры без переподписки.
Масштабирование. Кажется, что облачные платформы — это что-то волшебное: их ресурсы бесконечны. Но виртуальные машины приземляются на конкретные серверы с конкретными моделями процессоров и GPU’шками. Провайдер сначала покупает одни модели серверов, потом другие. В какой-то момент вы не сможете расшириться и создать новую виртуалку: не хватит серверов. Поэтому важно следить за новостями платформы в конкретном сервис-провайдере, читать его документацию и обновлять платформы в своём приложении. Причём очень часто новые платформы дешевле, чем старые: так сервис-провайдер стимулирует вас переходить на новое.
На что обращать внимание:
- Обычно зональные ВМ с x86 или ARM-архитектурой не могут мигрировать в другой ДЦ.
- Существуют режимы с гарантированным и негарантированным резервированием CPU.
- ВМ отличаются платформами (вендор/модель CPU, число CPU на хост, соотношение CPU/RAM).
Рекомендации:
- Резервируйте compute-ресурсы приложения в разных зонах доступности.
- Используйте для продакшена гарантированные выделенные CPU для предсказуемого масштабирования. Уплотняйте нагрузки, которым надо меньше 1 CPU, с помощью контейнеризации.
- Мониторьте новости о выходе новых платформ, чтобы не оказаться в ситуации, когда кончатся ресурсы текущей.
Сеть VPC
Сеть в облаке — это уникальная система со своими правилами и паттернами. Например, в сетях сервис-провайдеров запрещены broadcast и multicast. В итоге традиционные средства кластеризации и отказоустойчивости, которые базируются на том, что вы серверы подключили в обычный свитч, не будут работать. Надо использовать новые средства, например балансировщики нагрузки.
Latency
Любые сущности в облаке находятся в дата-центрах. Зачастую оборудование в ДЦ разное, а сами ДЦ связаны разными каналами. Поэтому внутри зоны доступности, между зонами и между регионами всегда задержка. Она всегда уникальная. Обращайте внимание на свои регионы и зоны доступности и делайте тесты задержки сети.
Нагрузка
Обычно в облаках сеть рассчитана на general purpose профиль нагрузки. Это SaaS-сервисы, транзакционные сервисы и т. д. По дефолту 80% нагрузок работает из коробки. Но есть нагрузки, которые называются network-bound. Их требования к производительности часто повышенные.
Соответственно, надо знать, что во всех облаках есть обычная сеть и ускоренная сеть.
VPC tier
Как понять, какой tier сети вам нужен? Очень просто: сделайте нагрузочное тестирование.
На что обращать внимание:
- Архитектура облака.
- Уровни SDN и физических сетей.
- Tier производительности сетей.
Рекомендации:
- Изучите правила работы сети, поддерживаемые протоколы.
- Изучите, какие задержки вам стоит ожидать в зонах доступности, между зонами, между регионами. Очертите границу синхронной и асинхронной репликации для своих систем.
- Сделайте нагрузочное тестирование, чтобы понять, требуется ли повышенная производительность сети.
Балансировщики нагрузки
В облаках обычно есть два типа балансировщиков нагрузки. Первый — это сетевой. Он может обрабатывать пакеты, обычно делая destination NAT. Больше ничего балансировщик не умеет, но за счёт этого он постоянно масштабируется. То есть вы скорее упрётесь в свои бэкенды по перформансу, чем в этот балансировщик.
Когда вы распределяете нагрузку, вам надо решать ещё и другие проблемы, например терминировать SSL, маршрутизировать по URL’ам и т. д. За это отвечают балансировщики нагрузки прикладного уровня, которые находятся за балансировщиками сетевого уровня. Здесь всё зависит от облака. Вы можете сами поднимать балансировщик нагрузки, либо использовать балансировщик нагрузки, который даёт облако. Почему здесь надо выбирать? Потому что, во-первых, балансировщики прикладного уровня, которые даёт облако, могут стоить дорого. Во-вторых, например, есть Ingress-контроллеры в Kubernetes, которые дают вам эту функциональность, и она достаточно стабильна, удобна и стандартизирована между облаками, и вы можете использовать её не только в одном облаке, но и в разных местах. Важный вывод — от сетевых балансировщиков нагрузки вы не уйдёте ни в каком облаке, а вот от балансировщиков нагрузки прикладного уровня — здесь уже выбирайте, что вам удобнее.
На что обращать внимание:
- Сетевые балансировщики — работают на уровне L3/L4. «Тупые», но линейно скейлятся и недорогие.
- Application балансировщики — работают на уровне L7. «Умные», но обычно скейлятся лесенкой и могут дорого стоить.
Рекомендации
- Вы не сможете жить без сетевых балансировщиков в облаке.
- Изучите типы балансировщиков в облаке, их scope, поддержку протоколов.
- Application Load Balancer опционален, тут вам выбирать — брать его у облака и разрабатывать свой.
Блочное хранилище
Хранилище — важная часть любого IaaS.
Диск — это почти всегда сущность зоны доступности. Диски, которые живут на несколько зон, обычно очень медленные.
Диски в облаках помогают увеличивать производительность несколькими способами. Например, увеличивая размер диска. Это позволяет изолировать нагрузки между пользователями и получить больше производительности. Но почти у любого типа дисков вы рано или поздно придёте к лимитам. Чтобы увеличить лимит в облаках, подключайте к виртуалкам несколько дисков, собирайте RAID или поднимайте системы, которые умеют параллельно писать несколько дисков.
Рекомендации:
- Реплицируйте stateful-приложения (как минимум в другую AZ).
- Не хватает перформанса диска — увеличьте его размер.
- Диски можно агрегировать на уровне ОС (RAID 0 или средствами софта).
- Сделайте нагрузочное тестирование: это позволит понять, требуется ли повышенная производительность диска.
Чек-лист для PaaS
Kubernetes
Kubernetes как cloud-native-система часто знает о топологии облака, под которой находятся его воркеры. То есть Kubernetes знает о зонах доступности и может делать anti-affinity для нод. Собственно, это знание в лейблах нод очень часто позволяет шедулить ваши поды внутри K8S и в разные доступности, в разные типы нод и т. д.
Autoscalers. В облаке есть Cluster Autoscaler. Он позволяет добавить и убрать в кластер ноды в зависимости от профиля нагрузки. Важно, что Cluster Autoscaler у Kubernetes оперирует суммой реквестов, запрошенных вашими подами. Если сумма меньше, чем есть в кластере, Autoscaler пойдёт создавать новую ноду. Это работает параллельно с Horizontal Pod Autoscaler, который использует метрики из Metrics Server. То есть Cluster Autoscaler и тот же Horizontal Pod Autoscaler — это параллельные autoscalers, принципы скейлинга у них разные. Чтобы правильно скейлить и поды, и ноды, нужно настраивать реквесты и знать, как всё работает.
Pod disruption budget. В облаке апдейты Kubernetes — обычно Managed Kubernetes — действуют так. Скажем, у вас есть кластер с тремя нодами, нужно сделать апдейт. Что происходит? В кластер добавляются три новые ноды, а со старых делается cordon & drain: поды рестартятся и убираются с этих нод, старые ноды останавливаются и удаляются. Теперь в кластере есть три новые ноды. Но во время cordon & drain нод поды рестартятся, поэтому может случиться downtime приложения. Pod disruption budget в Kubernetes позволит вам сделать cordon & drain так, чтобы это сокращало downtime приложения.
Local External Traffic Policy. В любом облаке вы можете создать сервис типа Load Balancer, и к вашему кластеру подключится балансировщик нагрузки облака. Это может быть сетевой балансировщик приложений, но обычно это сетевой балансировщик, который можно подключить к Ingress. Если вы просто по дефолту его создадите, то включится Cluster External Traffic Policy. Балансировщик станет распределять нагрузку по всем нодам кластера. Даже если в них нет подов вашего приложения, он будет отправлять нагрузку на kube-proxy, который уже будет делать нормальную балансировку средствами Kubernetes на этот под. То есть по дефолту вы получаете два хопа балансировки, а приложение не знает об IP-адресах пользователей.
В Kubernetes есть второй тип подключения балансировщика нагрузки: Local External Traffic Policy. Балансировщик распределяет нагрузку только на ноды, где есть поды, и, по сути, напрямую в поды. Уменьшается latency, потому что у вас один хоп балансировки и вы видите IP-адреса пользователей. Local External Traffic Policy используется в большинстве случае в продакшене.
Рекомендации:
- Делайте anti-affinity-правила, исходя из ограничений:
- Можно раскидать deployment’ы без дисков по разным нодам.
- Но StatefulSet, который использует диски, возможно, придётся раскидывать по разным зонам доступности, чтобы сервис работал, если одна AZ выйдет из строя.
- Комбинируйте affinity-правила с Cluster Autoscaler для равномерного скейлинга по зонам доступности.
- Используйте podDistruptionBudget и настройки Node Deployment Policy, чтобы минимизировать даунтаймы при апгрейде узла. Меняйте RollingUpdateStrategy для минимизации даунтаймов при апдейте deployment.
- Подключайте механизм интеграции с балансировщиком Local External Traffic Policy: он уменьшит latency пользовательских запросов.
Object Storage
В облаке можно дёшево хранить статический контент: картинки, JavaScript, HTML и т. д. Почти в каждом облаке есть сервис Object Storage, работающий по протоколу S3. Он позволяет складывать контент и отдавать его пользователям, но вы можете здесь платить за трафик. Поэтому Object Storage рекомендуется накрывать CDN’ом. Он даст вам и вашим пользователям поменьше latency, но позволит сэкономить деньги: так будет тратиться меньше исходящего трафика. Также Object Storage позволяет экономить не только на хранении, но и на обработке статического контента
В Yandex Cloud вы можете положить весь статический контент в отдельный бакет, назвать его static.example.com, подключить к нему Let’s Encrypt — и весь за статическим контентом браузер будет ходить в бакет, а за более сложной логикой — в ваше приложение.
Помните, что Object Storage — это не файловое хранилище.
Базы данных
В каждом облаке уникальный набор БД, но все их можно разделить на две части:
1. Opensource-варианты БД (например, Postgres). Они есть почти везде. Обычно вы покупаете preprovisioned-ресурсы (выбираете количество и размер нод) и масштабируете БД руками. Что-то масштабируется автоматически, но надо изучать документацию конкретной БД в конкретном облаке.
2. Проприетарные БД. Они обычно дешевле и доступны даже в режиме serverless. Есть и недостаток: с проприетарных БД сложно уехать, потому что придётся полностью переписывать код.
Поэтому выбирайте managed БД, ориентируясь на то, для каких кейсов станете её использовать (в первую очередь с точки зрения бизнеса: насколько вы хотите расширять свою географию, будет ли больше пользователей).
На что обращать внимание:
- Opensource-варианты баз preprovisioned, в них есть ограничения. Обычно масштабируются горизонтально.
- Проприетарные базы обычно serverless и масштабируются как угодно. Но встречается vendor lock.
Рекомендации:
- Внимательно изучите ограничения managed-базы: лимиты, возможности и средства масштабирования Compute и Storage, есть ли инструментарий автомасштабирования.
- Изучите интерфейсы и лимиты проприетарной СУБД.
Больше подробностей о масштабировании вы найдёте в документации Yandex Cloud.