Как развернуть свое приложение в Kubernetes
Инструкция о том, как с помощью проверенных инструментов сделать процессы контейнеризации, сборки и доставки приложений быстрее.
Введение
Контейнеризация, сборка и доставка приложений ─ рутинная, но неизбежная часть работы любого системного DevOps-администратора. В данной статье мы рассмотрим способы сделать этот процесс менее утомительным при помощи проверенных временем инструментов. Изначально этот материал был продемонстрирован в вебинаре, с записью которого вы можете ознакомиться на Youtube.
Список необходимого
Для последовательного выполнения шагов инструкции потребуются следующие утилиты:
Также нужно склонировать репозиторий с инфраструктурными манифестами cr-mks-webinar/infra. Шаблоны веб-сайтов скачивать не требуется, но вот ссылка на репозиторий ─ cr-mks-webinar/web-sites.
Готовим Dockerfile
Первым пунктом напишем небольшой Dockerfile и затем разберем его построчно:
# Dockerfile
FROM alpine:3.15 AS downloader
ARG TEMPLATE_REPO="https://gitlab.com/cr-mks-webinar/web-sites.git"
RUN apk add git \
&& git clone ${TEMPLATE_REPO} /tmp
FROM nginx:1.23
ARG TEMPLATE_NAME="coffee-shop-html-template"
COPY --from=downloader /tmp/${TEMPLATE_NAME} /usr/share/nginx/html
Здесь представлен простой пример multi-stage builds.
В нашем случае этапов 2:
- Склонировать репозиторий с шаблонами сайтов ─ cr-mks-webinar/web-sites.
- Переложить один из шаблонов сайтов в образ с веб-сервером.
Достигается разделение за счет двух команд FROM, начнем с первой:
- FROM alpine:3.15 AS downloader ─ объявляем образ первого этапа и его псевдоним для удобного обращения на следующей стадии. Выбран легковесный, но полноценный дистрибутив alpine
Следующим шагом объявляем аргумент для сборки и его значение по умолчанию:
- ARG TEMPLATE_REPO=»https://gitlab.com/cr-mks-webinar/web-sites.git» ─ перезаписать этот аргумент можно при сборке, указав аргумент и новое значение в ключе —build-arg
Затем выполним комбинацию команд:
- RUN apk add git && git clone ${TEMPLATE_REPO} /tmp ─ установим необходимый для клонирования репозитория git и в случае успешной установки склонируем репозиторий из аргумента TEMPLATE_REPO в директорию /tmp
После данных манипуляций мы переходим к следующему этапу сборки:
- FROM nginx:1.23 ─ объявляем образ второго (и заключительного) этапа. Именно этот образ будет базовым для конечного образа, который мы собираем. Для статического контента отлично подойдет веб-сервер nginx.
Объявляем еще один аргумент для сборки:
- ARG TEMPLATE_NAME=»coffee-shop-html-template» ─шаблоны сайтов расположились в директориях с разными названиями. Для сборки нам нужен только один шаблон. Именно название его директории указано в данном аргументе.
Заключительная команда в нашем Dockerfile:
- COPY —from=downloader /tmp/${TEMPLATE_NAME} /usr/share/nginx/html ─ копируем директорию с шаблоном сайта (тут нам и пригодился аргумент TEMPLATE_NAME) в директорию, откуда веб-сервер будет раздавать контент.
Таким образом, мы получили образ, в котором нет ничего лишнего ─ только веб-сервер и раздаваемый контент.
Очень часто такой подход используется для сборки программы из исходного кода, а готовый бинарный файл кладется в чистый и пустой образ.
Например, все что написано на Golang иначе как так не собирается.
Создаем реестр и авторизуемся
Создать реестр контейнеров можно в нашей панели управления my.selectel.ru:
- В разделе Облачная платформа выбираем раздел Container Registry
- Нажимаем кнопку Начать работу и вводим имя реестра.
- Чтобы настроить доступ к реестрам, нужно сгенерировать токен. Вы можете выбрать срок действия токена, права доступа и реестры, к которым дает доступ токен.
- Введите параметры и нажмите Сгенерировать токен. Когда будут созданы логин и пароль, нажмите Скачать json-токен.
- Возвращаемся в консоль и авторизуемся
# plain
$ docker login cr.selcloud.ru -u token -p <скопированный_из_панели_токен>
. . .
Login Succeeded
Теперь образы можно пулить и пушить.
Реестр для хранения образов контейнеров
Собираем первый образ
Теперь все готово для сборки и публикации образа. Далее действия выполняются в корне репозитория cr-mks-webinar/infra.
Первый образ собирается без дополнительных аргументов
# plain
$ docker build -t cr.selcloud.ru/webinar/coffee-shop .
. . .
Successfully tagged cr.selcloud.ru/webinar/coffee-shop:latest
Публикуем образ
# plain
$ docker push cr.selcloud.ru/webinar/coffee-shop:latest
The push refers to repository [cr.selcloud.ru/webinar/coffee-shop]
. . .
latest: digest: sha256:45967b1671c1e06fdecdf955890c8bb9a6a77bc2baf69f1249989bab1e8dc7cc size: 1781
Разворачиваем кластер K8S
Далее действия выполняются в корне репозитория cr-mks-webinar/infra.
Наша нагрузка будет развернута в кластере Managed Kubernetes. Кластер мы создадим через Terraform. Часть ресурсов уже создана для упрощения примера:
- проект (используем его id)
- приватная сеть (используем ее id)
- подсеть (используем ее id)
- роутер с внешним доступом (к нему подключена подсеть)
Также стоит отметить, что мы используем доменное имя, которое вам потребуется изменить на свое.
Managed Kubernetes
Проводим инициализацию
# plain
$ cd terraform
$ export TF_VAR_selectel_token=<api_ключ_из_панели_управления>
$ export TF_VAR_cr_token=<пароль_реестра_из_панели_управления>
$ terraform init
Initializing the backend...
Initializing provider plugins...
. . .
Terraform has been successfully initialized!
Применяем изменения, вбив в консоль yes для подтверждения
# plain
$ terraform apply
. . .
Plan: 8 to add, 0 to change, 0 to destroy.
. . .
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
. . .
Apply complete! Resources: 8 added, 0 changed, 0 destroyed.
Развертывание кластера в среднем занимает около 10 минут. Помимо самого создания кластера будут произведены следующие действия:
- развернут ingress-контроллер и назначен его внешний адрес,
- создан неймспейс webinar,
- создан секрет selectel-cr для доступа к нашему реестру.
После выполнения мы получим полностью готовый кластер и kubeconfig-файл для доступа в кластер ─ terraform/webinar.yaml. Можем запускать наше приложение.
Запуск приложений в кластере
Теперь у нас есть образ приложения, а также кластер для его запуска. В директории k8s/coffee-shop находятся манифесты для кластера:
- deployment.yaml ─ описание приложения для запуска в кластере,
- service.yaml ─ сервис для доступа к приложению внутри кластера,
- ingress.yaml ─ ингресс для доступа к приложению из внешней сети.
Далее действия выполняются в корне репозитория cr-mks-webinar/infra.
Давайте применим манифесты и проверим доступность нашего сайта.
Используем скачанный ранее kubeconfig-файл для доступа в кластер
# plain
$ export KUBECONFIG=$PWD/terraform/webinar.yaml
$ kubectl get node
NAME STATUS ROLES AGE VERSION
webinar-cluster-node-d6u9t Ready <none> 31m v1.24.3
webinar-cluster-node-q77zb Ready <none> 31m v1.24.3
Применяем манифесты
# plain
$ kubectl apply -f k8s/coffee-shop/
deployment.apps/coffee-shop created
ingress.networking.k8s.io/coffee-shop created
service/coffee-shop created
Проверяем ресурсы
# plain
$ kubectl get all -n webinar
NAME READY STATUS RESTARTS AGE
pod/coffee-shop-5d7977bd45-57kd8 1/1 Running 0 60s
pod/coffee-shop-5d7977bd45-bwdqf 1/1 Running 0 60s
pod/coffee-shop-5d7977bd45-nlk76 1/1 Running 0 60s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/coffee-shop ClusterIP 10.108.253.64 <none> 80/TCP 60s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/coffee-shop 3/3 3 3 60s
NAME DESIRED CURRENT READY AGE
replicaset.apps/coffee-shop-5d7977bd45 3 3 3 60s
Проверяем доступ к сайту в консоли
# plain
$ curl -I http://coffee-shop.shatohin.space
HTTP/1.1 200 OK
Проверяем в браузере
Собираем и разворачиваем остальные приложения
Далее действия выполняются в корне репозитория cr-mks-webinar/infra.
Теперь мы хотим подготовить образы с остальными шаблонами. Для этого запустим сборку с использованием ключа —build-arg.
Собираем образ шаблона limelight-html:
# plain
$ docker build -t cr.selcloud.ru/webinar/limelight --build-arg TEMPLATE_NAME=limelight-html .
. . .
Successfully tagged cr.selcloud.ru/webinar/limelight:latest
Публикуем образ шаблона limelight-html:
# plain
$ docker push cr.selcloud.ru/webinar/limelight:latest
The push refers to repository [cr.selcloud.ru/webinar/limelight]
. . .
latest: digest: sha256:0780191eeb3382dd58e055165248730f04b0251cfad3e874b4ed4087f65217f5 size: 1781
Собираем образ шаблона templatemo_559_zay_shop:
# plain
$ docker build -t cr.selcloud.ru/webinar/zay-shop --build-arg TEMPLATE_NAME=templatemo_559_zay_shop .
. . .
Successfully tagged cr.selcloud.ru/webinar/zay-shop:latest
Публикуем образ шаблона templatemo_559_zay_shop:
# plain
$ docker push cr.selcloud.ru/webinar/zay-shop:latest
The push refers to repository [cr.selcloud.ru/webinar/zay-shop]
. . .
latest: digest: sha256:c4a52946364825bb3eeecf08c57ca31c2245b761bfb350e4f4fdf6e844145b1f size: 1781
Применяем манифесты limelight:
# plain
$ kubectl apply -f k8s/limelight/
deployment.apps/limelight created
ingress.networking.k8s.io/limelight created
service/limelight created
Применяем манифесты zay-shop:
# plain
$ kubectl apply -f k8s/zay-shop/
deployment.apps/zay-shop created
ingress.networking.k8s.io/zay-shop created
service/zay-shop created
Проверяем доступ к сайтам в консоли
# plain
$ curl -I http://limelight.shatohin.space
HTTP/1.1 200 OK
$ curl -I http://zay-shop.shatohin.space
HTTP/1.1 200 OK
Заключение
В этой инструкции мы рассмотрели, как с помощью проверенных инструментов сделать процессы контейнеризации, сборки и доставки приложений быстрее.