☸️ Первое знакомство с Kubernetes: создаем приложение для развертывания в кластере
Изучив основы и подготовив тестовый полигон, мы переходим к практической части. Сегодня разберем, как создать первое приложение на Python + Flask и развернуть его в кластере k8s. Обсудить Мы изучили, что находится под капотом у оркестратора Kubernetes, разобрали базовые объекты и научились разворачивать кластер k8s для экспериментов. Стоит перейти к практике и написать простенькое веб-приложение на стеке Python и Flask, а затем задеплоить его в кластер. Поскольку Python – единственный язык программирования, на котором я что-то умею писать, особого выбора у меня нет. Приложения будет запускаться как веб-сервер, слушать указанный порт и при обращении выдавать приветствие “Hello from Python”. Кроме Python потребуется фреймворк Flask. Код приложения: app.py В первых двух строчках мы подключаем Flask, а далее создаем обработку корневого запроса. Приложение неидеально, но как минимальный вариант для развертывания в кластере k8s оно сгодится. Так как k8s – это среда запуска контейнеров, для переноса приложение необходимо упаковать, например, в Docker. Чтобы собрать контейнер, нужно поставить Docker на локальную машину (да, да – Капитан очевидность). Инструкция по инсталляции есть на официальном сайте – процесс довольно несложен. Далее собирать образ можно средствами Docker, я использую для этих целей утилиту buildah. Она ни разу меня не подводила, рекомендую. Для сборки контейнера на хосте должны быть установлены Docker и buildah. Все действия я провожу в CentOS, в других дистрибутивах Linux они могут немного отличаться. Для начала создаем директорию, из которой будем собирать контейнер. Первый файл в директории назовем, например, requirements.txt Третий файл называется Dockerfile Разберем его построчно: Готово, директория в итоге должна содержать следующие файлы: Находясь в директории с файлами, выполняем команду для сборки контейнера на основе Dockerfile с помощью утилиты buildah: Запустится сборка, прогрузятся все зависимости из Дальше необходимо запушить сборку в локальный репозиторий Docker. Выполняем следующую команду, подставляя в параметры свой хеш: Контейнер уже можно увидеть в списке локального репозитория Docker, выполнив следующую команду: Итак, у нас на локальном хосте есть собранный контейнер который мы можем запустить для проверки работоспособности с помощью curl. Приложение откликается, значит контейнер рабочий. Последний штрих – запушить контейнер из локального репозитория в удаленный, например, в Docker Hub. Это нужно, чтобы мы могли скачать контейнер в кластер k8s и запуститься его уже там. Чтобы это сделать, потребуется авторизоваться на Docker Hub и создать пустой репозиторий. Детально описывать эту процедуру не буду: процесс похож на создание Git-репозитория. Теперь можно на любом хосте с Docker запустить контейнер и в качестве расположения указать уже не локальный репозиторий, а Docker Hub. Дальнейшие действия проводятся в кластере k8s. Как его развернуть, мы уже писали. Цель – развернуть приложение Python из контейнера, но уже в кластере k8s в нескольких репликах. Для этого необходимо создать два объекта (подробнее мы рассматривали их в предыдущей статье): Дополнительные материалы Чтобы не путаться в терминах, вспомним, что под капотом у системы оркестрации Kubernetes. Заходим по SSH на мастер-узел (ноду), проверяем работоспособность deployment.yaml Разбираем подробнее: Сохраняем файл Если ошибок в файле не было, успешный исход – активное приложение в 2 репликах. Посмотреть состояние можно следующей командой: Приложение развернуто в двух репликах – с помощью curl можно обратиться к каждой из них по IP пода, но это плохой вариант (поды рано или поздно переедут на другие узлы и IP поменяются). Давайте напишем еще один объект кластера, который закроет эту проблему – Из статьи по базовым объектам кластера k8s мы уже знаем, что объекты Service нужны для мапинга всех реплик приложения на один IP ( Создаем еще один файл service.yaml Его главные отличительные особенности: Запускаем процедуру создания следующей командой: Далее смотрим детали Супер! У нас есть IP, по которому можно обращаться к сервису в кластере с любого пода. Подведем итог статьи. Мы добились следующих результатов: Использованные в статье файлы YAML можно скачать здесь. Поздравляю, вы развернули первое приложение в кластере k8s! Возможно оно простовато, но в следующих статьях мы будем доводить его до ума.Пишем приложение (Python + Flask)
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello from Python" if __name__ == "__main__": app.run(host='0.0.0.0')
Упаковываем приложение в контейнер Docker
app.py
(его код приведен выше). Для установки зависимостей нам потребуется файл requirements.txt
. Поскольку приложение простенькое, достаточно добавить только модуль Flask:
Flask==1.0.2
Dockerfile
– без расширения. Его содержимое:
FROM python:3.9-alpine RUN mkdir /app WORKDIR /app ADD . /app/ RUN pip install -r requirements.txt EXPOSE 5000 CMD ["python", "/app/app.py"]
/app
внутри контейнера./app
. Ее в кластере нет, и контейнер падает с ошибкой (не найден файл /app/app.py
).pip
и скармливаем ему файл зависимостей. Flask скачивается и устанавливается в контейнер.app.py
.app.py
, requirements.txt
, Dockerfile
.
buildah bud -f ./Dockerfile .
requirements.txt
, и в итоге сгенерируется хеш – строка Storing signatures
, которая нам в дальнейшем понадобится (копируем ее в буфер обмена)
buildah push dedd9a5526d3c97231e9a0b73ca1e4a91ece0d70a7f7bff254f61f7d28d8e9fb docker-daemon:app:v0
docker image ls
docker run --rm -d -v `pwd`:/app -p 5000:5000 app:v0
docker login <выполните авторизацию>. Делается один раз, пароль и логин запоминаются
docker tag app:v0 <ваш логин docker hub>/<ваш репозиторий>/app:v0 buildah push <image ID> <ваш логин docker hub>/<ваш репозиторий>:app
docker run --rm -d -v `pwd`:/app -p 5000:5000 test/learn_images:app:v0
Создаем Deployment для приложения в кластере k8s
kubectl
. Далее необходимо создать deployment.yaml
.
apiVersion: apps/v1 kind: Deployment metadata: name: app labels: app: app spec: replicas: 2 selector: matchLabels: app: app template: metadata: labels: app: app spec: containers: - name: app image: <ваш логин docker hub>/<ваш репозиторий>:app ports: - containerPort: 5000 protocol: TCP name: http resources: limits: cpu: 50m memory: 20Mi requests: cpu: 50m memory: 20Mi
Deployment
, но может быть и Service
или, скажем, Pod
.Deployment
(именно так он будет отображаться в кластере k8s).limits
). Без этих ресурсов приложение не стартует и планировщик кластера будет искать подходящий узел, удовлетворяющую минимальным ресурсам. Запрашиваемые (requests
) – это ресурсы, которые резервируются на ноде для вашего приложения. Сверх этих ограничений приложение не получит ресурсов CPU и RAM.deployment.yaml
и выполняем команду для развертывания приложения:
kubectl create -f deployment.yaml
kubectl get pod -o wide
Service
.Создаем Service приложения в кластере k8s
endpoint
). service.yaml
.
apiVersion: v1 kind: Service metadata: labels: app: app name: app spec: ports: - port: 8080 protocol: TCP targetPort: 5000 selector: app: app type: ClusterIP
Service
будет принимать трафик. Deployment
и все реплики по этой метке.Service
. В нашем случае для сетевого взаимодействия внутри кластера k8s.
kubectl create -f service.yaml
Service
:
kubectl get svc -o wide
- 6 views
- 0 Comment
Свежие комментарии