
Знакомство с Докером
Основы — Файлы Docker — Команды Docker — Умирает ли Docker?
Docker — это платформа как услуга (PaaS), которая контейнеризирует приложения. Он был основан в 2008 году, провел свой первый DockerCon в 2014 году, а сейчас насчитывает более 12 миллионов зарегистрированных разработчиков. Stackshare.io сообщает, что более 8700 компаний используют Docker. К ним относятся такие известные имена, как Twitter, Spotify и Pinterest. Если вы не знаете, о чем идет речь, вы, вероятно, вышли на поле достаточно поздно, чтобы принять эту технологию как должное. В этой статье вы узнаете, что такое Docker, его основные файлы и команды, а затем расскажете, является ли Docker умирающей технологией.
Основы
Здесь мы рассмотрим четыре основных понятия Docker: контейнеры, образы, тома и демон.
Контейнеры
Контейнер очень похож на виртуальную машину. Виртуальные машины (ВМ) — это программные компьютеры, работающие на физических машинах (узлах). Многие виртуальные машины могут работать на одном хост-компьютере. Виртуальные машины имеют собственную операционную систему и запускаются через уровень программного обеспечения, называемый гипервизором. Виртуальные машины были основой облачных вычислений, что позволяло компаниям продавать дополнительные вычислительные ресурсы, помещая многочисленные клиентские приложения в виртуальные машины и запуская их на одном хост-компьютере, который ранее мог использоваться недостаточно.

Контейнеры, как и виртуальные машины, объединяют приложения, чтобы можно было совместно использовать ресурсы с одного хоста. Однако у контейнеров нет собственной операционной системы. Вместо этого они содержат только приложение и его зависимости (двоичные файлы, библиотеки). Контейнеры, работающие на одном хосте, совместно используют ядро контейнера и операционную систему хоста.
Это делает контейнеры легкими. Они быстро модифицируются и повторяются. Для запуска виртуальных машин может потребоваться несколько минут, а для контейнеров — несколько миллисекунд. Они также чрезвычайно портативны, что делает их идеальными для облачных приложений, многие из которых состоят из микросервисов, работающих в тандеме. Однако эта скорость идет в ущерб безопасности. Контейнеры менее безопасны, чем виртуальные машины, поскольку они совместно используют ОС и базовое оборудование. Это означает, что уязвимость в одном контейнере может быть использована и распространена на остальные контейнеры.

Надеюсь, теперь вы понимаете, почему контейнеры стали такими популярными. Виртуальные машины — это здорово, но они громоздки и медленно запускаются. Это затрудняет развертывание изменений. С помощью контейнеров вы можете легко создавать и развертывать изменения. Это важные черты в современном мире CI/CD, где нам нужны обновления, и мы хотим их сейчас.
Изображений
Здесь важно различать образы и контейнеры, которые являются основой Docker. Образы, также называемые моментальными снимками, очень похожи на контейнеры в том смысле, что они упаковывают приложение вместе с его зависимостями. Однако образы — это шаблоны, доступные только для чтения, которые описывают, как будет создан контейнер. Контейнер — это реальный экземпляр этого образа во время выполнения.
Думайте об изображениях как о чертежах. Контейнеры — это машины, построенные по этому чертежу. Вы можете создать несколько контейнеров из одного образа Docker. Также важно отметить, что хотя изображения доступны только для чтения, контейнеры доступны для чтения и записи. Хотя вы можете изменять контейнеры, вы изменяете только копию файловой системы образа. Новый контейнер, созданный из этого образа, не будет содержать никаких изменений.
Изображения также можно накладывать друг на друга. Каждый шаг в Dockerfile представляет собой новый слой. Эти слои добавят новые утилиты или библиотеки в контейнеры, созданные из этого образа. Контейнер похож на слой чтения-записи поверх этих слоев изображения. Эта комбинация слоев только для чтения с одним открытым слоем для чтения и записи называется объединенной файловой системой.
Этапы построения кэша слоев помогают уменьшить избыточность. Это означает, что если вы измените Dockerfile, он будет использовать сборку из последнего неизмененного слоя (или строки) в вашем файле, чтобы перестроить всю последовательность вместо того, чтобы начинать с базового образа. Вы также можете создавать контейнеры из любого конкретного слоя — вам не всегда нужно начинать с базового образа. Все слои изображения доступны только для чтения.

Использование образов для создания контейнеров вместо создания контейнеров в качестве первого шага помогает сделать приложения еще более переносимыми. Разработчики могут легко обмениваться изображениями, и любые два контейнера, созданные из одного образа, гарантированно будут иметь одинаковые зависимости. Это помогает смягчить проблемы, когда приложение будет работать на компьютере одного разработчика, но не будет работать на компьютере другого.
Объемы
Помните файловую систему Union, о которой упоминалось несколько абзацев назад? Это была файловая система, которая содержала слои изображений, доступные только для чтения, за которыми следовал слой контейнера для чтения и записи. Тома также являются файловыми системами, но они не хранятся в файловой системе Union. Вместо этого они хранятся на главном компьютере.

Тома позволяют разработчику сохранять данные между различными контейнерами. Это также позволяет этим данным сохраняться после жизненного цикла целевого контейнера (контейнеров). После или во время создания тома вы можете подключить этот том к контейнеру. Затем он получит доступ к данным внутри этого тома. Имейте в виду, что у него также будут права на чтение/запись: изменения, которые контейнер вносит в файлы, будут отражены в файловой системе хоста.
Docker Daemon против CLI
Docker Daemon — это сервер, который работает в операционной системе хост-компьютера. Это сервер, который предоставляет REST API для взаимодействия с Docker CLI. Демон работает только в Linux, поэтому на компьютерах с MacOS и Windows он работает на виртуальной машине с операционной системой Linux.

Docker CLI — это то, как пользователь взаимодействует с Docker Daemon. Как пользователь, вы можете вводить такие команды, как docker run, docker compose или docker ps. Эти команды отправляются из CLI через REST API в Docker Daemon, после чего выполняется вся необходимая логика. Механизм контейнера для Docker представляет собой комбинацию Docker CLI, REST API и Docker Daemon.
Файлы докера
Docker включает в себя несколько разных файлов во время установки. Два самых основных файла называются .dockerignore и Dockerfile. Для реальных приложений производственного уровня для вашего Dockerfile может потребоваться многоэтапная сборка. Кроме того, для запуска нескольких приложений-контейнеров вам понадобится как минимум один YAML-файл Docker Composer. Они будут рассмотрены в следующей статье. Теперь давайте рассмотрим два других типа файлов.
.dockerignore
Если вы использовали систему управления версиями (например, Git), это должно быть самовосклицательным. Это файл, который вы используете, чтобы docker игнорировал набор файлов или папок при создании образа. Это чрезвычайно важно. Чем меньше размер сборки вашего образа, тем меньше плоскость атаки для злоумышленников, тем быстрее процесс сборки и ниже общая стоимость вашего хранилища.
Докерфайл
Следующий файл, который следует рассмотреть, — это Dockerfile. Этот текстовый файл будет содержать инструкции по созданию образов Docker. Файлы Docker — это, по сути, набор команд, которые можно запускать с помощью интерфейса командной строки Docker, но вместо этого они объединены в один файл для простоты использования.
Каждая строка в Dockerfile содержит команду, за которой следует какой-либо аргумент для этой команды. Эти команды начинаются с базового образа — например, если вы создаете приложение Node.js, вы можете написать:
FROM node:16
Это указывает на то, что ваш базовый образ будет копией Node.js v16. Другие команды Dockerfile включают RUN (для запуска команд для создания вашего образа), WORKDIR (для указания рабочего каталога вашего приложения), COPY (для копирования файлов в ваш образ), CMD (для запуска указанной команды, указанной в скобках после запуска встроенного образа) и EXPOSE (чтобы открыть указанный порт во время выполнения), и это лишь некоторые из них.
Простой Dockerfile для приложения Node.js может выглядеть так:
# base image of node v16 FROM node:16 # indicate a working directory of /usr/src/app WORKDIR /usr/src/app # copy the package.json file COPY package\*.json . # install dependencies RUN npm install # expose port 3000 for your server EXPOSE 3000
Многоэтапные сборки
Файлы Docker также могут включать многоэтапные сборки. Это метод создания сборок, оптимизированных для какой-либо цели. Отличным примером может быть разделение сборок для разработки и производства. До того, как были введены многоэтапные сборки, вы, возможно, застряли с nodemon, работающим в контейнере производственного уровня. Этот тип раздувания образа или контейнера увеличивает его размер, что, как мы уже говорили ранее, замедляет время сборки и увеличивает поверхность атаки для злоумышленников.
Многоэтапные сборки будут содержать несколько команд FROM. Классическим примером может быть создание базовой инструкции FROM, установка узла, создание рабочего каталога и копирование некоторых необходимых файлов, таких как package.json, а затем добавление еще двух команд FROM, одной для разработки и одной для производства. В каждой сборке вы должны использовать ключевое слово AS, чтобы различать цель сборки. Мы подробнее рассмотрим это в руководстве, которое последует за этой статьей.
Докер-команды
Команды Docker запускаются через интерфейс командной строки Docker. После подключения к демону Docker вы можете запускать команды в своем терминале, например, для создания образа с помощью следующей команды:
docker build -t [name your image repo] -f [dockerfile name]
Здесь флаг «-t» указывает, что следующим аргументом будет имя вашего нового образа, а флаг «-f» указывает имя вашего файла Dockerfile. Вы можете перечислить свое новое изображение, используя:
docker images
Эта команда покажет вам все ваши изображения с именем репо, тегом, идентификатором изображения, датой создания и размером. Затем вы можете запустить определенный образ и создать контейнер, используя:
docker run [image name]
Вы можете добавить различные флаги в команду запуска докера, например «-env», чтобы указать переменную среды. Чтобы вывести список запущенных в данный момент контейнеров, вы можете использовать:
docker ps
Это покажет вам различную информацию о контейнерах, которые в настоящее время запущены, включая сгенерированное Docker имя, если вы не указали свое собственное имя для контейнера с помощью флага «— name» при запуске вашего образа. Вы можете остановить свой контейнер с помощью:
docker stop [container ID OR name]
Вы также можете указать время ожидания перед остановкой контейнера с помощью флага «-t» или «— time», за которым следует количество секунд ожидания перед его остановкой. Или, если вы предпочитаете остановить его без возможности блокировки команды, вы можете убить его:
docker kill [container ID OR name]
Это лишь некоторые из основных команд, с которыми вы можете столкнуться в Docker. Есть много других для изучения, которые вы можете проверить, запустив:
docker --help
Или перейдите к документации Docker, чтобы узнать больше.
Докер умирает?
Это был вопрос, с которым я столкнулся незадолго до написания этой статьи. Одна из основных платформ для управления контейнерными приложениями, Kubernetes (K8), объявила устаревшим старый стек, в котором использовался переводчик между K8 и Docker под названием dockershim.

В конце 2021 года они решили упростить свой стек, включив мини-переводчик в интерфейс времени выполнения контейнеров (CRI), который позволяет им исключить посредников из уравнения. Это также избавляет от раздувания Docker.

Это сопровождалось некоторыми предсказаниями о том, что Docker в конечном итоге вымрет. На данный момент статистика в верхней части этой статьи остается. Отчасти это связано с тем, что вы все еще можете использовать контейнеры Docker с K8. Эти контейнеры не специфичны для Docker. Прямо сейчас компании и разработчики могут использовать K8 с Docker точно так же, как и раньше, хотя и с предупреждением об устаревании.
Хотя это указывает на изменение команды разработчиков K8, это не означает конец Docker. Это по-прежнему жизненно важная технология для разработчиков, поскольку она является выдающейся платформой контейнеризации, доступной прямо сейчас. Однако технологии постоянно меняются и превосходят друг друга в пространстве разработчиков. Просто подумайте о том, что React.js был выпущен около 9 лет назад и уже в следующем году стал доминирующим интерфейсным фреймворком. Можно только догадываться, когда Docker действительно встретит свой конец и какие новые технологии придут ему на смену.
Следите за моей следующей статьей, которая проведет вас через контейнеризацию вашего первого приложения с помощью Docker.