DevOps

Docker. Создание образов

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

all-top


Проблема

Рассмотрим процесс разворачивания веб-приложения написанного на php без Docker. Действия сводятся к такой последовательности задач:

  • Установка операционной системы (ubuntu)
  • Установка веб-сервера (apache)
  • Установка сервера базы данных (mysql)
  • Установка php (расширение для apache или php-fpm)
  • Установка других необходимых расширений
  • Конфигурация virtualhost (одного или нескольких при необходимости)
  • Перенос файлов приложения, конфигурация

Не ракетостроение, но достаточно сложно и занимает время. Особенно, если требуется установка специфических расширений. Особенно, если вы разворачиваете существующий проект без документации.


Решение

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

После создания Docker-образа его нужно только запустить на host машине, на которой установлен Docker. Это может быть и production сервер и рабочая станция программиста/тестировщика/…
Запущенный экземпляр образа называется контейнером.


Пример

Начнем с простого примера. Давайте подготовим Docker образ для машины с ubuntu, apache и supervisord. Оригинал статьи можно прочесть здесь.

Ubuntu — операционная система, apache — веб-сервер.

Несколько слов о supervisord. Supervisord — это специальная система, которая умеет контролировать запущенные процессы в unix-подобных ОС. Supervisord умеет перезапускать упавшие процессы. Он будет нужен для поддержания веб-сервера apache в работающем состоянии.

Перейдем к практике

1. Убедимся, что докер работает:

1

2. Список доступных образов можно посмотреть командой images:

2

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

3. Создаем директорию для файлов образа с названием example-image. Перейдем в нее и добавим два  файла:

3

4. Dockerfile выглядит так:

Разберем его построчно:

FROM ubuntu:16.04

Указываем, что за основу берем образ ubuntu версии 16.04 из официального репозитория ubuntu на Docker hub. О том, что такое Docker hub читайте здесь.


MAINTAINER zinchenko.us@gmail.com

Имя автора образа. Особенной смысловой нагрузки не несет.


RUN apt-get update && apt-get install -y openssh-server apache2 supervisor
RUN mkdir -p /var/lock/apache2 /var/run/apache2 /var/run/sshd /var/log/supervisor

Инструкция RUN запускает shell команды.
После каждого применения RUN состояние образа сохраняется! В строке следующей после RUN мы будем иметь дело с “обновленной” версией образа.

В первой строке мы устанавливаем необходимые пакеты. openssh-server — будет нужен, если мы захотим управлять сервером по ssh. Тег -y обеспечивает автоматическое подтверждение (yes) при установке.

Во второй строке создаем директории необходимые для пакетов.


COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

COPY копирует файлы из текущей директории (см. изображение 3) в файловую систему создаваемого образа. Файл supervisord.conf — это настройки supervisord. Его мы рассмотрим позже.


EXPOSE 22 80

Важная инструкция. Каким-то образом ваш контейнер должен взаимодействовать с “окружающим миром”. Инструкция EXPOSE говорит о том, что контейнер будет слушать определенные порты. Но это еще не значит, что контейнер будет доступен извне! То, как будет доступен контейнер, определяется во время его запуска. Об этом в продолжении статьи.


CMD [«/usr/bin/supervisord»]

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


5. Посмотрим файл supervisord.conf:

Здесь мы запускаем supervisord, ssh и apache2 сервер в фоновом режиме.


Создание образа Docker

Подготовительная часть закончена. Перейдем к созданию образа. Делается это при помощи команды buildВ общем случае ее используют так:

  • docker build — команда для создания образа
  • флаг -t используется для указания имени образа, которое следует сразу после флага, в нашем случае — ‘example1
  • .   — путь к директории, в которой находится Dockerfile. Т.к. мы уже находимся в C:\docker\example-image, то указываем . (точку)

1. Запускаем. Выполнение может занять некоторое время. build пройдет по всем шагам dockerfile. В результате вы должны получить сообщение об успешном создании образа. Ему будет присвоен ID (подчеркнуто красным):

4

2. Проверим существующие образы. Увидим только что созданный образ:

5

3. Давайте попробуем создать еще один образ с именем example2 на основе того-же dockerfile:

6

Образ создан. Во время второго запуска можно увидеть фразу “Using cache”.

Если теперь мы просмотрим список образов, то увидим, что example1 и example2 построены на основе одного и того же образа (ID 446d260e33e0).

7

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


Готово

Вы только что научились создавать docker-образы. Настало время запускать контейнеры! Читайте продолжение в статье «Запуск docker контейнера».

 

Поделитесь с друзьями или сохраните себе
  •  
  •  
  •  
  •  
  •  
  •  
  •  

8 Comments

  1. Сергей

    > Вы только что научились создавать docker-образы.
    Каким образом мы их научились создавать, если мы всё делали с «FROM ubuntu:16.04» ? Таким способом мы не научились их создавать, а научились использовать (модифицировать) существующие, кем-то подготовленные.
    На много интереснее было бы увидеть описание создания образов с нуля, когда никакие docker hub-ы не используются.
    В LXC, например, есть команда lxc-create, которая создаёт образ с нуля. А как с этим обстоит дело в docker-е ?

    Reply
  2. Сергей

    Смысл собирать руками в том, что мы понятия не имеем что такое «голый» образ ubuntu:16.04, кто и как его готовил, нет ли в нём троянов или устаревшего дырявого ПО. Или вы предлагаете использовать в продакшн среде образы «от Васи» ?
    Также не понятно зачем нужен образ с мини ОС внутри, если основная идея, которую продвигает docker, — иметь в контейнере только файлы необходимые для запуска конкретного сервиса и ничего более.
    Другая идея docker — иметь сценарий, позволяющий при каждой сборке создавать идентичные окружения. Каким образом будет реализована эта идентичность, если мы каждый раз делаем «RUN apt-get update && apt-get install …» ? В продакшн среде у нас поставятся одни версии пакетов, а потом, например, через полгода, какой-то новый разработчик будет у себя поднимать для тестов подобное окружение, и у него поставятся другие версии, т.к. репозиторий за это время успел обновиться.

    Reply
    1. pussy

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

      Reply
    2. pussy

      к тому же если вы взяли FROM официальный образ убунты, причем здесь вася :) вы же саму убунту для серверов тоже не сами пишете, а берете дистрибутив с официального сайта

      Reply

Напишите комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


16 + пятнадцать =