У нас были балансировщики нагрузки, несколько серверов приложений, 5 баз данных, 24 ядра, 32 гигабайта оперативки, nginx, php, redis, memcached и еще куча других сетевых технологий всех форм и расцветок. Не то чтобы это был необходимый минимум для бэкенда, но когда начал делать отличные онлайн-игры, становится трудно остановиться. Мы знали, что рано или поздно перейдем и на облако.
Это теперь мы делаем бэкенд для игр на основе микросервисов — раньше все было совсем по-другому. Был фиксированный аппаратный сетап, постоянные риски, что вот, еще чуть-чуть, и все сломается из-за наплыва игроков. Начинался 2013 год. Тогда мы и выпустили игру 2020: My Country.
Прошло достаточно много времени, проект рос и развивался, нагрузки постепенно увеличивались, и в какой-то момент мы решили перенести бэкенд в облако Azure — we do what we must because we can. Облака дают хороший запас по вычислительной мощности, поэтому начать мы решили с меньшего количества гигабайт и гигагерц, чем было в нашем дата-центре. Основой нового бэкенда стали менее мощные машины с более новыми процессорами. Больше всего мы переживали по поводу нагрузки на новые БД-сервера и даже готовились к разбиению баз, но переживали, как оказалось, зря.
Рис. 1 — Портал Microsoft Azure
На портале Azure мы подняли нужное количество машин, добавили security group с настройками доступа к машинам, установили нужные пакеты через Ansible, настроили конфиги, выпили еще немного кофе, включили новые балансировщики нагрузки и выдохнули. Оставалось сделать еще пару вещей.
Но перед этим — внимание, уважаемые знатоки, — вопрос задает начинающий системный инженер из Иркутска: «Хорошо, это один проект. А что, если их будет много, а хостов будут десятки и сотни?» Отвечаем: в таких случаях на помощь приходит terraform от HashiCorp, который у нас уже успешно работает в AWS и также поддерживает Azure.
В первом подходе к terraform нам помогает документация, где есть пример создания ресурсной группы, ее сети и файла с учетными данными для terraform. Мы вынесли эти данные в файл с расширением .tf в директории, откуда запускаются скрипты.
Команда terraform plan показывает превью будущих действий — планируется добавление ресурсов, которые уже созданы вручную и существуют.
Рис. 2 — Результат команды terraform plan.
Это не совсем то, что мы бы хотели увидеть, поэтому вспоминаем свой опыт с AWS — в terraform есть команда import, для, очевидно, импорта существующей инфраструктуры.
При импорте нужно ввести идентификаторы существующих ресурсов из Azure. По умолчанию они достаточно длинные и сложные, поэтому (наверное) на портале есть кнопка Copy to clipboard, которая значительно упрощает весь процесс.
Рис. 3 — Результат импорта
Еще один момент: terraform пока не умеет автоматически генерировать конфигурацию импортируемых ресурсов и предлагает нам сделать это вручную. По умолчанию, при отсутствии конфигурации у ресурса, он помечается на удаление при следующем запуске.
Добавляем конфигурацию и смотрим на terraform plan.
Рис. 4 — terraform plan после импорта ресурсов из Azure
Тильда и желтый цвет означают изменение ресурса — terraform хочет пересоздать subnet mc2020 без привязки к security group. Вероятно, это произошло из-та того, что мы не указали security group для подсети. Чтобы узнать причину наверняка, посмотрим на то, как импортирована существующая виртуальная сеть. Это можно сделать с помощью файла terraform.tfstate (нечитабельная JSON-простыня) или командой state. Вполне очевидно, какой способ выбрали мы.
Рис.5 — Снова terraform state
Действительно, привязка к security_group есть, но в изначальной конфигурации мы про нее забыли. Для исправления проходим все шаги заново — находим группу на портале Azure, копируем id, снова импортируем и прописываем в конфигурацию.
Замечание: при импорте ресурсов нужно внимательно смотреть их атрибуты — они case-sensitive, и важно не ошибаться при их наборе. Все это издержки того, что мы импортируем уже существующую инфраструктуру и кодируем ее.
После всех правок команда terraform plan выдает нам то, что мы ожидали увидеть изначально.
(Здесь был скучный процесс импорта\записи инфраструктуры всего проекта, который мы пропустили по очевидным причинам)
Мы рекомендуем создавать инфраструктуру сразу в виде кода. Магия делается следующим образом:
Примерно так. Спасибо за вопрос, внимательный читатель! Вернемся к паре обещанных ранее вещей.
Во-первых, нам нужно было перенести большое количество данных с боевого железа. Чтобы обновить xtrabackup, пришлось проапгрейдить MySQL и временно отключить часть сетевого функционала. Во время разработки игры в ней был предусмотрен офлайн-режим, поэтому мы сделали это безболезненно и начали перенос данных.
Рис.6 — Итоговая схема инфрастуктуры в Azure
На момент переноса в нескольких базах было около 500 гигабайт данных. Данные с двух самых объемных серверов мы перенесли между дата-центрами через xtrabackup на скорости в 1 Гбит/c, а для дампа необходимых баз с третьего сервера мы использовали myloader, который работает быстрее стандартного mysqldump. После этого мы допили оставшийся кофе и провели окончательные настройки всего-что-можно-было-настроить.
Во-вторых, мы начали потихоньку переводить трафик на новые балансировщики нагрузки, следя за ошибками и нагрузкой. Для обработки всего трафика мы добавили еще один app-сервер и в итоге получили ~30% нагрузки app- и 8-15% db-серверов.
В примере выше мы использовали state с локального компьютера одного из наших инженеров и при потере файла могли потерять всю проделанную работу. Поэтому, конечно же, мы сделали бэкапы, сохранили наш код в git и полностью используем преимущества системы контроля версий.
Планирование и хранение лэйаута кода и стейтов зависит от специфики проекта, поэтому подходов может быть несколько — создание в привязке к проектам, регионам, даже к отдельному state на каждый ресурс. В целом нужно начать писать инфраструктуру как код, и все получится.
Для полного переноса осталось:
Весь процесс переноса бэкенда на Azure (вместе с подготовкой и чтением документации по terraform) занял чуть меньше недели, а непосредственно перенос — около двух дней. Облако Azure из коробки позволяет почувствовать преимущества автоматического масштабирования, дает возможность мгновенно добавить ресурсы в случае повышения нагрузки и все остальное добро и позитив, которое приносят в жизнь разработчиков облачные сервисы.
При правильном подходе к организации процесса и выборе эффективных инструментов самая ответственная и сложная часть — переезд и запуск существующего бэкенда в облачной инфраструктуре — становится простой, предсказуемой и понятной, чем мы с удовольствием и воспользовались. Задокументировав процесс простого переезда на этой технологии, мы продолжим перенос в облако и других наших проектов.
Ждем ваших вопросов в комментариях. Спасибо за внимание!
Это теперь мы делаем бэкенд для игр на основе микросервисов — раньше все было совсем по-другому. Был фиксированный аппаратный сетап, постоянные риски, что вот, еще чуть-чуть, и все сломается из-за наплыва игроков. Начинался 2013 год. Тогда мы и выпустили игру 2020: My Country.
Прошло достаточно много времени, проект рос и развивался, нагрузки постепенно увеличивались, и в какой-то момент мы решили перенести бэкенд в облако Azure — we do what we must because we can. Облака дают хороший запас по вычислительной мощности, поэтому начать мы решили с меньшего количества гигабайт и гигагерц, чем было в нашем дата-центре. Основой нового бэкенда стали менее мощные машины с более новыми процессорами. Больше всего мы переживали по поводу нагрузки на новые БД-сервера и даже готовились к разбиению баз, но переживали, как оказалось, зря.
Рис. 1 — Портал Microsoft Azure
На портале Azure мы подняли нужное количество машин, добавили security group с настройками доступа к машинам, установили нужные пакеты через Ansible, настроили конфиги, выпили еще немного кофе, включили новые балансировщики нагрузки и выдохнули. Оставалось сделать еще пару вещей.
Но перед этим — внимание, уважаемые знатоки, — вопрос задает начинающий системный инженер из Иркутска: «Хорошо, это один проект. А что, если их будет много, а хостов будут десятки и сотни?» Отвечаем: в таких случаях на помощь приходит terraform от HashiCorp, который у нас уже успешно работает в AWS и также поддерживает Azure.
В первом подходе к terraform нам помогает документация, где есть пример создания ресурсной группы, ее сети и файла с учетными данными для terraform. Мы вынесли эти данные в файл с расширением .tf в директории, откуда запускаются скрипты.
provider "azurerm" {
subscription_id = "xxxx-xxxx"
client_id = "xxxx-xxxx"
client_secret = "xxxx-xxxx"
tenant_id = "xxxx-xxxx"
}
Команда terraform plan показывает превью будущих действий — планируется добавление ресурсов, которые уже созданы вручную и существуют.
Рис. 2 — Результат команды terraform plan.
Это не совсем то, что мы бы хотели увидеть, поэтому вспоминаем свой опыт с AWS — в terraform есть команда import, для, очевидно, импорта существующей инфраструктуры.
При импорте нужно ввести идентификаторы существующих ресурсов из Azure. По умолчанию они достаточно длинные и сложные, поэтому (наверное) на портале есть кнопка Copy to clipboard, которая значительно упрощает весь процесс.
Рис. 3 — Результат импорта
Еще один момент: terraform пока не умеет автоматически генерировать конфигурацию импортируемых ресурсов и предлагает нам сделать это вручную. По умолчанию, при отсутствии конфигурации у ресурса, он помечается на удаление при следующем запуске.
Добавляем конфигурацию и смотрим на terraform plan.
Рис. 4 — terraform plan после импорта ресурсов из Azure
Тильда и желтый цвет означают изменение ресурса — terraform хочет пересоздать subnet mc2020 без привязки к security group. Вероятно, это произошло из-та того, что мы не указали security group для подсети. Чтобы узнать причину наверняка, посмотрим на то, как импортирована существующая виртуальная сеть. Это можно сделать с помощью файла terraform.tfstate (нечитабельная JSON-простыня) или командой state. Вполне очевидно, какой способ выбрали мы.
Рис.5 — Снова terraform state
Действительно, привязка к security_group есть, но в изначальной конфигурации мы про нее забыли. Для исправления проходим все шаги заново — находим группу на портале Azure, копируем id, снова импортируем и прописываем в конфигурацию.
После все выглядит так:
resource "azurerm_resource_group" "mc2020" {
name = "mc2020"
location = "${var.location}"
}
resource "azurerm_virtual_network" "mc2020-vnet" {
name = "mc2020-vnet"
address_space = ["XX.XX.XX.XX/24"]
location = "${var.location}"
resource_group_name = "${azurerm_resource_group.mc2020.name}"
}
resource "azurerm_subnet" "mc2020-snet" {
name = "mc2020"
resource_group_name = "${azurerm_resource_group.mc2020.name}"
virtual_network_name = "${azurerm_virtual_network.mc2020-vnet.name}"
address_prefix = "XX.XX.XX.XX/24"
network_security_group_id = "${azurerm_network_security_group.mc2020-nsg.id}"
}
resource "azurerm_network_security_group" "mc2020-nsg" {
name = "mc2020-nsg"
location = "${var.location}"
resource_group_name = "${azurerm_resource_group.mc2020.name}"
security_rule {
name = "default-allow-ssh"
priority = 1000
direction = "Inbound"
access = "Allow"
protocol = "TCP"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "XX.XX.XX.XX/24"
destination_address_prefix = "*"
}
security_rule {
name = "trusted_net"
priority = 1050
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "0-65535"
source_address_prefix = "XX.XX.XX.XX/32"
destination_address_prefix = "*"
}
security_rule {
name = "http"
priority = 1060
direction = "Inbound"
access = "Allow"
protocol = "TCP"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "https"
priority = 1061
direction = "Inbound"
access = "Allow"
protocol = "TCP"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
Замечание: при импорте ресурсов нужно внимательно смотреть их атрибуты — они case-sensitive, и важно не ошибаться при их наборе. Все это издержки того, что мы импортируем уже существующую инфраструктуру и кодируем ее.
После всех правок команда terraform plan выдает нам то, что мы ожидали увидеть изначально.
No changes. Infrastructure is up-to-date. This means that Terraform
could not detect any differences between your configuration and
the real physical resources that exist. As a result, Terraform
doesn't need to do anything.
(Здесь был скучный процесс импорта\записи инфраструктуры всего проекта, который мы пропустили по очевидным причинам)
Мы рекомендуем создавать инфраструктуру сразу в виде кода. Магия делается следующим образом:
- Добавляем ресурс;
- Смотрим terraform plan;
- Выполняем terraform apply;
- Смотрим на чудеса автоматической переконфигурации ресурсов;
Примерно так. Спасибо за вопрос, внимательный читатель! Вернемся к паре обещанных ранее вещей.
Во-первых, нам нужно было перенести большое количество данных с боевого железа. Чтобы обновить xtrabackup, пришлось проапгрейдить MySQL и временно отключить часть сетевого функционала. Во время разработки игры в ней был предусмотрен офлайн-режим, поэтому мы сделали это безболезненно и начали перенос данных.
Рис.6 — Итоговая схема инфрастуктуры в Azure
На момент переноса в нескольких базах было около 500 гигабайт данных. Данные с двух самых объемных серверов мы перенесли между дата-центрами через xtrabackup на скорости в 1 Гбит/c, а для дампа необходимых баз с третьего сервера мы использовали myloader, который работает быстрее стандартного mysqldump. После этого мы допили оставшийся кофе и провели окончательные настройки всего-что-можно-было-настроить.
Во-вторых, мы начали потихоньку переводить трафик на новые балансировщики нагрузки, следя за ошибками и нагрузкой. Для обработки всего трафика мы добавили еще один app-сервер и в итоге получили ~30% нагрузки app- и 8-15% db-серверов.
В примере выше мы использовали state с локального компьютера одного из наших инженеров и при потере файла могли потерять всю проделанную работу. Поэтому, конечно же, мы сделали бэкапы, сохранили наш код в git и полностью используем преимущества системы контроля версий.
Планирование и хранение лэйаута кода и стейтов зависит от специфики проекта, поэтому подходов может быть несколько — создание в привязке к проектам, регионам, даже к отдельному state на каждый ресурс. В целом нужно начать писать инфраструктуру как код, и все получится.
Для полного переноса осталось:
- Пропатчить клиенты, чтобы прописать новые хосты (“az-”);
- Перенести файлы статики, которые заливаются скриптом на один из старых серверов и служат Origin для Akamai CDN;
- Через некоторое время отключить старые сервера.
Весь процесс переноса бэкенда на Azure (вместе с подготовкой и чтением документации по terraform) занял чуть меньше недели, а непосредственно перенос — около двух дней. Облако Azure из коробки позволяет почувствовать преимущества автоматического масштабирования, дает возможность мгновенно добавить ресурсы в случае повышения нагрузки и все остальное добро и позитив, которое приносят в жизнь разработчиков облачные сервисы.
При правильном подходе к организации процесса и выборе эффективных инструментов самая ответственная и сложная часть — переезд и запуск существующего бэкенда в облачной инфраструктуре — становится простой, предсказуемой и понятной, чем мы с удовольствием и воспользовались. Задокументировав процесс простого переезда на этой технологии, мы продолжим перенос в облако и других наших проектов.
Ждем ваших вопросов в комментариях. Спасибо за внимание!
Поделиться с друзьями
Комментарии (9)
adminguru
30.01.2017 15:15+2Azure хорош по возможностям, цены только хотелось бы поменьше. Если не секрет, намного дороже новое решение по сравнение с датацентром раньше.
evil_me
30.01.2017 15:28+2С точки зрения ресурсов, мы стали использовать меньше мощностей для тех же задач. По деньгам сложно сказать, прошло мало времени для подсчета статистики.
fuCtor
30.01.2017 19:09+1Terraform штука отличная, поверх его state файлов сделал обвязку для автоматизации типовых задач с сервисами (AWS).
Если используете docker и в принципе архитектура не критична к пропаданиям узлов, посмотрите Spotinst, для AWS при массовых деплоях позволяет хорошо экономить.
arzonus
31.01.2017 12:19Перенести файлы статики, которые заливаются скриптом на один из старых серверов и служат Origin для Akamai CDN;
Можно использовать не один старый сервер, а на прямую BLOB. CDN умеет получать информацию напрямую.
deril
Зачем скрины консоли? Может есть другой способ вставить текст?
Почему выбрали именно Azure а не amazon например? Что подтолкнуло к такому выбору?
evil_me
Спасибо за вопросы!
1) Мы честно пытались минимизировать количество скринов. В дальнейшем будем просить у хранителей консоли логи сразу текстом)
2) Мы работаем и с Amazon, вот здесь рассказ о том, как мы выбирали платформу для другой нашей игры.