Порог вхождения Kubernetes нередко отпугивает начинающих разработчиков. Однако, если выполнять развертывание приложений на k8s по определенному алгоритму, эта задача не покажется слишком сложной. А мы вам упростим ее еще больше с помощью этого руководства.
Для удобства будем рассматривать развертывание последовательно, шаг за шагом.
Допустим, у нас уже есть какая-то написанная программа: пусть она будет на Python и имеет название program.py
. Разумеется, у вас уже должен быть сервер с установленным Linux. Также для работы нам, помимо Kube, понадобится Docker, с которым вы, вероятно, уже умеете работать. Тем не менее не будет лишним напомнить, как собирать контейнеры в Docker. С этого и начнем.
Сборку образа контейнера в Docker можно выполнять по-разному. Например, при помощи утилит, а одной из самых удобных является buildah. После ее установки создайте директорию для сборки образа и пропишите зависимости в файле requirements.txt
. Вот пример такого файла, вам же следует заменить зависимости на свои:
Далее откроем и изучим содержимое Dockerfile, конфигурационного файла Docker, в котором содержатся инструкции для сборки образа контейнера. Там обратите внимание на следующие строчки:
FROM
— указывает на интерпретатор. Например: FROM python:3.8
.RUN mkdir
— нужно для создания каталога внутри образа. Давайте выберем такой: RUN mkdir /my_project
.WORKDIR
— используется для однократного указания пути: WORKDIR /my_project
.ADD .
— эта инструкция необходима для создания контейнера под Kube, без нее запуск в Kubernetes будет выдавать ошибку, так как оркестратор не сможет найти путь самостоятельно. Пропишем там наш путь: ADD . /my_project/
.RUN pip install -r
— служит для запуска pip и указания на обработку файла. В нашем случае понадобится запустить файл зависимостей, что делается следующим образом: RUN pip install -r requirements.txt
.EXPOSE
— открывает порт. Например, EXPOSE 8000
.CMD
— инструкция запуска. Прописываем примерно следующее: CMD ["python", "/my_project/program.py"]
.В результате появится каталог my_project
с program.py
внутри. Также там будет файл зависимостей и Dockerfile. Теперь собираем образ через buildah:
buildah bud -f ./Dockerfile
В результате мы запустим процесс сборки и подтянем зависимости. Сгенерированный хеш скопируйте в буфер обмена и подставьте в следующую инструкцию:
buildah push (здесь указываем хеш, но без скобок) docker-daemon:program:v0
Теперь посмотрим на созданный образ контейнера через инструкцию docker image ls
, а далее проверим его работоспособность таким образом:
docker run --rm -d -v `pwd`:/my_project -p 8000:8000 program:v0
Полученный ответ Hello
, выделенный желтым, будет говорить о том, что всё в порядке, образ собран и готов к работе. Осталось отправить контейнер в репозиторий для работы в кластере, что делается примерно так же, как и в случае с Git-репозиториями, поэтому трудностей это вызвать не должно.
Для начала понадобится создать файл deployment.yaml
. Этот же файл будет затем использоваться для поддержки нужного числа реплик. Примеров структуры deployment.yaml
достаточно в сети, вот один из них:
Рассмотрим важные для нас строки:
kind:
— определяет тип объекта.name:
— имя, выбранное для отображения в кластере (лучше оставить таким же, как имя файла программы).matchLabels:
— метки.app:
— идентификатор.replicas:
— количество экземпляров, которое будет создано.containers:
— в этой части указывается, из какого удаленного репозитория мы будем брать контейнер, а также сколько ресурсов будем использовать.resources:
— потребуется указать минимальную конфигурацию в limits
, чтобы приложение смогло запуститься, а в requests
резервируемые cpu
и memory
.Посмотрим, как можно организовать deployment.yaml
для нашего случая (просто скопируйте и замените параметры на свои):
kind: Deployment
metadata:
name: program
labels:
app: program
spec:
replicas: 3
selector:
matchLabels:
app: program
template:
metadata:
labels:
app: program
spec:
containers:
- name: program
image: <your login>/<your repository>:program
ports:
- containerPort: 8000
protocol: TCP
name: http
resources:
limits:
memory: 840Mi
cpu: 1
requests:
memory: 420Mi
cpu: 500m
Когда вы указали все нужные параметры, не забудьте сохранить файл. Наконец, используя kubectl
, мы можем развернуть наш контейнер и сразу же второй инструкцией проверить, всё ли в порядке, выведя его состояние:
kubectl create -f deployment.yaml
kubectl get pod -o wide
При вызове отдельных реплик приложения по IP может возникнуть проблема с доступностью подов, поскольку они мигрируют между узлами кластера, а значит, их IP будут меняться. Решить эту проблему можно при помощи service.yaml
, который составляется похожим образом, но с некоторыми отличиями в параметрах. Взгляните:
kind: Service
metadata:
labels:
app: program
name: program
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8000
selector:
app: program
type: ClusterIP
Здесь port
— это порт для приема трафика. Наконец, в строчке type
мы указали наш кластер для обеспечения внутреннего взаимодействия по сети. Осталось запустить Service
, и проблема недоступности подов будет решена:
kubectl create -f service.yaml
Допустим, у нас есть какое-то приложение, написанное на свежей версии Python — назовем его, скажем, newgenAI
. Нам нужно развернуть это приложение в уже созданном кластере.
В Docker-файле делаем следующее:
FROM python:3.11
RUN mkdir /newgenAI
WORKDIR /newgenAI
ADD . /newgenAI
RUN pip install -r requirements.txt
EXPOSE 9000
CMD ["python", "/newgenAI/newgenAI.py"]
Итак, у нас есть каталог newgenAI
с newgenAI.py
, файлом зависимостей и Dockerfile внутри. Собираем образ:
buildah bud -f ./Dockerfile
В ответном сообщении buildah
выдаст хеш, который нужно вставить в эту инструкцию:
buildah push (здесь укажите хеш, но без скобок) docker-daemon:newgenAI:v0
Проверяем работоспособность образа:
docker run --rm -d -v `pwd`:/newgenAI -p 9000:9000 newgenAI:v0
Получив ответ Hello, отправляем готовый образ контейнера в репозиторий командой docker push repo/
(вместо repo/
подставьте имя созданной вами директории).
Сначала создаем и настраиваем файл deployment.yaml
по образцу выше, обращая внимание на выделенные ресурсы. Так как мы работаем над проектом генеративного ИИ, вряд ли будет достаточно 1 CPU и 840 МБ оперативной памяти, так что выставите актуальные значения и создайте запас.
Теперь осталось развернуть созданный образ при помощи kubectl
:
kubectl create -f deployment.yaml
И в завершение проверим, работает ли он:
kubectl get pod -o wide
В ответ мы должны получить статус Running
.
Что ж, теперь вы знаете, как развернуть приложение на Kubernetes, и готовы к решению более сложных задач с помощью Kube. А мы вам в этом поможем!