Skip to content

kontur-web-courses/docker-course

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Docker and Minikube

0. Prerequisites

Что нужно сделать перед прохождением блока:

  • Установить Docker Desktop для своей системы (для Linux необязательно). Для Windows понадобится ещё WSL, но можно делать всё на виртуалке с Linux).
  • Зарегистрировать аккаунт на Docker Hub.
  • Установить Minikube для своей системы по инструкции. При запуск Minikube можно в качестве драйвера использовать docker (--vm-driver=docker), для этого должен быть запущен Docker Daemon (например, с помощью Docker Desktop).

1. Docker

Классический вопрос с собеседования - в чём разница виртуальной машины и контейнера/Docker? Ответ, как всегда, можно посмотреть на Wiki, нас же интересует, как пользоваться Docker.

Всё начинается с написания Dockerfile. Dockerfile - "инструкция" по сборке образа, из которого будет запускаться контейнер. Образ - готовый и упакованный набор ПО, готовый к развёртыванию.

Образ состоит из слоёв. Слой - команда, результат выполнения которой можно переиспользовать, например, результат команды RUN dotnet build. Не всякая команда создаёт слой (вообще, только четыре команды могут это делать: FROM, RUN, COPY, и ADD). Все команды можно посмотреть здесь. У образа может быть базовый образ, с которого начинается сборка (задаётся командой FROM). Это часто бывает удобно, потому что не нужно заново устанавливать всё ПО, необходимое для работы. Пример базовых образов - dotnet/aspnet:8.0 и dotnet/sdk:8.0.

Заметим, что название образа (или, по-другому, тег) чаще всего состоит из названия пользователя/организации, названия самого образа и версии. Версия может задаваться в произвольном формате, но всегда она следует после :.

Давай попробуем собрать свой образ!

1.1. Создаём Docker-образ

Для начала добавь в репозиторий файл Dockerfile (это стандартное название файла). Работать будем с текущим проектов WebApp. Теперь нужно сделать следующее:

  1. Добавить базовый образ (адрес - mcr.microsoft.com/dotnet/aspnet:8.0-alpine);
  2. Выставить наружу порт приложения (обычно 8080);
  3. restore Nuget-пакетов (тут уже нужен новый базовый образ, да, их может быть несколько, -- mcr.microsoft.com/dotnet/sdk:8.0);
  4. Билд для проверки того, что приложение билдится;
  5. Паблиш приложения (в виде exe либо dll, со вторым будет проще выполнять дальнейшие действия);
  6. выставить приложение в качестве entry-point контейнера.

Для первого используй команду FROM, для второго - EXPOSE, для остальных - WORKDIR, RUN и, возможно, COPY. Для последнего пункта - ENTRYPOINT.

Проверь сборку контейнера командой docker build . либо запуском файла в Rider. Если нет ошибок, можно двигаться дальше.

1.2. Пробуем запустить контейнер

После сборки контейнера скопируй id полученного образа (он будет в логах сборки или в Rider), после чего выполни команду docker run <id_образа>. Если на предыдущем этапе всё сделано правильно, увидишь логи запуска приложения dotnet.

1.3. (MacOS warning!) Пробуем получить доступ к сервису в контейнере

Если у тебя MacOS, этот пункт выполнить целиком не получится из-за бага в Docker для MacOS, который не даёт полноценно пробрасывать порты между хостом и контейнером.

Останови контейнер и выполни команду docker run <id_образа> -p 50121:8080. Вместо 50121 может быть произвольный свободный порт в твоей системе. Если всё ок, по адресу http://localhost:50121/WeatherForecast откроется результат выполнения запроса к методу API нашего приложения. Если у тебя MacOS и всё ок, вместо ответа ты увидишь 403 Forbidden (из-за Docker).

2. Minikube

Minikube - односерверный вариант Kubernetes. Kubernetes (k8s) - система для автоматического деплоя, скалирования и управления контейнеризированными приложениями. Типовую структуру кластера можно посмотреть здесь. Кратко - приложениями запускаются в так называемых pods (подах) на машинах-узлах (nodes). На одной ноде может располагаться много подов. Контролируется это всё control plane (чаще называемые primary-серверами). Primary может быть несколько, но всегда нечётное количество (для достижения кворума). Minikube же объединяет в себе все компоненты на одной машине.

2.1. Запуск Minikube.

Для запуска достаточно выполнить команду minikube start.

2.2. Публикация собранного docker-образа.

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

  • локальный registry;
  • Docker Hub;
  • не публиковать никуда, а шарить docker-демона между хостом и minikube.

Мы пойдём по пути публикации образов в Docker Hub. Для этого:

  1. Залогинимся командой docker login. При этом введём логин/пароль от учётки, созданной на Docker Hub. Если региистрировались с помощью учётки Google/GitHub, для входа вместо пароля можно использовать токен, который нужно получить в секции Security настроек профиля.
  2. Добавим тег нашему образу, чтобы было понятнее, что это за образ. Добавляется он командой docker tag <id_образа> <tag> и состоит из следующих частей:
  • имя профиля на Docker Hub, иначе получишь access denied при пуше;
  • название после слэша;
  • версия после двоеточия.

Например, myaccount/myimage:myversion 3. Запушим командой docker push .

Проверьте на Docker Hub в профиле после пуша, что образ там отображается.

2.3. Деплой сервиса

Одно из ключевых понятий k8s - deployment. Оно включает в себя образ приложения, который будет разворачиваться. Для деплоя нужно создать deployment командой kubectl create deployment <name> --image=docker.io/<image> (для случая с Docker Hub, для других registry адрес будет отличаться).

Происходит деплой обычно быстро. Проверить работоспособность деплоймента и подов можно с помощью команд kubectl get deployments и kubectl get pods.

2.4. Создание сервиса

Сервис - способ прокидывания наружу сетевого приложения, которое запущено в кластере k8s. Нас интересует способ через LoadBalancer, который является стандартным для выставления сервиса в "дикую" сеть. Создать сервис можно с помощью команды kubectl expose deployment <name>--type=LoadBalancer --port=<port>. С портом можно поэкспериментировать.

Теперь выполняем в отдельном терминале команду minikube tunnel, чтобы работало связывания сети хоста и k8s. Если всё получилось, можно открыть страницу http://localhost:/WeatherForecast. Должен появиться JSON с прогнозом погоды от нашего сервиса.

Releases

No releases published

Packages

No packages published

Languages