Базовое развертывание приложения Flask с помощью Kubernetes и Docker

В последние десять лет контейнерные приложения и кластеры быстро заменили старую парадигму масштабирования приложений на основе виртуальных машин. Контейнеры предлагают такую же изоляцию процесса, но, как правило, они гораздо легче, а еще они более портируемые и производительные, чем полная виртуализация. Кластеры, которые можно использовать для управления тысячами работающих контейнеров на множестве физических машин, абстрагируют большую часть работы по развертыванию новых версий приложений, их масштабированию и эффективному планированию рабочих задач. Учитывая все это, Kubernetes быстро превратилась в зрелую, готовую к производству систему. Она предоставляет широкий набор функций, таких как непрерывное развертывание, проверка работоспособности, самоконтроль, автоматическое масштабирование рабочей нагрузки и многое другое.

Этот мануал поможет вам выполнить базовое развертывание простого приложения Flask на основе этой технологии.

Требования

  • Кластер Kubernetes10+ с включенным управлением доступом на основе ролей (RBAC).
  • Инструмент командной строки kubectl на локальной машине или на сервере разработки. Этот инструмент нужно подключить к кластеру. Больше о kubectl можно узнать в официальной документации.
  • Установка Dockerна локальной машине или на сервере разработки. Инструкции по установке вы найдете в мануале Установка и использование Docker в Ubuntu 18.04. Обязательно добавьте своего пользователя в группу docker. Дополнительную информацию ищите в официальной документации.
  • Аккаунт Docker Hub (опционально – он понадобится только если вы планируете редактировать образ Flask Docker, описанный в этом руководстве). Создать аккаунт вам поможет мануал Docker Hub.

1: Клонирование репозитория и сборка образа приложения Flask

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

git clone https://github.com/do-community/k8s-intro-meetup-kit.git
cd k8s-intro-meetup-kit
ls
LICENSE  README.md  app  k8s

Каталог приложения содержит код тестового приложения Flask, а также файл Docker для создания образа контейнера. Каталог k8s содержит файлы манифеста Kubernetes для пода, развертывания и сервиса.

Читайте также: Краткий обзор Kubernetes

Перейдите в каталог приложения и выведите на экран содержимое файла app.py:

cat app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0')

Этот код определяет единственный маршрут по умолчанию, который выведет фразу «Hello World». Кроме того, приложение работает в режиме отладки, что позволяет включить подробный вывод.

Аналогичным образом запросите содержимое Dockerfile приложения:

cat Dockerfile
FROM python:3-alpine
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]

Этот Dockerfile для начала ссылается на легкий родительский образ Alpine Linux Python. Затем он копирует файл требований Python, устанавливает Flask, копирует код приложения в образ контейнера, определяет порт 5000 в качестве порта контейнера и, наконец, устанавливает python app.py как команду по умолчанию.

Соберите образ приложения:

cd app
docker build -t flask_demo:v0 .

Мы присвоили образу имя flask_demo и тег v0, используя опцию -t.

Когда Docker завершит сборку, запустите контейнер с помощью команды run:

docker run -p 5000:5000 flask_demo:v0

Эта команда запускает контейнер с помощью образа flask:v0 и перенаправляет локальный порт 5000 на порт контейнера 5000.

Если вы используете Docker на своем локальном компьютере, перейдите по адресу http://localhost:5000 в веб-браузере. Вы должны увидеть сообщение «Hello World», сгенерированное приложением Flask.

Если вы используете Docker на сервере разработки, откройте ссылку http://dev_server_external_IP:5000. Если вы используете брандмауэр (например, UFW), не забудьте разблокировать внешний доступ через порт 5000.

Читайте также: Основы UFW: общие правила и команды фаервола

На этом этапе вы можете поэкспериментировать с такими командами Docker, как docker ps, docker top и docker images, чтобы попрактиковаться в работе с образами и контейнерами в вашей системе.

Далее мы развернем это тестовое приложение в вашем кластере Kubernetes. Мы будем использовать готовый образ с Docker Hub. Если вы хотите выполнить пользовательскую настройку приложения Flask и использовать свой собственный образ, вам нужно создать аккаунт Docker Hub и выполнить действия, описанные здесь, чтобы перенести ваш образ в общедоступный репозиторий. Из него Kubernetes сможет загрузить образ контейнера и развернуть его в кластере.

2: Развертывание приложения Flask в Kubernetes

Приложение и образ Docker, описанные в предыдущем разделе, уже созданы и находятся в общем доступе в репозитории Docker Hub flask-helloworld. При желании вы можете создать свой собственный репозиторий для приложения и указать его вместо flask-helloworld.

Сначала мы развернем наше тестовое приложение «Hello World» в кластере в виде отдельного пода, а затем – в виде развертывания с несколькими подами.

Прежде чем запускать какие-либо рабочие задачи в кластере, мы создадим пространство имен, в котором будут выполняться объекты. Пространства имен позволяют сегментировать кластер и ограничивают область запуска тех или иных рабочих задач.

Создайте пространство имен flask:

kubectl create namespace flask

Теперь запросите список всех пространств имен в вашем кластере:

kubectl get namespace

Вы должны увидеть ваше новое пространство имен, а также несколько пространств по умолчанию (kube-system и default). В этом мануале мы будем работать исключительно в пространстве имен flask.

Вернитесь в каталог k8s:

cd ../k8s

В нем вы увидите три манифеста Kubernetes:

  • flask-pod.yaml: манифест пода приложения
  • flask-deploy.yaml: манифест развертывания
  • flask-service.yaml: манифест сервиса LoadBalancer приложения

Давайте посмотрим на манифест пода:

cat flask-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: flask-pod
labels:
app: flask-helloworld
spec:
containers:
- name: flask
image: hjdo/flask-helloworld:latest
ports:
- containerPort: 5000

Здесь мы определяем базовый под flask-pod и помечаем его с помощью пары ключ-значение app: flask-helloworld.

Затем мы указываем единый контейнер flask  и образ helloworld:latest из репозитория hjdo/flask-helloworld на Docker Hub. Если вы используете образ, хранящийся в другом репозитории Docker Hub, вы можете сослаться на него, используя это поле image. Затем мы открываем порт 5000 для входящих соединений.

Разверните этот под в пространстве имен flask, используя kubectl apply -f и флаг –n (он задает пространство имен):

kubectl apply -f flask-pod.yaml -n flask

Примерно через десять секунд под будет запущен в вашем кластере:

kubectl get pod -n flask
NAME        READY   STATUS    RESTARTS   AGE
flask-pod   1/1     Running   0          4s

Поскольку этот под работает внутри кластера Kubernetes, нам нужно перенаправить локальный порт на порт контейнера, в котором работает под, чтобы получить доступ к запущенному приложению локально:

kubectl port-forward pods/flask-pod -n flask 5000:5000

Мы используем port-forward для переадресации локального порта 5000 на порт 5000 контейнера.

Перейдите по ссылке http://localhost:5000, и вы должны снова увидеть сообщение «Hello World», сгенерированное приложением Flask. Если вы используете kubectl на удаленном сервере dev, замените localhost на внешний IP-адрес вашего сервера.

Попробуйте использовать разные команды kubectl (например, kubectl description), чтобы изучить свой под. Когда вы закончите, удалите под, используя delete:

kubectl delete pod flask-pod -n flask

Затем мы развернем этот под масштабируемым образом с помощью другого элемента Kubernetes, развертывания (Deployment). Выведите на экран содержимое манифеста flask-deploy.yaml:

cat flask-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-dep
labels:
app: flask-helloworld
spec:
replicas: 2
selector:
matchLabels:
app: flask-helloworld
template:
metadata:
labels:
app: flask-helloworld
spec:
containers:
- name: flask
image: hjdo/flask-helloworld:latest
ports:
- containerPort: 5000

В этом файле мы определяем развертывание по имени flask-dep с помощью метки app: flask-helloworld. Затем мы запрашиваем 2 реплики пода (они идентичны шаблону, который мы ранее использовали для развертывания пода приложения Flask). Поле selector сопоставляет шаблон приложения app: flask-helloworld  с развертыванием.

Разверните Deployment с помощью kubectl apply -f:

kubectl apply -f flask-deployment.yaml -n flask

Через некоторое время развертывание должно быть запущено в вашем кластере:

kubectl get deploy -n flask
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
flask-dep   2/2     2            2           5s

Вы также можете развернуть отдельные поды, управляемые контроллером развертывания:

kubectl get pod -n flask
NAME                        READY   STATUS    RESTARTS   AGE
flask-dep-876bd7677-bl4lg   1/1     Running   0          76s
flask-dep-876bd7677-jbfpb   1/1     Running   0          76s

Чтобы получить доступ к приложению, нужно перенаправить порт внутри кластера:

kubectl port-forward deployment/flask-dep -n flask 5000:5000

Эта команда перенаправит локальный порт 5000 на порт 5000 контейнера на одном из работающих подов.

Вы должны иметь доступ к приложению по ссылке http://localhost:5000. Если вы используете kubectl на удаленном сервере dev, замените localhost внешним IP-адресом вашего сервера dev.

На этом этапе вы можете попробовать запустить такие команды, как kubectl rollout и kubectl scale , чтобы поэкспериментировать с откатом развертываний и их масштабированием.

Заключение

Теперь у вас есть простое тестовое приложение flask, развернутое с помощью Kubernetes. На его основе вы можете разработать более сложное приложение или просто поэкспериментировать с командами.

Tags: , , ,