Под контейнеризацией часто понимается одна конкретная технология — Docker. В этой статье мы подробно расскажем о том, как устроен Docker, как начать им пользоваться и какие у него есть альтернативы.
Также будет практическая часть, где мы создадим собственный докер-образ и запустим контейнер.
Мы не будем рассказывать, что такое контейнеры и для чего они используются. Если вы еще не знакомы с этой темой, прочитайте нашу статью о контейнеризации. А в этой статье мы сосредоточимся именно на докере.
Компоненты Docker
Docker — это платформа для разработки и запуска контейнеров. Докер позволяет создавать контейнеры, автоматизирует их запуск и управляет жизненным циклом. Докер состоит из нескольких компонентов:
1. Docker host (докер-хост)
Это компьютер, на котором работает докер. Это может быть обычный персональный компьютер, железный сервер или виртуальная машина в облаке.
2. Docker daemon (докер-демон)
Это фоновый процесс, который работает постоянно и ожидает команды. Все операции по управлению контейнерами отправляются именно в демон, например: запустить или остановить контейнер, скачать образ. И уже на основе этих команд демон выполняет необходимые действия с контейнерами и образами. Поэтому докер-демон знает все о контейнерах, запущенных на одном хосте: сколько всего контейнеров, какие из них работают, где хранятся образы и так далее.
3. Docker client (докер-клиент)
Это клиент, при помощи которого пользователи взаимодействуют с демоном и отправляют ему команды. Это может быть консоль, API или графический интерфейс.
4. Docker image (докер-образ)
Это неизменяемый образ, из которого разворачивается контейнер. Его можно рассматривать как набор файлов, необходимых для запуска и работы приложения на другом хосте. Можно привести аналогию из мира установки ПО: образ — это компакт-диск, с которого устанавливается программа.
5. Docker container (докер-контейнер)
Это уже развернутое и запущенное приложение. Продолжая аналогию с установкой ПО, контейнер можно сравнить с уже установленной и работающей программой на ПК.
6. Docker registry
Это репозиторий, в котором хранятся образы. Когда разработчики создают приложения, они размещают свои образы в этих репозиториях, откуда их могут скачать другие люди. Есть публичные репозитории, например Docker Hub. А можно создать свой репозиторий, для использования внутри компании или команды.
7. Dockerfile (докер-файл)
Это файл-инструкция для сборки образа.
Рассмотрим несколько примеров команд и посмотрим, как на них реагирует докер и что при этом происходит. Обратите внимание, что все команды от клиента поступают в демон, который выполняет нужное действие.
- docker pull. Эта команда скачивает образ из docker registry и помещает его в локальное хранилище на хосте.
- docker build. Эта команда читает докер-файл и собирает образ.
- docker run. Эта команда создает из образа контейнер и запускает его.
Как устроены докер-образы и контейнеры
Докер-образ состоит из слоев. Каждая команда в докер-файле добавляет новый слой, который накладывается на предыдущий. Финальный докер-образ — это объединение всех слоев в один.
Такая структура позволяет использовать уже существующие образы для создания новых. Например, мы разрабатываем приложения на Python. Чтобы наши приложения запускались на других серверах, мы должны в каждый образ устанавливать среду выполнения Python. Чтобы не реализовывать это самостоятельно, мы просто используем готовый официальный образ Python. В свою очередь, этот образ основан на базе образа Debian — дистрибутива Linux. Без него Python не сможет работать.
В результате наш докер-образ упрощенно выглядит вот так:
Также этот подход позволяет один раз скачать образ Python и использовать его для всех наших приложений. Так мы экономим место на диске и не дублируем одни и те же файлы.
Образ — это неизменяемые слои, которые доступны только для чтения. А контейнер — это тот же самый образ, у которого «сверху» есть еще один слой для записи. Контейнер использует его, когда ему нужно сохранить информацию в процессе своей работы: логи, временные файлы и так далее. Если контейнер уничтожится, то этот слой и вся информация на нем тоже пропадут. А когда из этого же образа создастся новый контейнер, слой для записи у него будет новый и пустой.
Создание и запуск докер-контейнеров
Перейдем к практике. Для начала скачаем готовый образ и запустим из него контейнер. Затем создадим свое приложение, обернем его в образ и запустим в докере.
Для начала нужно установить Docker. Мы не будем описывать этот шаг, потому что он различается в зависимости от ОС и дистрибутива Linux. Инструкция по установке есть на официальном сайте.
Запускаем контейнер
Сначала мы скачаем уже собранный образ и запустим контейнер. Выполним в консоли команду:
docker run debian echo 'This is Debian'
Этой командой мы говорим докеру: «Запусти образ debian и выполни в нем вот эту команду». В результате мы должны получить одну строчку с текстом This is Debian.
Смотрим результат в консоли:
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
d960726af2be: Pull complete
Digest: sha256:acf7795dc91df17e10effee064bd229580a9c34213b4dba578d64768af5d8c51
Status: Downloaded newer image for debian:latest
This is Debian
Поясним, что тут происходит. Так как у нас свежая установка докера, у нас еще нет ни одного скачанного образа. Поэтому прежде чем использовать образ debian, его нужно откуда-то взять. По умолчанию Docker настроен на публичный репозиторий Docker Hub. Поэтому когда докер не нашел на нашем компьютере запрашиваемый образ, он решил найти его на докер-хабе и скачать. Docker самостоятельно определил, что ему сначала нужно выполнить команду docker pull и лишь затем docker run. И только после этого мы увидели результат в консоли. Если мы запустим эту же команду повторно, докер уже не будет скачивать образ, и мы сразу получим результат.
Создаем собственный образ
Теперь мы напишем простое Python-приложение, упакуем его в образ и запустим контейнер. Для начала создадим директорию для работы и перейдем в нее:
mkdir my-docker-app; cd my-docker-app
Далее создадим текстовый файл app.py и в любом текстовом редакторе запишем в него одну строчку кода:
print("This is Python");
Прежде чем упаковывать приложение в контейнер, нужно убедиться, что оно работает. Выполним команду:
python app.py
В консоли мы увидим результат: This is Python. Это все, что делает наше приложение: выводит одну строку текста. Но сейчас это не важно, ведь главная задача для нас — научиться упаковывать приложения в докер-образ.
Далее в этой же директории создадим файл с названием Dockerfile и запишем в него следующее:
FROM python:3
COPY app.py /
CMD [ "python3", "./app.py" ]
Поясним, что мы сделали:
- В первой строке мы указываем, что используем базовый образ Python, версию 3.
- Далее копируем файл нашего приложения в корневую директорию образа.
- Третьей командой мы запускаем наш файл.
Но пока это еще не докер-образ, а просто файл с командами. Чтобы из докер-файла собрать образ, запустим команду:
docker build -t my-docker-app .
Параметр -t обозначает имя создаваемого образа, мы назовем его my-docker-app.
После того как образ собран, мы можем запустить контейнер:
docker run my-docker-app
В результате в консоли будет результат: This is Python. Итак, мы создали простое Python-приложение, обернули его в докер-образ и запустили контейнер. Конечно, это очень простой пример, и в настоящих приложениях все намного сложнее. Но это позволяет понять основы технологии и как с ней работать.
Аналоги Docker
Docker стал стандартом де-факто в мире контейнеров. Часто, когда говорят про контейнеры, подразумевают именно Docker-контейнеры. Но это не единственная реализация технологии контейнеризации, есть и другие:
1. PodMan
Имеет интерфейс командной строки, который очень похож на команды Docker. Основное отличие от докера заключается в том, что у Podman нет отдельного демона, это самостоятельная утилита. Podman используется как инструмент управления контейнерами по умолчанию в дистрибутиве Fedora Linux.
2. LXC
Система виртуализации на уровне ОС, а не самостоятельная платформа, как Docker. Она создает отдельное виртуальное окружение с собственным пространством процессов и сетевым стеком, в котором все контейнеры используют один экземпляр ядра ОС. LXC часто рассматривается как среднее между chroot и полноценной виртуальной машиной.
3. rkt
Движок, который изначально был ориентирован на современные облачные приложения. В 2019 году разработка прекратилась, и движок переведен в архив. Возможно, еще можно встретить проекты, где он используется. Но в новых разработках rkt уже не стоит выбирать.
Docker подходит для облаков
Докер-контейнеры можно запускать не только на своих серверах, но и в облаке. Во-первых, это позволит не заниматься выбором, покупкой и настройкой серверов. Во-вторых, у облачных провайдеров разработано много готовых сервисов, которые позволяют получить дополнительные преимущества. Например, Kubernetes на платформе Mail.ru Cloud Solutions управляет жизненным циклом контейнеров, автоматически масштабируется под изменение нагрузки и помогает построить отказоустойчивую систему.
Источник: https://mcs.mail.ru/blog/chto-takoe-docker-i-kak-on-rabotaet
Автор: Марат Талипов
Читайте также статьи по теме:
Как устроен Kubernetes as a Service на платформе Mail.ru Cloud Solutions
26 основных паттернов микросервисной разработки
Деплоим проект на Kubernetes в Mail.ru Cloud Solutions. Часть 1.