Полное практическое руководство по началу использования Docker
С тех пор, как я начал работать инженером по компьютерному зрению, у меня была возможность узнать, как работает Docker. Весь опыт, который я накопил до сих пор, сконцентрирован здесь. Вы можете считать это учебным пособием 101 Docker, чтобы получить твердое базовое понимание и приобрести некоторый практический опыт.
Мы все были там. Вы узнаете что-то, что вызовет ваше любопытство. Вам не терпится проверить это на реальном проекте. Но жизнь случается, и ты прячешь свои новые блестящие знания в затылок.
«В теории, теория и практика одинаковы. На практике это не так»
Эти слова Бенджамина Брюстера резонируют во мне уже несколько недель. Я предлагаю вам выполнить шаги, описанные здесь. Вы можете владеть практическим опытом, на который у меня ушло пару месяцев, чтобы набраться всего за 10 минут.
Пора запачкать руки.
Теоретические вещи
Прежде чем перейти к практической стороне, давайте получим минимум, чтобы иметь четкое представление о Docker.
Docker выполняет процессы в изолированных средах, известных как контейнеры. Неважно, находится ли он на нашем локальном хосте или на сервере. Это означает, что вы можете установить ОС, операционные системы, библиотеки и пакеты в контейнер. Таким образом, ваш контейнер подобен этому мини-компьютеру, отделенному от вашего реального компьютера.
Это далеко не формально, но полезно знать, что можно делать с контейнером. Кривая обучения быстра и охватывает несколько приложений в ваших реальных проектах.
Просто подумайте о следующих ситуациях:
- Вы работаете в Windows, но для разработки пакета вам нужна другая ОС.
- Вы хотите установить некоторые библиотеки отдельным способом и запустить некоторый код, но хотите избежать проблем с совместимостью.
- Вы хотите загрузить какие-то скрипты в облако, но эти скрипты работают на определенных ОС и библиотеках.
Все эти (и многие другие) ситуации можно решить с помощью Docker. Хорошо, контейнеры — это довольно мощное средство, но как создать контейнер?
Точно так же, как у каждого сокровища есть карта, у каждого контейнера есть изображение. Точнее, образ Docker, который представляет собой файл, состоящий из слоев со всей необходимой информацией для создания контейнера. Процесс создания образа Docker можно начать с нуля или с использованием существующих образов Docker.
Когда вы определяете образ Docker с нуля, вы хотите создать набор инструкций, описывающих поведение образа. Место, куда вы вставляете эти инструкции, — это файл с именем Dockerfile. Один интересный факт о Dockerfile: это текстовый файл без без расширения.
На следующей диаграмме показаны этапы запуска контейнера Docker:
Иногда вам не нужно определять и настраивать Dockerfile. Например, вам может потребоваться просто базовый образ для запуска вашего контейнера. Вот где Docker Hub может стать подходящим ресурсом для вашей работы. По сути, после регистрации на платформе вы можете получать (загружать) и отправлять (загружать) образы Docker. В этом смысле Docker Hub чем-то похож на GitHub.
Docker Hub облегчает вам процесс работы с Docker, так как сокращает количество этапов:
Практические вещи
Внедрение контейнера Docker научит вас некоторым шагам, которым я следую при работе над проектами машинного обучения. Я решил использовать первую диаграмму, чтобы представить Docker в панорамном виде.
Давайте воссоздадим реалистичную ситуацию с некоторыми ограничениями, чтобы думать, понимать и применять контейнеры.
Ваш менеджер или клиент требует, чтобы вы попробовали определенный алгоритм машинного обучения в файле script.py. Алгоритм будет частью программного решения. Если вы одобрите алгоритм, производственная группа развернет программное обеспечение для обслуживания определенного рынка с высоким потенциалом.
Прежде чем ваше волнение зашкаливает, ваш менеджер предупреждает вас о некоторых условиях:
- Алгоритм требует, чтобы вы работали с Ubuntu 16.04 и Python версии 3.5.2.
- Алгоритм основан на pandas 0.24.2 и numpy 1.16.4.
- После того, как вы попробуете алгоритм, ваш менеджер тоже захочет его попробовать.
- В случае успеха ваша команда развернет алгоритм в общедоступном облаке и расширит его по мере необходимости.
- Вы собираетесь работать на своем новом ноутбуке с установленной Ubuntu 20:04 и Python 3.8.6.
Хорошо, а как вы подходите к ситуации? Ну, наверное, лучший способ начать — это понять, что вы не можете напрямую запустить script.py насвоем ноутбуке. Это связано с тем, что ваша версия ОС и Python отличаются от тех, которые требуются для алгоритма.
Доступны некоторые решения, когда речь идет об устранении проблем совместимости программного обеспечения.
Популярной стратегией в Python является применение виртуальных сред. Они разделяют функцию изоляции контейнеров, поскольку они отделены от вашего устройства. В виртуальной среде вы можете установить любую версию Python. Хотя это может звучать хорошо, вы не можете использовать виртуальные среды для тестирования алгоритма машинного обучения. Это потому, что вы по-прежнему будете работать с Ubuntu 20.04, а нам нужна Ubuntu 16.04.
Другое потенциальное решение — попробовать виртуальную машину (ВМ). Виртуальная машина поможет вам установить Ubuntu 16.04 и python 3.5.2 на ваш ноутбук. Тем не менее, у него есть некоторые недостатки для этой конкретной ситуации. А именно, он недостаточно портативный, чтобы его можно было перенести на другие устройства (ноутбук вашего руководителя), и его нельзя развернуть в облаке.
Лучшим решением в этом случае, вероятно, является контейнер Docker. Если на вашем компьютере не установлен Docker, вы можете следовать инструкциям на официальной странице.
Давайте начнем писать код.
Первый этап — сборка нашего Dockerfile:
FROM ubuntu:16.04 RUN apt-get update &&\ apt-get install -y python3 &&\ apt-get install -y python3-pip &&\ python3 -m pip install -U pip COPY requirements.txt /opt/app/requirements.txt WORKDIR /opt/app RUN pip install -r requirements.txt
Первая строка извлекает ОС Ubuntu 16.04 в качестве базового образа для последующих инструкций. Мы в основном устанавливаем основу нашего контейнера, используя команду FROM.
Далее до пятой строки выполняем некоторые команды с помощью инструкции RUN. Во второй строке мы обновляем инструмент командной строки apt-get для обработки пакетов в дистрибутивах Linux на основе Ubuntu. Сразу после этого мы устанавливаем python 3.5.2, а в следующей строке мы также устанавливаем pip, установщик пакетов для python. Наконец, в пятой строке мы обновляем pip до последней доступной версии.
Шестая строка копирует requirements.txt, содержащий необходимые библиотеки алгоритма, в путь /opt/app/requirements.txt, который будет создан внутри контейнера докеров.
В седьмой строке в качестве рабочего каталога задается путь /opt/app внутри контейнера. Это будет путь по умолчанию внутри контейнера, как только мы его запустим.
Последняя строка выполняет установку pip в режиме чтения в файле requirements.txt. Это вызовет установку pandas 0.24.2 и numpy 1.16.4 в контейнере Docker.
Ниже вы можете увидеть содержимое файла requirements.txt.
pandas==0.24.2 numpy==1.16.4
Теперь все готово для создания образа Docker! Убедитесь, что вы знаете путь к файлу Dockerfile и файлу requirements.txt, а затем измените каталог терминала. В моем случае у меня есть этот путь как mypath/docker, но вы можете выбрать все, что хотите.
mylaptop:~mypath/docker$ docker build .
Мы собираем образ Docker с помощью команды build. Это создает образ Docker по текущему пути, поэтому в конце используется символ точки (.). Команда сборки берет файл Dockerfile и файл requirements.txt и строит из них наш образ. Вы можете пометить свое изображение, используя следующее:
mylaptop:~mypath/docker$ docker build -t coolimage:1.0 .
Флаг -t задает имя репозитория coolimage для образа, а тег будет 1.0.
Когда вы запустите эту команду, вы увидите несколько шагов, выполняемых в вашем терминале:
Вы можете проверить, успешно ли создано ваше изображение, посмотрев на нижнее сообщение, отображаемое на терминале:
Это означает, что идентификатор нашего изображения — 8039bb5fb541, и мы также пометили его как coolimage:1.0.
Осталось только запустить наш контейнер. Есть несколько хороших практик, которые вы можете применить, чтобы иметь более универсальный контейнер:
- Сопоставление портов: для подключения некоторых портов между вашим контейнером и хостом, на котором он работает.
- Настройте запуск докера [параметры]: несмотря на то, что существует множество параметров, которые можно проверить здесь, одним из наиболее важных параметров запуска является выбор между отдельным режимом -контейнер завершает работу при завершении корневого процесса — и режим переднего плана, который позволяет запустить процесс в контейнере и подключить псевдотерминал, также известный как tty или pts.
- Прикрепите несколько томов к контейнеру: это позволит получить доступ к каталогам внутри вашего локального устройства/сервера и вашего контейнера. Более эффективно, чем простое копирование папок и файлов в вашем контейнере
- Пометьте свой контейнер: вместо длинного и скучного идентификатора контейнера по умолчанию, такого как 46d5e125776f, почему бы не назвать его чем-то вроде happyhippo.
Теперь набираем в терминале следующую команду:
$ docker run -ti -v/home/victor/tutorials/ml:/container_ml --name happyhippo coolimage:1.0
docker run указывает образ — например, coolimage:1.0 — для создания контейнера. Флаг -ti запускает процессы на переднем плане в интерактивном режиме и подключает псевдотерминал, где вы можете видеть потоки ввода и вывода.
-v/home/hostdirectory:/container_ml сопоставляет каталог хоста слева от двоеточия (:) с каталогом докера справа. Все файлы, находящиеся в вашем каталоге устройства /home/hostdirectory, теперь видны и доступны из вашего контейнера в /container_ml. Файл script.py хранится в папке /home/hostdirectory на ноутбуке.
happyhippo — это узнаваемое имя вашего контейнера в дополнение к идентификатору контейнера 46d5e125776f, который создается автоматически.
Поздравляю! Вы только что создали Docker-контейнер, который соответствует всем условиям, заданным вашим менеджером. Например, вы можете проверить версию Python, установленную в контейнере:
Вы можете написать некоторые команды в терминале контейнера.
Вы можете видеть, что файл requirements.txt был скопирован в /opt/app, который является рабочим каталогом контейнера. Мы определили это в нашем Dockerfile.
Изменив каталог на container_ml/, мы увидим, что файл script.py, смонтированный в томе, теперь находится внутри нашего контейнера. Это означает, что мы можем выполнить алгоритм и протестировать его.
root@46d5e125776f:/container_ml# python3 script.py
На схеме ниже описаны основные команды, которые мы использовали для решения задачи от вашего менеджера:
Хорошие хитрости
Я попытался предоставить контент, который охватывает наиболее распространенные основные операции с Docker. Иногда вам могут понадобиться дополнительные приемы, чтобы сделать вашу повседневную жизнь более гладкой. Давайте посмотрим несколько примеров
Список и удаление изображений и контейнеров
Вполне вероятно, что при работе с Docker у вас будет несколько образов и контейнеров. Вот почему вы хотите перечислить, а иногда и удалить изображения и контейнеры.
Чтобы просмотреть изображения и контейнеры:
# list all images (including intermediate images) docker image ls -a # list all containers docker container ls -a # list running containers docker container ls
Когда контейнеры и образы перечислены, вы увидите столбец СТАТУС, показывающий текущий статус образа и контейнера.
Удаление изображений и контейнеров
# remove specific image docker image rm IMAGE_ID # remove specific container docker rm CONTAINER_ID # remove all unused images docker image prune # remove all stopped containers docker container prune
Просто имейте в виду, что контейнеры построены на изображениях. Поэтому перед удалением образов следует удалить контейнеры.
Перезапустите контейнер и сохраните изменения
В своей работе я сталкивался с ситуациями, когда мне нужно было сохранить изменения в моем контейнере, чтобы на следующий день я мог восстановить свой прогресс там, где я его оставил. Представьте на мгновение, что вам удалось собрать некоторые внешние данные для нашего алгоритма машинного обучения. Вы оставили данные внутри контейнера через смонтированный том, и завтра вы будете обучать алгоритм на этих данных.
Вы возвращаетесь в офис со своими недавно приобретенными навыками Docker и печатаете:
docker container ls -a
Статус контейнера вышел. Но мы хотим, чтобы контейнер работал. Для этого мы выполняем двухэтапный процесс: сначала запускаем контейнер, а затем подключаем к нему терминал:
docker start happyhippo docker attach happyhippo
Теперь у вас снова есть контейнер вместе со всеми изменениями, которые вы сделали до сих пор.
Информация о контейнере и изображениях
Контейнеры и образы содержат множество различных сведений об их функциях. Многое происходит под поверхностью!
# information about container docker inspect CONTAINER_ID # information about image docker inspect IMAGE_ID
Вы получите много информации в формате json, такой как порты, смонтированные тома и так далее. Иногда я использовал команду inspect, чтобы найти ip-адрес определенного контейнера. Для этого просто убедитесь, что статус контейнера установлен, а затем используйте команду проверки. Если вы прокрутите вниз до раздела NetworkSetting, вы найдете IP-адрес.
Вывод
Я только что стал уверенным в Docker после того, как несколько раз попрактиковался в шагах, которые я показал вам на предыдущей диаграмме. Сначала определите Dockerfile, затем создайте образ и, наконец, сгенерируйте контейнер. Эта статья предназначена для того, чтобы дать вам почувствовать вкус всего процесса.
Я призываю вас не только следовать этому примеру, но и создать контейнер самостоятельно (при необходимости посетите Docker Hub для вдохновения). Это упражнение сделает вас на один шаг ближе к освоению Docker.
Не стесняйтесь проверить мои другие статьи!