Share This
Связаться со мной
Крути в низ
Categories
//☸️ Первое знакомство с Kubernetes: создаем приложение для развертывания в кластере

☸️ Первое знакомство с Kubernetes: создаем приложение для развертывания в кластере

Изучив основы и подготовив тестовый полигон, мы переходим к практической части. Сегодня разберем, как создать первое приложение на Python + Flask и развернуть его в кластере k8s. Обсудить

pervoe znakomstvo s kubernetes sozdaem prilozhenie dlja razvertyvanija v klastere ae55a70 - ☸️ Первое знакомство с Kubernetes: создаем приложение для развертывания в кластере

Мы изучили, что находится под капотом у оркестратора Kubernetes, разобрали базовые объекты и научились разворачивать кластер k8s для экспериментов. Стоит перейти к практике и написать простенькое веб-приложение на стеке Python и Flask, а затем задеплоить его в кластер.

Пишем приложение (Python + Flask)

Поскольку Python – единственный язык программирования, на котором я что-то умею писать, особого выбора у меня нет. Приложения будет запускаться как веб-сервер, слушать указанный порт и при обращении выдавать приветствие «Hello from Python». Кроме Python потребуется фреймворк Flask.

Код приложения:

app.py

         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')      

В первых двух строчках мы подключаем Flask, а далее создаем обработку корневого запроса. Приложение неидеально, но как минимальный вариант для развертывания в кластере k8s оно сгодится. Так как k8s – это среда запуска контейнеров, для переноса приложение необходимо упаковать, например, в Docker.

Упаковываем приложение в контейнер Docker

Чтобы собрать контейнер, нужно поставить Docker на локальную машину (да, да – Капитан очевидность). Инструкция по инсталляции есть на официальном сайте – процесс довольно несложен. Далее собирать образ можно средствами Docker, я использую для этих целей утилиту buildah. Она ни разу меня не подводила, рекомендую.

Для сборки контейнера на хосте должны быть установлены Docker и buildah. Все действия я провожу в CentOS, в других дистрибутивах Linux они могут немного отличаться.

Для начала создаем директорию, из которой будем собирать контейнер. Первый файл в директории назовем, например, app.py (его код приведен выше). Для установки зависимостей нам потребуется файл requirements.txt. Поскольку приложение простенькое, достаточно добавить только модуль Flask:

requirements.txt

         Flask==1.0.2     

Третий файл называется Dockerfile – без расширения. Его содержимое:

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"]      

Разберем его построчно:

  • FROM python:3.9-alpine – добавляем в контейнер интерпретатор Python 3.9, сборка alpine.
  • RUN mkdir /app – создаем директорию /app внутри контейнера.
  • WORKDIR /app – позволяет один раз указать конкретный путь (каталог на диске), после чего большинство инструкций (например, RUN или COPY) будут выполняться в контексте этого каталога.
  • ADD . /app/ – очень важная команда, если мы делаем контейнер для k8s. Дело в том что когда отрабатывает запуск контейнера, k8s думает, что нам необходима внешняя директория /app. Ее в кластере нет, и контейнер падает с ошибкой (не найден файл /app/app.py).
  • RUN pip install -r requirements.txt – запускаем pip и скармливаем ему файл зависимостей. Flask скачивается и устанавливается в контейнер.
  • EXPOSE 5000 – пробрасываем порт 5000 для общения с нашим приложением.
  • CMD [«python», «/app/app.py»] – запускаем интерпретатор Python и наше приложение app.py.

Готово, директория в итоге должна содержать следующие файлы: app.py, requirements.txt, Dockerfile.

Находясь в директории с файлами, выполняем команду для сборки контейнера на основе Dockerfile с помощью утилиты buildah:

         buildah bud -f ./Dockerfile .     

Запустится сборка, прогрузятся все зависимости из requirements.txt, и в итоге сгенерируется хеш – строка Storing signatures, которая нам в дальнейшем понадобится (копируем ее в буфер обмена)

pervoe znakomstvo s kubernetes sozdaem prilozhenie dlja razvertyvanija v klastere dd76324 - ☸️ Первое знакомство с Kubernetes: создаем приложение для развертывания в кластере

Дальше необходимо запушить сборку в локальный репозиторий Docker. Выполняем следующую команду, подставляя в параметры свой хеш:

         buildah push dedd9a5526d3c97231e9a0b73ca1e4a91ece0d70a7f7bff254f61f7d28d8e9fb docker-daemon:app:v0     
  • :app – это имя нашего контейнера (можно указать свой).
  • :v0 – это tag. Обычно через него выставляется версионность для удобной навигации в репозитории.

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

         docker image ls     

pervoe znakomstvo s kubernetes sozdaem prilozhenie dlja razvertyvanija v klastere 3df32da - ☸️ Первое знакомство с Kubernetes: создаем приложение для развертывания в кластере

Итак, у нас на локальном хосте есть собранный контейнер который мы можем запустить для проверки работоспособности с помощью curl.

         docker run --rm -d -v `pwd`:/app -p 5000:5000 app:v0     

pervoe znakomstvo s kubernetes sozdaem prilozhenie dlja razvertyvanija v klastere 4d7e658 - ☸️ Первое знакомство с Kubernetes: создаем приложение для развертывания в кластере

Приложение откликается, значит контейнер рабочий. Последний штрих – запушить контейнер из локального репозитория в удаленный, например, в Docker Hub. Это нужно, чтобы мы могли скачать контейнер в кластер k8s и запуститься его уже там.

Чтобы это сделать, потребуется авторизоваться на Docker Hub и создать пустой репозиторий. Детально описывать эту процедуру не буду: процесс похож на создание Git-репозитория.

         docker login <выполните авторизацию>. Делается один раз, пароль и логин запоминаются      
         docker tag app:v0 <ваш логин docker hub>/<ваш репозиторий>/app:v0 buildah push <image ID> <ваш логин docker hub>/<ваш репозиторий>:app      

Теперь можно на любом хосте с Docker запустить контейнер и в качестве расположения указать уже не локальный репозиторий, а Docker Hub.

         docker run --rm -d -v `pwd`:/app -p 5000:5000 test/learn_images:app:v0     

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

Цель – развернуть приложение Python из контейнера, но уже в кластере k8s в нескольких репликах.

Для этого необходимо создать два объекта (подробнее мы рассматривали их в предыдущей статье):

  • Deployment – развернет приложение и будет поддерживать необходимое количество реплик.
  • Service – обеспечит сетевое взаимодействие внутри кластера.

Создаем Deployment для приложения в кластере k8s

Дополнительные материалы Чтобы не путаться в терминах, вспомним, что под капотом у системы оркестрации Kubernetes.

Заходим по SSH на мастер-узел (ноду), проверяем работоспособность kubectl. Далее необходимо создать deployment.yaml.

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      

Разбираем подробнее:

  • kind: Deployment – определяем, какой у нас будет объект. В данном случае Deployment, но может быть и Service или, скажем, Pod.
  • name: app – имя нашего Deployment (именно так он будет отображаться в кластере k8s).
  • matchLabels: и app: app – метка приложения, ее уникальный идентификатор для дальнейшего мапинга с сервисом и другими объектами k8s.
  • replicas: 2 – сколько экземпляров приложения необходимо создать
  • containers: – этой секции описывается, откуда нам спулить контейнер (ясно дело, с Docker Hub). Порт для сетевого взаимодействия.
  • resources: – интересная секция. Тут описаны минимально необходимые ресурсы для запуска (limits). Без этих ресурсов приложение не стартует и планировщик кластера будет искать подходящий узел, удовлетворяющую минимальным ресурсам. Запрашиваемые (requests) – это ресурсы, которые резервируются на ноде для вашего приложения. Сверх этих ограничений приложение не получит ресурсов CPU и RAM.

Сохраняем файл deployment.yaml и выполняем команду для развертывания приложения:

         kubectl create -f deployment.yaml     

Если ошибок в файле не было, успешный исход – активное приложение в 2 репликах. Посмотреть состояние можно следующей командой:

         kubectl get pod -o wide     

Приложение развернуто в двух репликах – с помощью curl можно обратиться к каждой из них по IP пода, но это плохой вариант (поды рано или поздно переедут на другие узлы и IP поменяются). Давайте напишем еще один объект кластера, который закроет эту проблему – Service.

Создаем Service приложения в кластере k8s

Из статьи по базовым объектам кластера k8s мы уже знаем, что объекты Service нужны для мапинга всех реплик приложения на один IP (endpoint).

Создаем еще один файл service.yaml.

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      

Его главные отличительные особенности:

  • ports: port – порт, по которому Service будет принимать трафик.
  • targetPort – порт для связи с приложением.
  • selector: – мапим наш Deployment и все реплики по этой метке.
  • type: clusterIP – тип объекта Service. В нашем случае для сетевого взаимодействия внутри кластера k8s.

Запускаем процедуру создания следующей командой:

         kubectl create -f service.yaml     

Далее смотрим детали Service:

         kubectl get svc -o wide     

pervoe znakomstvo s kubernetes sozdaem prilozhenie dlja razvertyvanija v klastere 818f984 - ☸️ Первое знакомство с Kubernetes: создаем приложение для развертывания в кластере

Супер! У нас есть IP, по которому можно обращаться к сервису в кластере с любого пода.

Подведем итог статьи. Мы добились следующих результатов:

  • Написали приложение на Python + Flask.
  • Упаковали приложение в контейнер Docker.
  • Разместили контейнер в репозитории Docker hub.
  • Сделали Deployment и Service в кластере k8s.

Использованные в статье файлы YAML можно скачать здесь.

Поздравляю, вы развернули первое приложение в кластере k8s! Возможно оно простовато, но в следующих статьях мы будем доводить его до ума.

  • 6 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Связаться со мной
Close