Переосмысляем виртуализацию java приложений при использовании Docker. Часть 3

Предыдущие части:
Часть 1: часть 1
Часть 2: часть 2

Интегрируем Docker в сборку maven-ом

В предыдущей главе мы создали Dockerfile и развернули в нем наш WAR. Это достигалось копированием этого файла из папки target проекта в папку docker/deploy и запуском докера из командной строки.

В общем-то, не так уж и сложно, но если вы активно занимаетесь разработкой и и хотите изменить свои исходники и тут же протестировать изменения, то процесс станет утомительным. Теперь, если вы работаете в режиме continuous integration: делаете билд на CI сервере и хотите получить запускаемый образ, надо разобраться, как подружить докер с вашим инструментарием CI.

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

В интернете вы можете найти несколько плагинов, для рассмотрения в статье я выбрал этот: rhuss/docker-maven-plugin ссылка. Моя статья не претендует на исчерпывающий разбор и сравнение всех плагинов, поэтому я настоятельно рекомендую изучить сравнение, сделанное Роландом Хуссом: сравнение сравнение. Этот материал поможет вам выбрать наиболее подходящий плагин для ваших задач.

Мои потребности таковы:
1. Возможность создать образ, базирующийся на образе Tomcat и содержащий мое приложение.
2. Возможность запустить образ в процессе сборки для моих собственных тестов.
3. Возможность интегрировать образ с фазой сборки maven test, в которой будут запускаться автоматизированные тесты.

Для этих задач вполне подходит docker-maven-plugin.

О плагине Maven Docker

Плагин хорошо задокументирован, ноя позволю себе сделать выжимку из документации. Плагин состоит из 2 основных компонентов для конфигурирования:

— Процесс сборки образа и конфигурация запуска задается в pom.xml
— Список файлов для копирования в образ задается в assembly.xml

Настройки для сборки и запуска образа задаются в разделе plugins:

Листинг 8. Конфигурация плагина Docker Maven в POM

<build>
        <finalname>helloworld</finalname>
        <plugins>
            <plugin>
                <groupid>org.jolokia</groupid>
                <artifactid>docker-maven-plugin</artifactid>
                <version>0.13.4</version>
                <configuration>
                        <dockerhost>tcp://192.168.99.100:2376</dockerhost>
                        <certpath>/Users/shaines/.docker/machine/machines/default</certpath>
                        <usecolor>true</usecolor>
                   <images>
                        <image>
                                <name>lygado/tomcat-with-my-app:0.1</name>
                                <alias>tomcat</alias>
                                <build>
                                        <from>tomcat</from>
                                        <assembly>
                                           <mode>dir</mode>
                                           <basedir>/usr/local/tomcat/webapps</basedir>
                                           <descriptor>assembly.xml</descriptor>
                                        </assembly>
                                </build>
                                <run>
                                        <ports>
                                           <port>8080:8080</port>
                                        </ports>
                                </run>
                        </image>
                   </images>
                </configuration>
            </plugin>
        </plugins>
  </build>

Как видим, конфигурация проста и состоит из следующих элементов:

Параметры для идентификации плагина
Строки groupId, artifactId, и version

Глобальная конфигурация
Элементы dockerHost и certPath задают ваш докер хост, который назначается при запуске Docker, и путь к сертификату. Путь можно отследить по переменной окружения DOCKER_CERT_PATH.

Конфигурация образа

Все образы в вашей сборке задаются как дочерние элементы image в секции images. Элемент image имеет специфичную структуру, как и секции build и run. Специфичным для образа является элемент name. В данном случае это имя образа состоит из имени пользователя (lygado), и имени образа (tomcat-with-my-app), а также версии образа (0.1). В этих секциях вы можете использовать значения property.

Конфигурация сборки образа

Когда вы собираете образ, как вы ранее делали с помощью команды docker build, вам нужен Dockerfile с описанием действий. Рассматриваемый плагин позволяет использовать докерфайл, но для статьи мы соберем образ по докерфайлу, который создается налету и размещается в памяти. Поэтому мы указываем родительский образ в элементе from – это образ Tomcat.

Плагин maven-assembly-plugin ссылка определяет общую структуру для включения результатов сборки проекта (зависимостей, модулей, документации для выкладывания в онлайн) в один распространяемый архив, и плагин docker-maven-plugin придерживается этого стандарта. В нашем примере мы работаем в режиме dir, это означает что файл из src/main/docker/assembly.xml должны быть скопированы в basedir нашего образа. Другие режимы — это tar, tgz (GZipped Tar), zip. Элемент basedir задает папку назначения внутри образа для копирования файлов. В нашем случае это папка webapps Томката.

Наконец, элемент descriptor сообщает плагину имя файла с инструкциями сборки, он будет в папке src/main/docker. Наш пример упрощенный, поэтому я рекомендую изучить документацию. В частности, я думаю, что вам будет полезно ознакомиться с элементами:

entrypoint и cmd, которые задают команду для запуска образа
env для определения переменных окружения.
runCmds для запуска команд как из Dockerfile
workdir для смены папки
volumes для монтирования

Если кратко: плагин предоставляет все средства для сборки Dockerfile в виде элементов xml.

Конфигурация запуска образа

Когда вы запускаете образ с помощью команды docker run, вы можете передать параметры. В нашем примере мы запускаем так:

docker run -d -p 8080:8080 lygado/tomcat-with-my-app:0.1

Поэтому нужно задать отображение портов.

Элемент run позволяет параметры запуска, и в нем мы указываем что порт 8080 в контейнере надо прокинуть как порт 8080 на докер хосте. С помощью элемента links можно задать связываемые контейнеры. Команда docker:start часто используется для запуска интеграционных тестов, поэтому секция run поддерживает элемент wait для задания паузы. Это время может понадобиться для появления в логе определенной записи или для начала прослушивания определенного URL. Т.е. гарантируется, что образ пришел в рабочее состояние и тесты не завалятся просто из-за поспешного запуска.

Загружаем зависимости

В файле src/main/docker/assembly.xml задаем список файлов для копирования в образ:

Листинг 9. assembly.xml

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
  <dependencysets>
    <dependencyset>
      <includes>
        <include>com.geekcap.vmturbo:hello-world-servlet-example</include>
      </includes>
      <outputdirectory>.</outputdirectory>
      <outputfilenamemapping>helloworld.war</outputfilenamemapping>
    </dependencyset>
  </dependencysets>
</assembly>

В листинге 9 мы видим секцию набора зависимостей, которая включает элемент с нашим артефактом hello-world-servlet-example, мы хотим увидеть его в . папке. Вспомните, что в POM мы задали basedir, которая определяла путь к папке webapps Томката, теперь outputDirectory указывает путь относительно той базовой папки. Иначе говоря, мы хотим развернуть артефакт hello-world-servlet-example в папке webapps.

Плагин поддерживает ряд целей (maven target):

docker:build: сборка образа
docker:start: запуск контейнера
docker:stop: остановка контейнера
docker:push: коммит обра в репозиторий, например, в DockerHub
docker:remove: удалить образ с Docker хоста
docker:logs: просмотр логов контейнера

Собираем образ

Вы можете скачать исходники с GitHub исходники и собрать командой:

mvn clean install

Для сборки образа используйте команду:

mvn clean package docker:build

После сборки вы можете убедиться в появлении образа:

$ docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
lygado/tomcat-with-my-app   0.1                 1d49e6924d19        16 minutes ago      347.7 MB

Запускаем контейнер:

mvn docker:start

Теперь он должен появиться в выводе команды docker ps. Наш сервлет должен прослушивать URL:

http://192.168.99.100:8080/helloworld/hello

Останавливаем контейнер:

mvn docker:stop

Заключение

Docker – это скорее технология виртуализации на уровне процессов, а не на уровне машин. Docker состоит из клиентского процесса, который взаимодействует с демоном, который запущен на хосте Docker. В linux демон запускается как процесс ОС, в то время как в Windows и Mac он стартует как линуксовая виртуальная машина в VirtualBox и уже в ней работает демон. Образы докера содержат минимальный слой ОС, необходимый для работы, и все бинарники/библиотеки для работы вашего приложения. Образы управляются докерфайлами, в которых содержатся инструкции по конфигурированию.

В этом учебном руководстве я рассказал об азах использования докера, рассмотрел структуру докерфайлов для CentOS, Java, и Tomcat, и показал, как сделать на базе Томката свой образ. В конце статьи мы подключили к нашей сборке плагин docker-maven-plugin. Сделав создание образа и запуск контейнера частью процесса сборки, мы упростили тестирование. Это также позволяет организовать создание образов, готовых для развертывания в продакшн, на CI сервере.

You can leave a response, or trackback from your own site.

Leave a Reply