В этой статье я не буду погружаться во все дебри контейнеризации, а лишь рассмотрю, что должен знать любой человек, начинающий работать с Kubernetes (k8s).

Что такое Docker?

Docker — это платформа для контейнеризации, которая позволяет создавать, запускать и управлять приложениями в изолированных контейнерах. Сам Docker уже давно используется (2013 год) и, скорее всего, вы так или иначе с ним сталкивались.

Суть контейнеризации в том, что вы используете одно физическое устройство (сервер) вместо нескольких. Благодаря контейнеризации один и тот же физический сервер может быть и веб-сервером, и сервером приложений.

enter image description here

Экономия ресурсов и бюджета

Давайте для примера рассмотрим компанию, разрабатывающую софт для нескольких проектов (проект А, проект Б, проект В). И под каждый проект приходится выделять три физических сервера. Почему так? На то много причин, и самая основная, конечно же, в том, что проекты не должны пересекаться, т.е. требуется изоляция каждого проекта от другого.

И в такой реализации следующие минусы: цена, обслуживание серверов, мониторинг состояния серверов.

При использовании контейнеризации все эти три проекта можно разместить на одном физическом сервере. Получается, что мы урезаем бюджет, да и работу администратора примерно в три раза.

drawing

Для начала на физический сервер устанавливается ОС, и потом в ней устанавливается программа контейнеризации (Docker, Podman и т.д.). Уже эта программа отвечает за работу контейнеров, в которых запущены проект А, проект Б, проект В.

Изоляция процессов

Каждое приложение работает в своём контейнере, независимо от других. Все контейнеры изолированы. И работа, например, с проектом Б никак не повлияет на другие проекты.

Быстрая развертываемость

Выполнить сборку проекта можно гораздо быстрее, чем используя отдельный сервер с установленными зависимостями локально.

При использовании определённого сервера, если необходимо проверить приложение на новой версии Python, что происходит:

  1. Разработчик просит администратора обновить Python
  2. В идеале администратор перед выполнением делает резервную копию сервера
  3. Администратор обновляет Python на сервере, где происходит сборка проекта
  4. Уведомляет о проделанной работе разработчика

drawing

А теперь рассмотрим, как это выглядит при использовании контейнеризации:

  1. Разработчик может сам запустить сборку приложения в контейнере с образом новой версии Python. Тут не надо ничего устанавливать — просто меняется версия образа контейнера. ра.

Портативность (переносимость)

Если вы сталкивались с разработкой приложения, то в курсе, что частенько всплывают проблемы с совместимостью вашего приложения на другом устройстве. Например, ваше приложение работает на вашем компьютере, но не работает на компьютере вашего коллеги.

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

Docker image

Для того чтобы запустить контейнер, нам нужен образ контейнера (Docker image).

О том, что такое сам образ, можно говорить долго, но проще представить, что это очень сильно урезанная ОС с нужными библиотеками и самим кодом для работы вашего приложения.
Docker-образ — это минимальная упакованная система с вашим кодом, которая работает одинаково везде — на ПК, сервере или в облаке.

Например, у вас есть приложение, которое работает на Python. Для работы такого приложения вам понадобится запустить его внутри контейнера с образом Python, который весит около 100 МБ.

Docker build

Для того чтобы сделать образ, используется команда Docker build. Каждый образ состоит из слоёв — простым языком, каждый слой — это выполнение той или иной команды для создания образа.

Для примера рассмотрим следующий Dockerfile, необходимый для создания Docker image.

FROM python:3.11-slim << базовый образ с Dockerhub

COPY script.py /app/script.py << копирование локального файла в образ 
WORKDIR /app << смена основной директории (рабочей)

CMD ["python", "script.py"] << выполнение скрипта

Docker image состоит из слоёв, но не все слои одинаково “видимы” или сохраняются как отдельные файловые изменения. Инструкция CMD не создаёт файловых изменений, а значит, не создаёт отдельного слоя с данными.

drawing

Docker image repository

Теперь, когда мы знаем, что существуют образы Docker, встаёт вопрос — где их хранить? Хранят их в репозиториях образов, которые могут быть как приватными, так и публичными. Наиболее распространённый публичный репозиторий — это Docker Hub.

Для того чтобы хранить свои собственные образы внутри компании, не используя публичные репозитории, можно воспользоваться функциями Docker либо же использовать сторонние приложения, например, Sonatype Nexus Repository.

docker pull

Теперь, когда мы знаем, что каждый образ находится в том или ином репозитории, необходимо его скачать. Делается это при помощи команды docker pull.

Команда docker pull используется для скачивания Docker-образа из репозитория (обычно Docker Hub) на ваше локальное устройство.

docker pull ubuntu:latest
docker pull node:18

При выполнении команды docker pull происходит следующее:

  1. Docker-клиент отправляет запрос к реестру репозитория
  2. Если образ найден, он скачивается по слоям (каждый слой образа загружается отдельно)
  3. Образ сохраняется локально и может использоваться для старта контейнеров

drawing

Также вы можете опустить выполнение этой команды, просто выполнив docker run.
Дело в том, что если образ ещё не скачан, то Docker под капотом сам выполнит docker pull и скачает необходимый образ.

docker push

Команда docker push используется для загрузки вашего локального Docker-образа (созданного с помощью docker build) в удалённый репозиторий (например, Docker Hub, GitLab Registry и т.д.).

Для загрузки образа в удалённый репозиторий иногда требуется авторизоваться.

drawing

docker login myregistry.com
docker push myregistry.com/project/app:latest

docker run

Самая часто используемая команда при работе с Docker. Эта команда создаёт сам контейнер и запускает его.

docker run -d --name myhttpd -p 8080:80 httpd

В команде выше:

  • -p 8080:80сопоставление локального порта 8080 с портом 80 контейнера
  • httpdимя образа, с которого создаётся контейнер
  • -dпродолжать работу в фоне
  • --name myhttpdзадать имя контейнеру