45. Что из себя представляет оьбраз Docker
Содержание
Анатомия образа Docker
На прошлом занятии мы рассмотрели некоторые основы использования Docker Desktop в сочетании с DockerHub для развертывания и запуска некоторых проверенных образов. Вкратце о том, что такое образ, вы не забудете, если я продолжу упоминать.
Образ Docker - это шаблон, доступный только для чтения, содержащий набор инструкций для создания контейнера, который может работать на платформе Docker. Это удобный способ упаковки приложений и предварительно сконфигурированных серверных сред, которые вы можете использовать для личного пользования или публично делиться ими с другими пользователями Docker. Образы Docker также являются отправной точкой для тех, кто впервые использует Docker.
Что произойдет, если мы захотим создать свой собственный образ Docker? Для этого мы создадим Dockerfile. Вы видели, как мы могли взять образ контейнера Ubuntu и добавить наше программное обеспечение, и у нас получился образ контейнера с программным обеспечением, которое мы хотели, и все хорошо, но если этот контейнер выключить или выбросить, то все эти обновления и установки программного обеспечения пропадут, и не будет повторяющейся версии того, что мы сделали. Это отлично подходит для демонстрации возможностей, но не помогает при транспортировке образов в несколько сред с одним и тем же набором программного обеспечения, устанавливаемого при каждом запуске контейнера.
Что такое Dockerfile
Dockerfile - это текстовый файл, содержащий команды, которые обычно выполняются вручную для создания образа docker. Docker может собирать образы автоматически, читая инструкции, содержащиеся в нашем dockerfile.
Каждый из файлов, составляющих образ docker, называется слоем. Эти слои образуют серию образов, поэтапно создаваемых друг над другом. Каждый слой зависит от слоя, расположенного непосредственно под ним. Порядок расположения слоев является ключевым фактором эффективности управления жизненным циклом образов docker.
Мы должны расположить слои, которые меняются чаще всего, как можно выше в стеке, потому что при внесении изменений в слой образа Docker перестраивает не только этот слой, но и все слои, созданные на его основе. Поэтому изменение слоя на самом верху требует наименьшего объема работы по пересборке всего образа.
Каждый раз, когда docker запускает контейнер из образа (как мы делали вчера), он добавляет слой, доступный для записи, известный как слой контейнера. В нем хранятся все изменения, вносимые в контейнер в течение всего времени его работы. Этот слой - единственное различие между работающим контейнером и исходным образом. Любое количество подобных контейнеров может иметь общий доступ к одному и тому же базовому образу, сохраняя при этом свое индивидуальное состояние.
Вернемся к примеру, который мы использовали вчера с образом Ubuntu. Мы можем выполнить одну и ту же команду несколько раз и на первый контейнер установить pinta, а на второй - figlet. Это два разных приложения, разного назначения, разного размера и т.д. и т.п.. Каждый контейнер, который мы установили, имеет один и тот же образ, но не одно и то же состояние, и это состояние исчезает, когда мы удаляем контейнер.
В приведенном выше примере используется образ Ubuntu, но также существует множество других готовых образов контейнеров, доступных на DockerHub и в других сторонних репозиториях. Эти образы обычно называют родительским образом. Это фундамент, на котором строятся все остальные слои, и базовые строительные блоки для наших контейнерных сред.
Наряду с набором отдельных файлов слоев, образ Docker также включает дополнительный файл, известный как манифест. Это, по сути, описание образа в формате JSON, содержащее такую информацию, как теги образа, цифровая подпись и подробные сведения о том, как настроить контейнер для различных типов хост-платформ.
Как создать образ docker
Есть два способа создания образа docker. Мы можем сделать это на лету, используя процесс, который мы начали вчера, мы выбираем наш базовый образ, раскручиваем контейнер, устанавливаем все программное обеспечение и депенансы, которые мы хотим иметь на нашем контейнере.
Затем мы можем использовать команду docker commit container name
, после чего у нас будет локальная копия этого образа в разделе docker images и на вкладке docker desktop images.
Супер просто, я бы не рекомендовал этот метод, если вы не хотите понять процесс, будет очень сложно управлять жизненным циклом таким образом и много ручной настройки/переконфигурации. Но это самый быстрый и простой способ создания образа docker. Отлично подходит для тестирования, устранения неполадок, проверки зависимостей и т.д.
Мы собираемся создать наш образ с помощью dockerfile. Это дает нам чистый, компактный и повторяемый способ создания образов. Намного проще управлять жизненным циклом и легко интегрировать в процессы непрерывной интеграции и непрерывной доставки. Но, как вы уже поняли, это немного сложнее, чем первый упомянутый процесс.
Использование метода dockerfile гораздо больше соответствует реальным развертываниям контейнеров корпоративного уровня.
Создание dockerfile - это трехэтапный процесс, в ходе которого вы создаете dockerfile и добавляете команды, необходимые для сборки образа.
В следующей таблице приведены некоторые из утверждений dockerfile, которые мы будем использовать или которые вы, скорее всего, будете использовать.
Команда | Задача |
---|---|
FROM | Чтобы указать родительский образ |
WORKDIR | Чтобы задать рабочий каталог для всех последующих команд в Dockerfile. |
RUN | Для установки любых приложений и пакетов, необходимых для контейнера. |
COPY | Для копирования файлов или каталогов из определенного места. |
ADD | Как COPY, но также может работать с удаленными URL и распаковывать сжатые файлы. |
ENTRYPOINT | Команда, которая всегда будет выполняться при запуске контейнера. Если она не указана, по умолчанию используется /bin/sh -c. Аргументы, передаваемые точке входа. Если ENTRYPOINT не задан (по умолчанию /bin/sh -c), .md будут командами, которые выполняет контейнер. |
EXPOSE | Для определения порта, через который будет осуществляться доступ к вашему контейнерному приложению. |
LABEL | Чтобы добавить метаданные к образу. |
Теперь у нас есть подробная информация о том, как создать наш первый dockerfile, мы можем создать рабочий каталог и создать наш dockerfile. Я создал рабочий каталог в этом репозитории, где вы можете увидеть файлы и папки, которые мне предстоит пройти. Containers
В этом каталоге я собираюсь создать файл .dockerignore, аналогичный .gitignore, который мы использовали в предыдущем разделе. В этом файле будут перечислены все файлы, которые могут быть созданы в процессе сборки Docker и которые вы хотите исключить из окончательной сборки.
Помните, что все, что связано с контейнерами, - это компактность, максимальная скорость и отсутствие лишнего объема.
Создадим простой Dockerfile с приведенной ниже схемой, которую также можно найти в папке по ссылке выше.
# Use the official Ubuntu 18.04 as base
FROM ubuntu:18.04
# Install nginx and curl
RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y nginx curl
RUN rm -rf /var/lib/apt/lists/*
Перейдите в этот каталог в терминале, а затем выполните команду docker build -t 90daysofdevops:0.1 .
мы используем -t
, а затем задаем имя и тег изображения.
Теперь, когда мы создали наш образ, мы можем запустить его с помощью Docker Desktop или командной строки docker. Я использовал Docker Desktop Я запустил контейнер, и вы можете видеть, что у нас есть curl
, доступный нам в cli контейнера.
В Docker Desktop также есть возможность использовать пользовательский интерфейс для выполнения некоторых других задач с этим новым образом.
Мы можем проинспектировать наш образ, при этом очень хорошо виден dockerfile и строки кода, которые мы хотели запустить в нашем контейнере.
У нас есть опция pull, теперь она не работает, потому что это изображение нигде не размещено, поэтому мы получим ошибку. Однако у нас есть Push to hub, который позволит нам отправить наш образ на DockerHub.
Если вы используете ту же docker build
, которую мы запустили ранее, то это тоже не сработает, вам понадобится команда сборки docker build -t {{username}}/{{imagename}}:{{version}}
.
Если мы посмотрим на наш репозиторий DockerHub, то увидим, что мы только что выложили новый образ. Теперь в Docker Desktop мы сможем использовать эту вкладку pull.