Развёртывание двухуровневого приложения в Kubernetes с MongoDB и Flask
Введение
Многоуровневое (multi-tier) приложение разделено на логические слои — обычно фронтенд, бэкенд и базу данных. В этой инструкции мы реализуем простое 2-уровневое приложение: MongoDB как бэкенд-хранилище и Python Flask как фронтенд (веб-сервер). Всё разворачивается в Kubernetes с помощью Deployment и Service.

Предварительные требования
- Кластер Kubernetes с минимум одним рабочим узлом (node). Для тестов можно использовать локальные среды (minikube, kind) или облачные EC2/VM. Если вам нужно создать кластер вручную — воспользуйтесь официальными руководствами облачного провайдера или minikube.
- Базовое понимание Deployment и Service в Kubernetes. Знание kubectl и умение применять манифесты YAML.
Важно: этот пример использует публичные Docker-образы и не учитывает обязательного постоянного хранилища для MongoDB — в продакшне обязательно использовать PersistentVolumeClaim и, как минимум, StatefulSet.
Что мы сделаем
- Создадим Deployment для MongoDB (база данных).
- Создадим Service для доступа к MongoDB внутри кластера.
- Создадим Deployment для Python Flask приложения (frontend).
- Создадим Service типа NodePort для доступа к веб-интерфейсу извне.
- Проверим работу, добавим тестовые записи и удалим объекты.
Развёртывание — шаг за шагом
Ниже приведены четыре файла-манифеста, которые нужно разместить в одной директории и применить с помощью kubectl.
1) Deployment для MongoDB (test-db-deployment.yaml)
Создайте файл test-db-deployment.yaml со следующим содержимым. Этот Deployment создаёт один под с образом mongo:3.3 и задаёт переменную окружения MONGODB_DATABASE.
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-db
spec:
selector:
matchLabels:
appdb: testdb
replicas: 1
template:
metadata:
labels:
appdb: testdb
spec:
containers:
- name: test-db
image: mongo:3.3
env:
- name: MONGODB_DATABASE
value: testdata
ports:
- containerPort: 27017
Примечание: в продакшне вместо Deployment для базы данных следует использовать StatefulSet и обеспечить PersistentVolumeClaim для сохранности данных при перезапуске.
2) Service для MongoDB (test-db-service.yaml)
Создайте Service, который будет доступен для других подов в кластере на порту 27017.
apiVersion: v1
kind: Service
metadata:
name: mongodb
labels:
app: testdb
spec:
ports:
- port: 27017
protocol: TCP
selector:
appdb: testdb
Этот Service называется mongodb и другие поды смогут ссылаться на него по DNS-имени mongodb в том же неймспейсе.
3) Deployment для Python Flask (test-web-deployment.yaml)
Фронтенд использует публичный образ teamcloudyuga/rsvpapp и ожидает переменную окружения MONGODB_HOST с именем сервисa mongodb.
apiVersion: apps/v1
kind: Deployment
metadata:
name: test
spec:
selector:
matchLabels:
app: test
replicas: 1
template:
metadata:
labels:
app: test
spec:
containers:
- name: test-app
image: teamcloudyuga/rsvpapp
env:
- name: MONGODB_HOST
value: mongodb
ports:
- containerPort: 5000
name: web-port
Если приложение требует секреты (пароли), используйте Kubernetes Secrets вместо явного указания в манифесте.
4) Service для фронтенда типа NodePort (test-web-service.yaml)
Этот Service открывает порт 31081 на каждом узле кластера и пробрасывает трафик к контейнерам на порт 5000.
apiVersion: v1
kind: Service
metadata:
name: test
labels:
apps: test
spec:
type: NodePort
ports:
- name: tcp-31081-5000
nodePort: 31081
port: 5000
protocol: TCP
selector:
app: test
NodePort удобен для тестирования: вы заходите на IP любого узла кластера и порт 31081.
Проверка объектов в кластере перед развёртыванием
Проверьте текущие объекты в кластере:
kubectl get pods
kubectl get deployments
kubectl get service

Если в кластере только дефолтные объекты — можно продолжать.
Применение манифестов
Из директории с четырьмя файлами выполните по очереди:
kubectl create -f test-db-deployment.yaml
kubectl create -f test-db-service.yaml
kubectl create -f test-web-deployment.yaml
kubectl create -f test-web-service.yaml

Проверим, что объекты созданы:
kubectl get pods
kubectl get deployments
kubectl get service

Вы должны увидеть по одному поду для MongoDB и для фронтенда, а также два сервиса.
Доступ к приложению
Откройте в браузере URL: http://
В примере приложение отображает RSVP-счётчик — при первом запуске счётчик будет 0, так как в MongoDB ещё нет записей.

Добавьте несколько записей через интерфейс — счётчик должен увеличиться, что подтверждает запись данных в базу.

Удаление созданных объектов
Когда объекты больше не нужны, из той же директории выполните:
kubectl delete -f .
Эта команда удалит Deployment и Service, которые вы создали. Проверьте состояние:
kubectl get all

Критерии приёмки
- Два пода запущены и готовы (READY): один для MongoDB, один для Flask.
- Сервис mongodb доступен в кластере и резолвится по DNS имени mongodb.
- NodePort (31081) на узле возвращает рабочую страницу приложения.
- При добавлении записей через UI данные читаются из MongoDB.
Чек-листы по ролям
Администратор кластера
- Убедиться, что узлы имеют сетевой доступ и nodePort разрешён в брандмауэре.
- Проверить версию Kubernetes и совместимость с используемыми API.
DevOps/инженер
- Настроить PersistentVolume и заменить Deployment MongoDB на StatefulSet для продакшна.
- Вынести конфигурации и пароли в ConfigMap/Secret.
- Настроить мониторинг (Prometheus, liveness/readiness probes).
Разработчик
- Проверить переменные окружения и поведение приложения при недоступности БД.
- Добавить обработку ошибок при подключении к MongoDB.
QA
- Проверить сценарии записи/чтения данных.
- Прогнать тесты отказоустойчивости (рестарт пода базы, проверки сохранности данных при использовании PVC).
Советы по отладке и частые проблемы
Поды находятся в статусе CrashLoopBackOff:
- Просмотрите логи: kubectl logs
- Проверьте переменные окружения и доступность сервиса mongodb для фронтенда.
- Просмотрите логи: kubectl logs
Приложение не видит MongoDB по имени mongodb:
- Убедитесь, что Service назван mongodb и в том же неймспейсе.
- Выполните dns-резолв внутри кластера: kubectl run -i –tty dnsutils –image=tutum/dnsutils –restart=Never – sh и выполните nslookup mongodb.
Данные не сохраняются после перезапуска пода MongoDB:
- Используйте PersistentVolumeClaim и StatefulSet; в облаке — привяжите диск к PVC.
NodePort недоступен извне:
- Проверьте настройки сети/маршрутизации и правила брандмауэра (Security Group, firewall). Убедитесь, что порт 31081 открыт.
Альтернативные подходы и когда этот пример не годится
- Если нужна отказоустойчивость БД: используйте MongoDB ReplicaSet и StatefulSet с PVC.
- Для продакшна лучше не использовать NodePort — применяйте LoadBalancer или Ingress с контроллером и TLS.
- Если требуется секретность: храните учётные данные в Kubernetes Secret или интегрируйте HashiCorp Vault.
- Для сложных приложений применяйте Helm-чарты для управления параметризацией и релизами.
Мини-методология развёртывания (шаблон действий)
- Подготовить манифесты: Deployment, Service, PVC, Secret.
- Проверить локально (minikube или kind).
- Применить в staging/QA.
- Прогнать smoke-тесты, мониторинг и алерты.
- Перенести в продакшн с использованием CI/CD и GitOps-процессов.
Короткий глоссарий
- Deployment — контроллер для управления подами и их обновлений.
- Service — абстракция доступа к одному или группе подов.
- NodePort — тип Service, открывающий порт на каждом узле.
- StatefulSet — контроллер для приложений с сохранением состояния и порядком старта.
- PVC — PersistentVolumeClaim, запрос дискового хранилища.
Безопасность и хранение данных
- В продакшне MongoDB должна работать с PVC, иметь настройки резервного копирования и сетевые правила доступа.
- Никогда не храните пароли в манифестах в открытом виде — используйте Secrets.
- Ограничьте доступ к NodePort/LoadBalancer с помощью брандмауэра.
Пример принятия решения: Service vs Ingress vs LoadBalancer
flowchart TD
A[Требуется доступ извне?] -->|Нет| B[Service типа ClusterIP]
A -->|Да| C{Есть cloud-интеграция}
C -->|Да| D[Service типа LoadBalancer]
C -->|Нет| E[Ingress + NodePort]Итоги
Мы развернули рабочую двухуровневую систему: MongoDB как бэкенд и Flask-приложение как фронтенд, настроили сервисы для внутреннего и внешнего доступа, проверили запись данных и описали практические рекомендации для продакшна. Для боевого использования обязательно добавить устойчивое хранение, секреты и мониторинг.
Важно: пример предназначен для обучения и демонстрации концепции. Для промышленного использования требуются расширенные меры надёжности, безопасности и резервного копирования.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента