Полнофункциональный ML-сервис для предсказания типа ириса с контейнеризацией, IaC и нагрузочным тестированием.
Это учебный DevOps-проект, демонстрирующий:
- Разработку ML-сервиса с RESTful API (FastAPI)
- Контейнеризацию с Docker
- Автоматизацию развертывания с Ansible (Infrastructure as Code)
- Нагрузочное тестирование с Locust
- Анализ дрейфа данных с Evidently AI
- Документирование архитектурных решений (ADR)
Проект реализован как монолитный сервис с модульной структурой:
┌─────────────────────────────────────┐
│ ML Prediction Service │
│ │
│ ┌──────────┐ ┌─────────────┐ │
│ │ API │ │ ML Model │ │
│ │ (FastAPI)│──│ (RandomForest) │
│ └──────────┘ └─────────────┘ │
│ │
│ ┌──────────┐ ┌─────────────┐ │
│ │ Drift │ │ Monitoring │ │
│ │ Analysis │ │ (Health) │ │
│ └──────────┘ └─────────────┘ │
└─────────────────────────────────────┘
│
▼
Docker Container
│
▼
Ansible Automation
.
├── README.md # Основная документация
├── requirements.txt # Python зависимости
├── Dockerfile # Конфигурация Docker образа
├── docker-compose.yml # Docker Compose для локального запуска
├── locustfile.py # Конфигурация нагрузочного тестирования
│
├── app/ # Код приложения
│ ├── main.py # Основной API сервис
│ └── drift_analysis.py # Модуль анализа дрейфа данных
│
├── adr/ # Архитектурные решения (ADR)
│ ├── 0001-выбор-архитектурного-стиля.md
│ ├── 0002-выбор-веб-фреймворка.md
│ └── 0003-выбор-IaC-инструмента.md
│
└── ansible/ # Infrastructure as Code
├── ansible.cfg # Конфигурация Ansible
├── inventory.ini # Инвентарь хостов
├── deploy.yml # Playbook развертывания
├── stop.yml # Playbook остановки
└── status.yml # Playbook проверки статуса
GET /- Информация о сервисеGET /health- Healthcheck для мониторингаGET /docs- Интерактивная Swagger документацияPOST /api/v1/predict- Одиночное предсказаниеPOST /api/v1/predict/batch- Пакетное предсказаниеGET /api/v1/model/info- Информация о моделиGET /api/v1/stats- Статистика обучающих данных
curl -X POST "http://localhost:8000/api/v1/predict" \
-H "Content-Type: application/json" \
-d '{
"sepal_length": 5.1,
"sepal_width": 3.5,
"petal_length": 1.4,
"petal_width": 0.2
}'# Клонируйте проект
cd /home/yuriy-samorodov/MIPT/Sem3/devops/exam
# Запустите сервис
docker-compose up -d
# Проверьте статус
docker-compose ps
# Откройте документацию
xdg-open http://localhost:8000/docs# Установите Ansible (если еще не установлен)
sudo apt install ansible
# Запустите развертывание
cd ansible
ansible-playbook deploy.yml
# Проверьте статус
ansible-playbook status.yml
# Остановите сервис
ansible-playbook stop.yml# Соберите образ
docker build -t ml-prediction-service .
# Запустите контейнер
docker run -d -p 8000:8000 \
--name ml-service \
-v $(pwd)/models:/app/models \
-v $(pwd)/reports:/app/reports \
ml-prediction-service
# Проверьте healthcheck
curl http://localhost:8000/health# Убедитесь, что сервис запущен
curl http://localhost:8000/health
# Запустите Locust
locust -f locustfile.py
# Откройте веб-интерфейс
xdg-open http://localhost:8089- Number of users: 100 (количество симулируемых пользователей)
- Spawn rate: 10 (скорость увеличения пользователей в секунду)
- Host: http://localhost:8000
- Run time: 60s (ограничение по времени)
После завершения теста скачайте отчет (Download Report) и проанализируйте:
- Request per second: количество обработанных запросов в секунду
- Response time percentiles: распределение времени ответа
- Failure rate: процент неуспешных запросов
- RPS график: динамика нагрузки во времени
Для демонстрации анализа дрейфа данных с Evidently AI:
# Активируйте виртуальное окружение (если используется)
source venv/bin/activate
# Установите зависимости
pip install -r requirements.txt
# Запустите анализ дрейфа
python app/drift_analysis.py
# Откройте сгенерированные отчеты
xdg-open reports/data_drift_report_*.htmlАнализатор создаст два типа отчетов:
- Без дрейфа: данные соответствуют обучающему распределению
- С дрейфом: искусственно внесенное смещение данных
Все архитектурные решения задокументированы в директории adr/:
-
ADR-0001: Выбор монолитной архитектуры
- Сравнение: монолит vs микросервисы
- Решение: монолит с модульной структурой
-
ADR-0002: Выбор FastAPI как веб-фреймворка
- Сравнение: FastAPI vs Flask
- Решение: FastAPI для асинхронности и автодокументации
-
ADR-0003: Выбор Ansible для IaC
- Сравнение: Ansible vs Terraform/OpenTofu
- Решение: Ansible для универсальности и простоты
- Linux (Инструкции даны для Debian-based систем. Рекомендуется использовать Ubuntu 20.04+ или новее)
- Docker 20.10+
- Docker Compose 2.0+
- Python 3.11+
- Ansible 2.9+ (как алльтернатива Docker)
Все зависимости указаны в requirements.txt
Сервис включает встроенный healthcheck:
# Проверка состояния
curl http://localhost:8000/health
# Ожидаемый ответ:
{
"status": "healthy",
"model_loaded": true,
"timestamp": "2025-12-03T..."
}Docker автоматически выполняет healthcheck каждые 30 секунд.
# Просмотр логов Docker
docker logs ml-service
# Следить за логами в реальном времени
docker logs -f ml-service
# Запуск сервиса локально (для отладки)
cd app
python main.pyРеализованные меры безопасности:
- Контейнер запускается под непривилегированным пользователем
- Валидация входных данных через Pydantic
- Healthcheck для обнаружения проблем
- Минимальный базовый образ (python:3.11-slim)
Для интеграции в CI/CD pipeline:
# Пример для GitHub Actions
steps:
- name: Build Docker image
run: docker build -t ml-service .
- name: Run tests
run: docker run ml-service pytest
- name: Deploy with Ansible
run: ansible-playbook ansible/deploy.ymlХарактеристики под нагрузкой (на тестовом окружении):
- Throughput: ~50-100 RPS
- Latency p50: ~50-100ms
- Latency p95: ~200-500ms
- Latency p99: ~500-1000ms
Результаты зависят от железа и конфигурации.
Для горизонтального масштабирования:
# Docker Compose - несколько реплик
docker-compose up --scale ml-service=3
# Kubernetes - deployment с репликами
kubectl scale deployment ml-service --replicas=5# Создайте виртуальное окружение
python -m venv venv
source venv/bin/activate
# Установите зависимости
pip install -r requirements.txt
# Запустите сервис
cd app
uvicorn main:app --reload --host 0.0.0.0 --port 8000# Unit тесты
pytest tests/
# Интеграционные тесты
pytest tests/integration/
# Нагрузочное тестирование
locust -f locustfile.py --headless -u 100 -r 10 --run-time 60s# Проверьте логи
docker logs ml-service
# Проверьте порты
sudo netstat -tulpn | grep 8000
# Пересоберите образ
docker-compose build --no-cache# Увеличьте лимиты файловых дескрипторов
ulimit -n 65535
# Проверьте доступность сервиса
curl -v http://localhost:8000/healthСамородов Юрий Сергеевич Группа М08-401НД Московский Физико-Технический Институт