DevOps для гейминга: Масштабируемый хостинг CS 1.6 на Docker

Практический курс по созданию автоматизированной платформы аренды серверов CS 1.6. Вы научитесь упаковывать серверы в Docker, настраивать динамическое масштабирование под нагрузкой, внедрять мониторинг и разрабатывать ботов для управления арендой.

1. Подготовка окружения Ubuntu и создание оптимизированного Docker-образа для сервера CS 1.6

Подготовка окружения Ubuntu и создание оптимизированного Docker-образа для сервера CS 1.6

Добро пожаловать в курс DevOps для гейминга. Мы начинаем путь к созданию масштабируемой платформы для хостинга серверов Counter-Strike 1.6. Эта игра, несмотря на свой возраст, остается эталоном киберспортивных дисциплин и требует высокой стабильности и низкой задержки.

В этой первой статье мы заложим фундамент: подготовим операционную систему Ubuntu, разберемся с зависимостями старого движка GoldSrc и напишем Dockerfile, который позволит нам запускать серверы изолированно, безопасно и предсказуемо.

Зачем нам Docker для CS 1.6?

Традиционный запуск игровых серверов подразумевает ручную установку библиотек, скачивание файлов через SteamCMD и запуск скриптов в фоне (например, через screen). При масштабировании до 100 серверов этот подход превращается в администрирование хаоса. Конфликты портов, версий библиотек и сложность обновления — главные враги хостинг-провайдера.

Docker решает эти проблемы, предоставляя:

* Изоляцию: Каждый сервер живет в своем контейнере и не знает о существовании соседей. * Воспроизводимость: Образ, собранный один раз, будет работать одинаково на любом сервере. * Скорость: Развертывание нового экземпляра занимает секунды.

!Схема контейнеризации игровых серверов: один хост управляет множеством изолированных экземпляров игры.

Шаг 1: Подготовка хост-системы Ubuntu

В качестве базовой ОС мы будем использовать Ubuntu 22.04 LTS или 24.04 LTS. Это стабильные релизы с длительной поддержкой. Перед тем как начать работу с Docker, необходимо оптимизировать саму систему.

Обновление и установка Docker

Сначала обновим индексы пакетов и установим необходимые утилиты:

Теперь установим Docker Engine. Рекомендуется использовать официальный репозиторий Docker, а не стандартный из Ubuntu, чтобы получать свежие версии:

Чтобы не писать sudo перед каждой командой Docker, добавим текущего пользователя в группу docker:

dockerfile

Используем легкий базовый образ Debian

FROM debian:bullseye-slim

Устанавливаем метаданные

LABEL maintainer="admin@cs-hosting.com"

Отключаем интерактивный режим при установке пакетов

ENV DEBIAN_FRONTEND=noninteractive

1. Добавляем архитектуру i386 (32-бит)

2. Обновляем пакеты

3. Устанавливаем lib32gcc-s1 (критично для HLDS) и curl

4. Чистим кэш для уменьшения размера образа

RUN dpkg --add-architecture i386 && \ apt-get update && \ apt-get install -y --no-install-recommends \ lib32gcc-s1 \ lib32stdc++6 \ ca-certificates \ curl \ wget \ unzip && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*

Создаем пользователя steam, чтобы не запускать сервер от root

RUN useradd -m -d /home/steam steam USER steam WORKDIR /home/steam

Скачиваем SteamCMD

RUN mkdir steamcmd && \ cd steamcmd && \ curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxvf -

Устанавливаем сервер CS 1.6 (AppID 90)

Мы делаем это в одном слое RUN, чтобы зафиксировать файлы

+quit нужен для корректного выхода из steamcmd

RUN ./steamcmd/steamcmd.sh +force_install_dir /home/steam/cs16 \ +login anonymous \ +app_update 90 validate \ +quit || true # || true добавлен, так как steamcmd иногда возвращает код ошибки даже при успехе

Исправление частой ошибки с steamclient.so

RUN mkdir -p /home/steam/.steam/sdk32 && \ ln -s /home/steam/steamcmd/linux32/steamclient.so /home/steam/.steam/sdk32/steamclient.so

Открываем порт по умолчанию

EXPOSE 27015/udp

Рабочая директория сервера

WORKDIR /home/steam/cs16

Команда запуска по умолчанию

ENTRYPOINT ["./hlds_run"] CMD ["-game", "cstrike", "+maxplayers", "32", "+map", "de_dust2", "+port", "27015"] bash docker build -t cs16-server:v1 . bash docker run -d \ --name cs16-test \ -p 27015:27015/udp \ cs16-server:v1 \ -game cstrike +maxplayers 16 +map de_dust2 bash docker logs cs16-test ``

Вы должны увидеть строчки вроде Connection to Steam servers successful и VAC secure mode is activated`.

Оптимизация размера образа

Получившийся образ может весить около 1 ГБ или больше. В будущих статьях мы рассмотрим использование Multi-stage builds, чтобы исключить сам SteamCMD из финального образа, оставив только скачанные файлы игры. Это позволит уменьшить размер и повысить безопасность, удалив инструменты загрузки из продакшн-контейнера.

Заключение

Мы успешно подготовили хост-систему и создали базовый Docker-образ для сервера CS 1.6. Теперь у нас есть "кирпичик", из которого мы будем строить нашу масштабируемую систему.

В следующей статье мы научимся управлять множеством таких контейнеров, использовать Docker Compose для локальной оркестрации и подготовим почву для автоматического развертывания через Telegram-бота.

2. Архитектура масштабирования: управление пулом от 10 до 100 контейнеров через Docker API

Архитектура масштабирования: управление пулом от 10 до 100 контейнеров через Docker API

В предыдущей статье мы создали идеальный «атом» нашей системы — оптимизированный Docker-образ сервера Counter-Strike 1.6. Мы научились запускать один сервер вручную. Но что, если нам нужно запустить 10 серверов? А 100? А если нужно автоматически выдавать их пользователям через Telegram-бота?

Ручной ввод команд docker run в терминале перестает работать уже на пятом сервере. Вы начнете путаться в портах, забывать имена контейнеров и терять контроль над ресурсами. В этой статье мы переходим от ручного управления к программному. Мы спроектируем архитектуру, где Python-скрипт управляет флотилией контейнеров через Docker API.

Проблема масштабирования игровых серверов

В отличие от веб-серверов (Nginx, Apache), которые обычно слушают 80 или 443 порт и балансируют нагрузку, игровые серверы являются stateful (сохраняющими состояние). Каждый матч — это уникальный процесс, к которому игроки подключаются напрямую по уникальному порту.

Если мы хотим запустить 100 серверов на одной машине, нам нужно решить три главные задачи:

  • Управление портами: Каждому контейнеру нужен свой уникальный внешний UDP-порт.
  • Изоляция ресурсов: Один «жадный» сервер не должен съедать весь CPU, заставляя лагать остальные 99.
  • Автоматизация жизненного цикла: Сервер должен создаваться, запускаться и удаляться по команде извне (например, от бота).
  • !Архитектура управляющего сервиса: центральный контроллер принимает команды от пользователей и управляет Docker-демоном.

    Docker API вместо CLI

    Многие новички пытаются автоматизировать Docker, вызывая системные команды через subprocess в Python (например, os.system("docker run...")). Это плохой путь. Он ненадежен, сложен в отладке и небезопасен.

    Профессиональный подход — использование Docker SDK for Python. Это библиотека, которая общается с Docker Daemon напрямую через Unix-сокет или TCP, отправляя JSON-запросы.

    Установим библиотеку:

    Теперь мы можем управлять серверами как объектами в коде.

    Математика распределения портов

    Самая критичная часть архитектуры — это аллокация портов. Стандартный порт CS 1.6 — 27015. Если мы запустим 100 контейнеров, мы не можем привязать их все к 27015 на хост-машине.

    Нам нужна формула для назначения внешнего порта для -го сервера:

    Где: * — внешний порт, который мы сообщим игрокам для подключения к -му серверу. * — базовый порт начала диапазона (обычно 27015). * — порядковый номер сервера (индекс), начиная с 0.

    Например, для 10-го сервера (где , так как счет с нуля):

    Таким образом, наши серверы займут диапазон портов от 27015 до 27114. Внутри контейнера сервер всегда будет думать, что он работает на 27015. Это упрощает конфигурацию самого HLDS.

    Реализация контроллера на Python

    Давайте напишем базовый класс, который будет отвечать за запуск игрового сервера. Этот код станет ядром вашего будущего Telegram-бота.

    Разбор параметров запуска

  • ports={'27015/udp': public_port}: Это магия Docker. Внутри контейнера CS 1.6 слушает порт 27015. Docker перехватывает трафик, приходящий на public_port хост-машины, и перенаправляет его внутрь. Для игрока это прозрачно.
  • mem_limit="512m": Жесткое ограничение памяти. Если сервер начнет течь (memory leak) или подвергнется атаке, Docker убьет только этот контейнер, спасая остальные 99.
  • cpu_quota=50000: Ограничение процессорного времени. Значение 50000 при периоде 100000 означает, что контейнер может использовать не более 50% мощности одного ядра процессора.
  • Расчет ресурсов для 100 серверов

    При масштабировании важно заранее посчитать, выдержит ли ваше железо. Используем формулу расчета необходимого CPU:

    Где: * — общее количество необходимых ядер процессора. * — количество серверов (100). * — средняя нагрузка одного активного сервера (для CS 1.6 это примерно 0.1-0.2 ядра современного процессора). * — накладные расходы Docker и ОС (около 0.01 ядра на контейнер).

    При и нагрузке 0.15 ядра на сервер:

    Это означает, что для хостинга 100 активных серверов вам потребуется мощный процессор (например, AMD Ryzen 9 или серверный Intel Xeon) минимум с 16 физическими ядрами.

    Мониторинг через API

    Ваш Telegram-бот должен знать, жив ли сервер. Docker API позволяет получать статистику в реальном времени.

    Этот код позволяет боту отвечать на команду /status мгновенно, не заходя на сервер по SSH.

    Хранение состояния (State)

    Чтобы связать Docker-контейнеры с пользователями Telegram, нам нужна база данных. Docker не знает, что контейнер cs16_server_5 принадлежит пользователю @ivan_gamer. Он знает только ID контейнера.

    Вам понадобится простая таблица в базе данных (SQLite для начала, PostgreSQL для продакшена):

    | ID | User_ID (Telegram) | Container_ID | Port | Status | Expires_At | | :--- | :--- | :--- | :--- | :--- | :--- | | 1 | 123456789 | a1b2c3d4... | 27015 | running | 2023-10-27 18:00 | | 2 | 987654321 | e5f6g7h8... | 27016 | stopped | 2023-10-27 19:00 |

    Когда пользователь пишет боту «Дай сервер», скрипт:

  • Находит свободный порт в БД.
  • Вызывает start_cs_server с этим портом.
  • Записывает ID контейнера и ID пользователя в БД.
  • Отправляет пользователю IP:Port.
  • Заключение

    Мы построили логическую архитектуру масштабируемого хостинга. Мы отказались от ручного управления в пользу Docker API, научились динамически выделять порты и ограничивать ресурсы, чтобы один сервер не «убил» соседей.

    В следующей статье мы займемся реализацией Telegram-бота, который соединит пользователей с нашим Python-контроллером, позволяя арендовать серверы прямо из мессенджера.

    3. Система мониторинга нагрузок и процессов с отправкой алертов в Telegram

    Система мониторинга нагрузок и процессов с отправкой алертов в Telegram

    Мы продолжаем наш курс DevOps для гейминга. В предыдущих статьях мы научились создавать оптимизированный Docker-образ для Counter-Strike 1.6 и управлять пулом контейнеров через Python-скрипт. Теперь перед нами стоит задача эксплуатации: как уследить за сотней серверов одновременно?

    Представьте ситуацию: вы запустили 50 серверов. Три из них зависли из-за ошибки в плагине AMX Mod X, один потребляет 100% CPU, вызывая лаги у соседей, а еще пять просто упали. Если вы узнаете об этом от разгневанных клиентов в чате поддержки — вы уже проиграли.

    В этой статье мы создадим систему активного мониторинга, которая будет следить за здоровьем («health check») каждого контейнера и мгновенно сообщать администратору или пользователю о проблемах через Telegram.

    Архитектура системы мониторинга

    Для игрового хостинга стандартные решения вроде Zabbix или Prometheus могут быть избыточны на старте или сложны в интеграции с логикой аренды «по часам». Нам нужно решение, которое знает контекст: кто арендовал сервер, когда заканчивается время и какой тариф оплачен.

    Мы построим Monitor Service — отдельный процесс на Python, который работает параллельно с нашим основным ботом.

    !Логическая схема потока данных от игровых контейнеров к администратору через сервис мониторинга.

    Основные задачи сервиса:

  • Сбор метрик: Опрос Docker API каждые секунд.
  • Анализ аномалий: Сравнение текущих показателей с пороговыми значениями.
  • Алертинг: Отправка уведомлений при нарушении порогов.
  • Автоматическая реакция: Перезагрузка зависших контейнеров.
  • Математика нагрузок: что считать аномалией?

    Сервер CS 1.6 (процесс hlds_linux) — это однопоточное приложение. Это означает, что оно не может использовать более 100% одного ядра процессора, даже если у вас 64-ядерный монстр. Однако, если процесс упирается в полку 100% одного ядра, игра начинает «фризить» и телепортировать игроков.

    Нам нужно рассчитать критический порог загрузки CPU. Docker API возвращает данные в наносекундах использования CPU. Чтобы получить понятные проценты, используется следующая формула:

    Где: * — итоговая загрузка процессора контейнером в процентах. * — разница в использовании процессорного времени контейнером между двумя замерами. * — разница в системном времени хоста между двумя замерами. * — количество ядер процессора, доступных системе (множитель необходим, так как Docker считает 100% как полную загрузку одного ядра, а в многоядерной системе значения могут превышать 100%).

    Для CS 1.6 критическим является не только CPU, но и оперативная память. Утечки памяти (memory leaks) — частая проблема старых движков. Определим условие тревоги (алерта) для памяти:

    Где: * — статус тревоги (1 — тревога, 0 — норма). * — текущее потребление памяти контейнером. * — жесткий лимит памяти, установленный при запуске контейнера (например, 512 МБ).

    Мы будем отправлять алерт, если потребление памяти превысит 90% от выделенного лимита.

    Реализация сборщика метрик на Python

    Для работы с Docker API мы продолжаем использовать библиотеку docker. Нам понадобится метод stats, который возвращает поток данных в реальном времени.

    Создадим файл monitor.py. В нем мы реализуем класс, который обходит все активные контейнеры.

    Важные нюансы кода

  • stream=False: По умолчанию stats() открывает постоянное соединение и ждет новых данных. Для мониторинга 100 серверов это создаст 100 открытых HTTP-соединений, что убьет ваш скрипт. Используйте stream=False для получения мгновенного снимка (snapshot).
  • Обработка ошибок: Контейнер может быть удален прямо во время проверки. Блок try-except обязателен, иначе мониторинг упадет целиком из-за одного сервера.
  • Интеграция с Telegram Bot

    Теперь нам нужно отправлять эти алерты. Мы не будем встраивать код бота прямо в мониторинг, чтобы избежать блокирующих операций. Вместо этого мы будем использовать простую функцию отправки HTTP-запроса к API Telegram.

    Вам понадобится BOT_TOKEN от BotFather и ADMIN_CHAT_ID (ваш ID).

    Теперь объединим всё в главный цикл мониторинга:

    Связь с пользователями: Аренда и Статус

    В бизнес-требованиях указано, что пользователи должны иметь возможность получать серверы в аренду и проверять их статус. Мониторинг — это «бэкенд» этой истории. Но как пользователь узнает о статусе своего сервера?

    Нам нужно связать Container ID с User ID в базе данных (как мы обсуждали в прошлой статье). Когда мониторинг обнаруживает проблему у контейнера cs16_server_45, он должен:

  • Посмотреть в БД, кому принадлежит сервер №45.
  • Если сервер арендован, отправить уведомление не только админу, но и лично пользователю: «Ваш сервер потребляет слишком много ресурсов и был перезагружен».
  • Команда /status в боте

    Пользователь не хочет ждать алерта, он хочет проверить сервер прямо сейчас. Реализуем логику для обработчика команды /status в вашем боте:

    Проблема «зомби» процессов

    Иногда контейнер имеет статус running, но сервер CS 1.6 внутри завис и не отвечает на запросы игроков. Docker stats покажет, что потребление ресурсов минимально, и наш мониторинг промолчит.

    Для решения этой проблемы используется UDP-пинг. Мы должны отправлять специальный пакет движку GoldSrc (протокол A2S_INFO) и ждать ответа.

    Формула расчета доступности сервиса:

    Где: * — оценка доступности (Health Score). * — количество полученных ответов от игрового сервера. * — количество отправленных запросов (пингов).

    Если , сервер считается «зомби» и подлежит перезагрузке, даже если Docker говорит, что контейнер запущен.

    Заключение

    Мы создали базовую, но надежную систему мониторинга. Она не требует сложных баз данных временных рядов и работает на чистом Python. Теперь ваша ферма из 100 серверов не превратится в хаос: вы будете знать о проблемах раньше пользователей, а критические ошибки будут исправляться автоматически.

    В следующей части мы займемся созданием веб-интерфейса и биллинга, чтобы автоматизировать процесс оплаты и выдачи серверов, полностью исключив ручной труд.

    4. Разработка API для автоматической аренды и управления временем жизни игровых серверов

    Разработка API для автоматической аренды и управления временем жизни игровых серверов

    Добро пожаловать в четвертую часть курса DevOps для гейминга. Мы уже прошли большой путь: научились упаковывать сервер CS 1.6 в Docker, масштабировать его до сотни копий и даже написали систему мониторинга, которая следит за здоровьем нашей фермы.

    Однако, пока что всем этим управляем мы — администраторы. Если пользователь захочет арендовать сервер, нам придется вручную запускать скрипт, выделять порт и следить за временем, чтобы выключить сервер, когда оплаченный период закончится. Это не масштабируемо. Нам нужна автоматизация бизнес-логики.

    В этой статье мы создадим REST API — центральный мозг нашей системы. Этот API станет прослойкой между инфраструктурой (Docker) и интерфейсами пользователей (Telegram-бот, веб-сайт). Мы научим систему самостоятельно создавать серверы по запросу, считать время аренды и безжалостно удалять контейнеры, когда время истекло.

    Зачем нам API?

    В предыдущих уроках мы работали с Python-скриптами напрямую. Почему нельзя просто встроить код управления Docker прямо в Telegram-бота?

  • Безопасность: Бот не должен иметь прямой доступ к Docker-сокету. Если бота взломают, злоумышленник получит root-доступ к серверу.
  • Универсальность: Сегодня у нас Telegram-бот, завтра мы захотим сделать веб-сайт или мобильное приложение. API позволит подключать любые клиенты к одной и той же логике.
  • Централизация состояния: API будет работать с базой данных, которая является единственным источником правды о том, кто и что арендовал.
  • !Архитектура: API выступает единой точкой входа для всех внешних запросов к инфраструктуре.

    Выбор технологий: FastAPI

    Для реализации мы выберем FastAPI. Это современный фреймворк для Python, который идеально подходит для наших задач по нескольким причинам:

    * Асинхронность: Работа с Docker и сетью — это операции ввода-вывода. Асинхронный код позволяет обрабатывать сотни запросов на аренду одновременно, не блокируя поток выполнения. * Автоматическая документация: FastAPI сам генерирует Swagger UI, что упростит нам тестирование. * Валидация данных: Мы будем уверены, что пользователь прислал число, а не текст в поле «количество часов».

    Установим необходимые библиотеки:

    Проектирование Базы Данных

    Нам нужно где-то хранить информацию об арендах. Docker-контейнеры эфемерны (временны), поэтому хранить данные в них нельзя. Мы будем использовать SQLAlchemy в качестве ORM (Object-Relational Mapping), чтобы работать с базой данных как с объектами Python.

    Нам понадобятся две основные сущности (таблицы):

  • User (Пользователь): Хранит ID из Telegram и баланс.
  • Rental (Аренда): Хранит связь между пользователем, контейнером и временем окончания аренды.
  • Определим модель данных для аренды:

    Математика времени: расчет срока аренды

    Когда пользователь просит сервер на 2 часа, нам нужно вычислить точное время, когда сервер должен быть выключен. В программировании и базах данных время часто хранится в формате Unix Timestamp (количество секунд с 1 января 1970 года) или в формате ISO 8601.

    Формула расчета времени окончания аренды выглядит так:

    Где: * — временная метка окончания аренды (момент, когда сервер превратится в тыкву). * — текущее время сервера в момент поступления запроса. * — длительность аренды в часах, запрошенная пользователем. * — количество секунд в одном часе (константа перевода).

    Например, если сейчас 12:00 (), и пользователь берет сервер на 2 часа (), то:

    Это кажется тривиальным, но ошибки в работе с часовыми поясами (UTC vs Local Time) — самая частая причина багов в биллинге. Мы будем хранить всё строго в UTC.

    Реализация API: Эндпоинт аренды

    Самая сложная часть — это функция, которая обрабатывает POST-запрос на создание сервера. Она должна выполнить ряд действий атомарно (или всё, или ничего).

    Алгоритм действий:

  • Проверить входные данные.
  • Найти свободный порт (как мы делали во второй статье).
  • Запустить Docker-контейнер.
  • Рассчитать .
  • Записать данные в БД.
  • Вернуть пользователю IP и порт.
  • Вот упрощенная реализация на FastAPI:

    Фоновая задача: The Reaper (Жнец)

    Мы запустили сервер, но кто его выключит? API пассивен — он отвечает только когда его спрашивают. Нам нужен активный процесс, который будет периодически проверять базу данных и «убивать» просроченные серверы.

    Этот процесс называется Background Task или Cron Job.

    Логика работы «Жнеца»:

  • Раз в минуту запросить из БД все активные аренды (is_active = True).
  • Для каждой аренды проверить условие истечения времени.
  • Математическое условие остановки:

    Где: * — сигнал к остановке сервера. * — текущее время в UTC. * — время окончания аренды, записанное в базе данных.

    Если истинно, мы отправляем команду docker stop и помечаем аренду как завершенную в БД.

    Реализуем это как отдельный поток внутри нашего приложения FastAPI (или отдельный скрипт):

    !Жизненный цикл аренды: от запроса пользователя до автоматического удаления фоновым процессом.

    Расчет стоимости аренды

    Хотя наш курс технический, мы строим бизнес-систему. Нам нужно списывать виртуальные или реальные средства. Добавим простую экономику.

    Пусть — стоимость одного часа аренды (например, 10 рублей). Тогда общая стоимость рассчитывается как:

    Где: * — итоговая сумма к списанию. * — длительность аренды. * — базовая ставка. * — коэффициент динамического ценообразования (опционально). Например, в вечер пятницы, когда нагрузка на серверы максимальна, и в остальное время.

    Этот расчет должен происходить до запуска контейнера. Если у пользователя недостаточно средств (), API должно вернуть ошибку 402 Payment Required.

    Обработка ошибок и восстановление

    Что произойдет, если API упадет и перезагрузится? Благодаря тому, что мы храним состояние в базе данных (PostgreSQL/SQLite), а не в оперативной памяти Python, система восстановится.

    При рестарте:

  • Docker-контейнеры продолжают работать (они независимы от API).
  • API поднимается и снова запускает задачу «Жнеца».
  • Жнец читает БД и удаляет те серверы, время которых истекло, пока API был выключен.
  • Это называется stateless архитектурой приложения (само приложение не хранит состояние, оно делегирует это базе данных).

    Заключение

    Мы создали «мозг» нашей хостинг-компании. Теперь у нас есть:

  • Docker для запуска игр.
  • Мониторинг для слежения за ресурсами.
  • API для управления арендой и жизненным циклом.
  • Теперь мы готовы к финальному шагу — созданию интерфейса. В следующей статье мы напишем Telegram-бота, который будет красиво общаться с этим API, позволяя пользователям арендовать серверы нажатием одной кнопки в мессенджере.

    5. Интеграция пользовательских интерфейсов: Telegram-бот и веб-панель для заказа серверов

    Интеграция пользовательских интерфейсов: Telegram-бот и веб-панель для заказа серверов

    Добро пожаловать в финальную часть нашего курса DevOps для гейминга. Мы проделали огромный путь: от настройки ядра Linux и создания Docker-образов до написания масштабируемого API и системы мониторинга. У нас есть мощный «двигатель» и умная «трансмиссия», но пока нет «руля».

    В этой статье мы создадим интерфейсы, через которые реальные люди будут взаимодействовать с нашей системой. Мы не будем заставлять игроков отправлять cURL-запросы в терминале. Вместо этого мы разработаем удобный Telegram-бот для быстрой аренды и Веб-панель для визуального контроля состояния фермы серверов.

    Архитектура Frontend-слоя

    Главное правило современной разработки: разделяй и властвуй. Наши интерфейсы (Frontend) не должны знать, как работает Docker или где лежит база данных. Они должны знать только одно — как общаться с нашим API.

    Это делает систему безопасной. Если злоумышленник взломает веб-сайт, он не получит доступ к root-правам сервера, так как веб-сайт — это просто «витрина», которая шлет запросы к API.

    !Поток данных от пользователя к инфраструктуре через слой интерфейсов и API.

    Часть 1: Telegram-бот на Python (aiogram)

    Telegram — идеальная платформа для игровых сервисов. Игрокам не нужно устанавливать лишние приложения, а уведомления о готовности сервера приходят мгновенно.

    Мы будем использовать библиотеку aiogram. Она асинхронна, что критически важно. Если бот будет ждать ответа от Docker синхронно (блокирующе), то пока один пользователь создает сервер, остальные 100 не смогут даже нажать кнопку «Старт».

    Установка зависимостей

    Логика машины состояний (FSM)

    Процесс аренды сервера — это диалог. Бот должен запоминать ответы пользователя на каждом шаге:

  • Сколько часов?
  • Какая карта?
  • Подтверждение оплаты.
  • Для этого используется Finite State Machine (FSM).

    Взаимодействие с API

    Бот не запускает контейнеры сам. Он отправляет JSON-запрос нашему API, который мы написали в прошлом уроке. Для асинхронных HTTP-запросов используем aiohttp.

    Вот пример функции, которая заказывает сервер:

    Расчет стоимости для пользователя

    Перед тем как попросить пользователя оплатить, бот должен показать итоговую цену. Допустим, у нас есть динамическое ценообразование. Формула расчета стоимости, которую бот отобразит пользователю:

    Где: * — итоговая цена, которую увидит пользователь. * — количество часов аренды, выбранное пользователем. * — базовая стоимость часа (например, 10 рублей). * — коэффициент скидки лояльности (от 0 до 1). Например, если у пользователя скидка 10%, то .

    Если пользователь берет сервер на 5 часов по ставке 10р со скидкой 10%, расчет будет таким:

    Часть 2: Веб-панель администратора

    Бот удобен для клиентов, но неудобен для администратора. Когда у вас 100 активных серверов, листать чат с ботом невозможно. Нам нужен Dashboard — панель управления с таблицами и графиками.

    Для DevOps-инженеров, которые не хотят погружаться в сложные JS-фреймворки (React/Vue), идеально подойдет Streamlit или простой HTML + JS.

    Мы сделаем простую HTML-страницу, которая забирает данные из API через JavaScript (AJAX).

    Получение списка серверов (JS Fetch API)

    Предположим, у нашего API есть эндпоинт GET /servers/, который возвращает список всех контейнеров.

    ``javascript async function loadServers() { const response = await fetch('http://api-host:8000/servers/'); const servers = await response.json(); const tableBody = document.getElementById('server-table'); tableBody.innerHTML = ''; // Очищаем таблицу

    servers.forEach(server => { const row = <tr> <td>{server.port}</td> <td>{server.expires_at}</td> <td> <button onclick="stopServer('M_{GB}M_{bytes}1024^3$ — делитель для перевода (1024 1024 * 1024).

    Безопасность интерфейсов

    Открывая API для внешнего мира (через веб-панель или бота), мы рискуем.

  • API Token: Бот и веб-панель должны отправлять секретный токен в заголовке каждого запроса (Authorization: Bearer SECRET_KEY). API должен отклонять запросы без ключа.
  • Rate Limiting: Один пользователь не должен иметь возможности заспамить бота кнопкой «Создать сервер», положив всю нашу инфраструктуру. В aiogram для этого есть middleware ThrottlingMiddleware.
  • Заключение курса

    Поздравляю! Мы завершили курс DevOps для гейминга.

    Давайте оглянемся на то, что мы построили:

  • ОС и Docker: Мы создали оптимизированный, легкий образ Linux для старой игры, решив проблемы с 32-битными библиотеками.
  • Масштабирование: Мы научились управлять портами и ресурсами, запуская десятки изолированных серверов на одной машине.
  • Мониторинг: Мы написали «сторожевого пса», который перезагружает зависшие серверы и шлет алерты.
  • API и UI: Мы обернули сложную инфраструктуру в удобный API и создали дружелюбные интерфейсы для людей.
  • Теперь у вас есть полноценный прототип хостинг-провайдера. Этот стек технологий (Docker + Python API + Bot + Monitoring) универсален. Замените CS 1.6 на Minecraft, Valheim или даже на веб-сервисы для разработчиков — архитектура останется прежней.

    Спасибо за внимание, и удачи в ваших DevOps-проектах!