Введение

Контейнеризация, сборка и доставка приложений ─ рутинная, но неизбежная часть работы любого системного 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:

  1. Склонировать репозиторий с шаблонами сайтов ─ cr-mks-webinar/web-sites.
  2. Переложить один из шаблонов сайтов в образ с веб-сервером.

Достигается разделение за счет двух команд 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:

  1. В разделе Облачная платформа выбираем раздел Container Registry
  1. Нажимаем кнопку Начать работу и вводим имя реестра.
  1. Попадаем на страницу реестра и выбираем пункт Получить токен.
  1. Копируем токен в буфер обмена
  1. Возвращаемся в консоль и авторизуемся
    # 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=
$ 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       31m   v1.24.3
webinar-cluster-node-q77zb   Ready       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         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

Проверяем доступ в браузере

Заключение

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

Что дальше?

Зарегистрироваться в панели управления

Регистрируйте аккаунт в панели управления Selectel, пополняйте баланс удобным способом и подключайте наши продукты.
Перейти в панель

Узнать о продуктах больше

Все о принципах работы, задачах и фичах читайте на нашем сайте.
Перейти на сайт

Комментарии