Ах, это соблазнительное желание «запилить свое приложение». Все мы с ним знакомы. Как ему не поддаться? Но столкнувшись с вопросами «как» и «где» разместить свой код, многие бросают эту затею. А это еще не было вопроса «Зачем».
В этой статье я хочу поделиться опытом, рассказать, как развернуть свое первое SaaS-приложение. Также разберем, как его развить в будущем. Это материал для тех, кто давно собирался, но не знает, как.

Что важно понять и принять сразу: ваш проект будет эволюционировать. Сперва это будет минимально работающий продукт с совсем базовым функционалом. Затем проект начнет решать все новые и новые задачи, поэтому потребует дополнительных ресурсов. В итоге эволюция приведет к тому, что ваше приложение изменится до неузнаваемости.
К чему это я? К тому, что не нужно требовать от своего проекта всего и сразу. В него не придут в одночасье сотни пользователей, это значит, что нужно начать с чего-то простого и развивать. Со временем проект будет эволюционировать под ваши потребности.
Облака
Белогривые лошадки. Начнем с того, что не стоит самим покупать «железки» и делать свой центр обработки данных. Это сложно, долго и дорого. Лучше разместите свое приложение у облачных провайдеров, используя IaaS. Так вы сэкономите деньги, время и нервы. Свой ЦОД — это удел крупных компаний со специфическими требованиями.
В современных реалиях для российского проекта стоит выбрать отечественного облачного провайдера. Например:
Также для приценки приведу стоимость сервера:
-
Selectel (4 ядра, 8 ГБ ОЗУ и 30 ГБ на очень быстром NVMe диске):

-
Yandex.Cloud (4 ядра, 8 ГБ ОЗУ и 30 ГБ на быстром SSD диске):

Сколько серверов?
Для начала вам потребуется два сервера:
-
Сервер тестирования (dev). На нем вы проверяете все новые фичи и исправленные баги.
-
Сервер эксплуатации (prod). На нем и размещаете ваше приложение для пользователей.
Помните об эволюционном пути развития проекта. В самом начале все сервисы вашего приложения будут на одном сервере:
-
веб-сервер,
-
сервер системы управления базами данных,
-
почтовый сервер,
-
все остальное, что потребуется вашему приложению.
Со временем prod претерпит изменения. Какие? Чтобы узнать, придется читать дальше!
Требуемые ресурсы серверов для вашего приложения нужно считать самостоятельно. У всех разные задачи. Помните, что сервер использующий:
-
менее 50% своих ресурсов работает штатно.
-
50-70% заставляет задуматься о дополнительных ресурсах.
-
90% и более не дает вашему приложению работать от слова совсем. Это катастрофа и вы единолично вызываете глобальное потепление. Должно быть стыдно.
Под процентами понимайте загруженность CPU и RAM. Конечно, не все так просто, это лишь основные величины. Есть также пиковые нагрузки и множество факторов влияющих на штатную работу вашего приложения со стороны сервера:
-
скорость чтения записи на диск;
-
ОС и ее настройки;
-
используемая СУБД и ее настройки;
-
используемый веб-сервер и его настройки и т. д.
Что еще вам обязательно понадобиться
Выбор языка программирования, СУБД, веб-сервера и много чего еще я вынесу за скобки этой статьи. Это зависит от типа вашего приложения и множества других факторов. Но есть вещи, которые обязан использовать каждый.
Система контроля и управления версиями жизненно необходима! Используйте Git, достойных альтернатив попросту нет.
Обязательно используйте хранилище кода. Тут выбор за вами: GitHub, Bitbucket или GitLab (российских аналогов пока нет). Все они имеют приватные репозитории на бесплатных тарифах и поддерживают работу с Git.
Создайте репозиторий (или несколько) для проекта в одном из хранилищ. В нем должно быть как минимум две ветки. Названия могут быть любыми, но чаще их называют как-то так:
-
dev – ветка для dev-сервера (создается от ветки master).
-
master – ветка для prod-сервера.
Клонируйте репозиторий проекта на dev-сервер и переключитесь на ветку dev. Проделайте то же самое для prod-сервера, но используйте ветку master.
Принцип такой: начали делать новую «фичу» или исправлять «баг» — создаете новую ветку от ветки dev. Закончили работу в новой ветке — вливаете ее в ветку dev. Получаете и тестируете все на dev-сервере. Если все хорошо, то вливаете ветку dev в ветку master и выкатываете изменения на prod-сервер.

Разверните сервера на ОС Linux. Чаще всего используют Centos 7 или Ubuntu 20.04 LTS. Могут быть и другие Linux, выбор за вами. Важно использовать версии ОС с длительным сроком поддержки (Long-Term Support — LTS).
ОС от Microsoft (Windows Server) используется только для специфичных проектов, где без нее не обойтись. Не забывайте, что за лицензию регулярно придется доплачивать облачному провайдеру.
Я рекомендую «заскриптовать» развертывание сервера. Создайте репозиторий с bash-скриптами, которые устанавливают необходимые сервисы, «подсовывают» в них нужные конфиги и поднимают (запускают) их. Да, на это нужно потратить время, но вы получите ряд преимуществ:
-
dev и prod вы развернете с одних и тех же скриптов, причем, абсолютно одинаково, ничего не забудете. Поверьте, это сэкономит кучу нервных клеток.
-
сервера не должны «падать», но они так иногда делают. Скрипты помогут вам быстро «поднять» новый сервер, причем точно такой же, как старый.
Админы делятся на три типа: которые не делают бэкапы, которые уже делают бэкапы, которые проверяют созданные бэкапы. Давайте угадаем, кто поступает правильно.
Обязательно делайте бэкапы данных — дампы баз данных, файлов пользователей и т. д. Их можно хранить у тех же облачных провайдеров, это не очень дорого. Конечно, все зависит от объема, но хранение пары сотен ГБ обойдется дешевле стоимости сервера, приведенного выше. Если ваша система позволяет работать с файлами, хранящимися в удаленной корзине типа S3, то сразу храните файлы в таких хранилищах у облачных провайдеров.
Не забывайте про файрвол. Эта ваша первая линия защиты, ведь ваш сервер доступен из сети Интернет.
Если ваше приложение работает через браузер, а все остальное пока находится на том же сервере, то достаточно открыть SSH, HTTP и HTTPS и закрыть остальные порты. Современные IDE и клиенты СУБД прекрасно умеют работать «over SSH». Поищите, как это настроить и вы прикроете множество уязвимостей для вашего приложения.
Еще я бы порекомендовал поменять SSH порт с 22 на какой-нибудь другой, например, 2200 и использовать SSH-ключи вместо логина и пароля.
Если облачные провайдеры предоставляют файрвол, который стоит на границе облачной сети и Интернет — настраивайте его. Если нет, то разворачивайте свой сервер (на ОС Centos 7), устанавливайте iptables и заскриптуйте правила при помощи bash. В следующий раз, когда вам понадобиться что-то открыть или закрыть, то вы допишете правило в скрипт и выполните его. Это лучше, чем вычитывать, что же у вас открыто и закрыто действующими правилами. Принцип написания скрипта прост:
-
Сбрасываете все действующие правила.
-
Объявляете политику по умолчанию (я предпочитаю «Все запрещено»).
-
Разрешаете то, что необходимо. Например, SSH, HTTP и HTTPS.
Я всегда делаю три скрипта. Вкусовщина, конечно, но мне так удобнее. И да, скрипты я обязательно храню в репозитории.
-
Скрипт, который сбрасывает все правила и ставит политикой по умолчанию «Все разрешено». Иногда надо быстро проверить, не в файрволе ли проблема.
-
Скрипт с постоянными правилами. Принцип его написания я описал выше.
-
Скрипт сохранения правил, использующий утилиту iptables-save. Нужен потому что iptables хранит изменения правил только до перезагрузки ОС. Чтобы сохранить нужные правки, используем этот скрипт.
Уследить за всем будет непросто, а стикеры на мониторе могут быстро заполонить все свободное место. И организовать собственное государство. Поэтому искренне надеюсь, что вы используете какой-нибудь таск-трекер. Опять-таки, в наших реалиях платформа нужна российская. Варианты:
Количество пользователей растет
Значит нагрузка на prod-сервер тоже увеличилась. Вы оптимизируете код и запросы в СУБД. Это временно помогает, но не решает проблему, так как пользователи все приходят. В этом же и была цель приложения?
Пришло время изменить архитектуру prod-сервера. Дело это не быстрое, поэтому нужно выиграть время. В этом поможет вертикальное масштабирование. Пока просто добавьте ресурсы на prod-сервер: CPU, RAM, увеличьте объем диска.
Вам придется разделить сервисы. Возможно, реализовать микросервисную архитектуру. В любом случае prod-сервер будет уже не один.
Архитектура с «Бастионным узлом»
Смысл этой архитектуры очень прост: абсолютно все запросы из интернета проходят через единый файрвол. Реализован он может быть по-разному. Некоторые облачные провайдеры уже предоставляют такой файрвол, и вам потребуется лишь настроить на нем правила с проброской портов.
Есть другой вариант: развернуть свой сервер с минимальными характеристиками. 1 ядро, 1 ГБ ОЗУ и минимальный, пусть даже медленный, диск. Ставите на него Centos 7 и iptables. Создаете репозиторий и скриптуете правила iptables с проброской по порту на нужный сервер.
В первую очередь с единого prod-сервера выносят СУБД. Возможно, что вам потребуется вынести что-то еще. Смотрите, что создает нагрузку и выносите этот сервис на отдельный сервер.
Если вы ранее скриптовали установку prod-сервера, то теперь вы создаете два репозитория. В один выносите скрипты по развертыванию СУБД, а в другой все остальное. Разворачиваете два сервера: СУБД и приложения. На файрволе делаете проброску портов HTTP и HTTPS на сервер приложений.
Так, стоп. Мы же не пробросили SSH? Конечно, это можно было сделать. Но я предлагаю подумать о будущем и сделать лучше.
Нужно развернуть еще один сервер, который называется терминальным. Пока хватит 2 ядра, 4 ГБ ОЗУ и быстрого диска на 20 ГБ. Терминальный сервер будет работать под управлением ОС Ubuntu 20.04 LTS с графическим интерфейсом, службой VNC и/или RDP. Также на него следует поставить IDE и клиент СУБД. Позже на нем можно развернуть средства мониторинга всех серверов. Например, grafana+prometheus или zabbix. Осталось пробросить SSH-порт на файрволе к терминальному серверу.
На терминальном сервере у нас развернут VNC и/или RDP, а проброшен только доступ по SSH. Так зачем тогда вообще нужен графический интерфейс?
Ответ прост: нужно подключаться VNC over SSH и/или RDP over SSH. До файрвола у нас будет шифрованный канал (SSH), а на терминальный сервер мы подключимся уже по графическому интерфейсу. В итоге терминальный сервер будет вашим рабочим местом в приватной облачной сети. На него можно установить любое нужное ПО и безопасно подключаться к облачным серверам.

Какие преимущества мы получим от этих действий:
-
Сервисы на разных серверах, а значит можно более тонко настраивать потребляемые ресурсы, оптимизировать производительность и стоимость.
-
Единая точка входа «Бастионный узел»:
-
Очень легко контролировать доступ.
-
Скрытая архитектура вашего приложения.
-
Легко масштабироваться в дальнейшем.
-
-
Работа на серверах только с доверенного устройства — терминального сервера.
-
Шифрованный канал связи, но в отличие от VPN дополнительные настройки не требуются.
Используйте Docker, а лучше docker-compose
Пользователей все больше, а значит для поддержки и разработки приложения требуется больше разработчиков.
И тут мы сталкиваемся с еще двумя проблемами:
-
Каждому программисту нужно обеспечить рабочее место с локальной версией системы. До этого разработчик разворачивал и настраивал самостоятельно все компоненты системы руками.
-
У разработчика на ПК новая «фича» работала нормально, залили на dev-сервер — ничего не работает. Чудеса, да и только. У этой проблемы даже есть имя: различные среды для разработки, тестирования и эксплуатации.
Обе проблемы можно решить при помощи docker-compose. Также нам опять пригодятся скрипты, которые делали для развертывания серверов. Теперь в них можно заменить установку, настройку и запуск сервисов yml-файлом docker-compose.
Да, конечно, скрипты развертывания локальной, dev и prod версии системы будут отличаться, но в них много общего. Главное: мы получим единую среду разработки, тестирования и эксплуатации. Поверьте, это очень важно.
Если вы подготовите развертывание приложения через докер к моменту перехода на архитектуру с «Бастионным узлом», то убьете двух зайцев:
Заяц 1: Вам не потребуется еще раз развертывать сервера и переносить данные.
Заяц 2: В вашем приложении еще нет тысяч пользователей и процесс миграции на современные технологии будет менее болезненным. Чем дольше вы будете оттягивать переезд на Docker, тем будет сложнее миграция.
А что дальше?
После всего вышеописанного можно посоветовать:
-
Автоматизировать развертывание кода через pipeline, используя концепцию CI/CD.
-
Мониторить нагрузку и переходить на горизонтальное масштабирование ресурсов с использованием балансировщиков нагрузки при необходимости. Я бы посоветовал посмотреть в сторону Kubernetes. Тем более некоторые облачные провайдеры предлагают его в качестве PaaS. Но не забывайте, что ваше приложение должно уметь работать с балансировщиком нагрузки.
В заключение повторюсь: приложение должно эволюционировать, постепенно адаптироваться под реалии.
Мир ИТ очень динамичен. То что актуально и в тренде сейчас, через некоторое время может быть заменено, изменено или просто устареть.
Не отставайте от актуальных трендов, но и не пытайтесь прикрутить все фичи сразу. Сперва подумайте, есть ли в них смысл для вашего проекта и стоят ли они ресурсозатрат.
ссылка на оригинал статьи https://habr.com/ru/post/664200/


Добавить комментарий