Как засунуть существующую программу в контейнеры с помощью Docker

1656547815 kak zasunut sushhestvuyushhuyu programmu v kontejnery s pomoshhyu docker

Даниель Ньютон

1*mxgRaQctGgv6qSSjNrq1JQ
Гонконг Марси Марк

Я наконец-то научился использовать Docker, не зная, что это такое, и не пользуясь им. Это первая публикация, в которой я попытался использовать Docker и, вероятно, я буду обращаться к ней, когда начинаю новый проект (во всяком случае, для Java или Kotlin).

Это будет краткая публикация, берущая существующий проект (из одной из других моих публикаций) и изменяющая его, чтобы он мог работать внутри контейнеров. Проект представляет собой приложение Spring Boot с базой данных MongoDB и очередью сообщений ActiveMQ. Все эти составляющие являются главным кормом для контейнерирования.

Выполнение шагов, описанных в этой публикации, снимает необходимость локальной установки MongoDB и ActiveMQ. Просто установите Docker и все готово. Это уже само по себе победа в моих книгах.

Вот ссылка на код и соответствующую публикацию в блоге. Пост охватывает всю информацию о коде.

Последний комментарий: что касается содержимого этой публикации, я предполагаю, что вы уже установили Docker. Если вы этого не сделали, значит, Docker уже снабдил вас. Вот где вы можете найти поддерживаемые платформы, содержащие дополнительные ссылки на то, как установить Docker для вашей конкретной машины. Страница ориентации и настройки, предоставляемая Docker, также может быть полезна.

Преобразование программы Spring

Во-первых, программа Spring Boot.

Это единственная часть проекта, содержащая наш код. Остальные – изображения, загруженные из чужого хранилища. Чтобы начать двигать это приложение к работе в контейнере, нам нужно создать файл a Dockerfile определяющий содержание изображения:

Это берет базовое изображение openjdk:8-jdk-alpine. Это хорошая отправная точка для приложения. Он добавляет Jar, созданный из кода программы (называя его app.jar) и открывает порт для связи между контейнерами. Последняя строка определяет команду, выполняемую при запуске изображения в контейнере. Это то, что запускает приложение Spring.

Чтобы построить образ из Dockerfile выполните следующую команду (предполагая, что вы уже создали код программы):

docker build -t spring-boot-jms-tutorial .

Теперь есть изображение с именем spring-boot-jms-tutorial (-t давайте определим название). Теперь это можно использовать для создания контейнера, выполняющего код, упакованный в Jar изображение:

docker run --name application -p 4000:8080 spring-boot-jms-tutorial

Это создаст и запустит контейнер, созданный на основе файла spring-boot-jms-tutorial изображение. Он называет контейнер application и -p свойство позволяет отображать порт локальной машины на порт внутри контейнера. Для доступа в порт 8080 контейнера нам просто нужно использовать port 4000 на нашей собственной машине.

Если мы остановили этот контейнер и хотим запустить его снова, мы должны использовать команду:

docker start application

Где application это название контейнера, который мы создали раньше. Если docker run был использован снова, он создал бы другой новый контейнер, а не повторно использовал существующий. На самом деле, потому что мы предоставили имя контейнера, который запустил то же самое run Предыдущая команда приведет к ошибке.

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

Ошибка подключения MongoDB:

Exception in monitor thread while connecting to server mongocontainer:27017 com.mongodb.MongoSocketException: mongocontainer: Name does not resolve at com.mongodb.ServerAddress.getSocketAddress(ServerAddress.java:188) ~[mongodb-driver-core-3.6.4.jar!/:na] at com.mongodb.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:59) ~[mongodb-driver-core-3.6.4.jar!/:na] at com.mongodb.connection.SocketStream.open(SocketStream.java:57) ~[mongodb-driver-core-3.6.4.jar!/:na] at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:126) ~[mongodb-driver-core-3.6.4.jar!/:na] at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:114) ~[mongodb-driver-core-3.6.4.jar!/:na] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_171] Caused by: java.net.UnknownHostException: mongocontainer: Name does not resolve at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method) ~[na:1.8.0_171] at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928) ~[na:1.8.0_171] at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323) ~[na:1.8.0_171] at java.net.InetAddress.getAllByName0(InetAddress.java:1276) ~[na:1.8.0_171] at java.net.InetAddress.getAllByName(InetAddress.java:1192) ~[na:1.8.0_171] at java.net.InetAddress.getAllByName(InetAddress.java:1126) ~[na:1.8.0_171] at java.net.InetAddress.getByName(InetAddress.java:1076) ~[na:1.8.0_171] at com.mongodb.ServerAddress.getSocketAddress(ServerAddress.java:186) ~[mongodb-driver-core-3.6.4.jar!/:na] ... 5 common frames omitted

ActiveMQ также нет:

Could not refresh JMS Connection for destination 'OrderTransactionQueue' - retrying using FixedBackOff{interval=5000, currentAttempts=1, maxAttempts=unlimited}. Cause: Could not connect to broker URL: tcp://activemqcontainer:61616. Reason: java.net.UnknownHostException: activemqcontainer

Мы разберем их в следующих разделах, чтобы программа могла работать полностью.

И последнее, прежде чем мы перейдем в Mongo и ActiveMQ.

The dockerfile-maven-plugin также можно использовать, чтобы помочь с вышеупомянутым, который создает контейнер как часть запуска mvn install. Я решил не использовать его, поскольку не мог заставить его работать должным образом docker-compose. Ниже приведен краткий пример использования плагина:

Это затем позволяет нам заменить несколько строк в Dockerfile:

Здесь добавлена ​​одна строка и изменена одна существующая строка. The JAR_FILE аргумент заменяет оригинальное название Jar, которое вводится в плагин из файла pom.xml. Внесите эти изменения и запустите mvn install и бац, ваш контейнер создан со всем необходимым кодом.

Использование образа MongoDB

Существует готовый образ MongoDB, ожидающий использования. Он идеально назван mongo… Чего еще вы ожидали? Все, что нам нужно сделать, это run изображение и дать его контейнеру название:

docker run -d --name mongocontainer mongo

Добавление -d запустить контейнер в фоновом режиме. Название контейнера предназначено не только для удобства, поскольку приложение Spring понадобится позже для подключения к Mongo.

На изображение ActiveMQ

Настроить ActiveMQ так же просто, как Mongo. Выполните команду ниже:

docker run -d --name activemqcontainer -p 8161:8161 rmohr/activemq

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

Связывая это все вместе

Если бы вы выполняли все эти команды, читая сообщение, вы бы заметили, что application контейнер действительно не смог увидеть mongocontainer и activemqcontainer. Это потому, что они не работают в одной сети. Заставить их общаться несложно и требует всего несколько дополнительных шагов.

По умолчанию Docker создает сеть Bridge при ее настройке без дополнительной конфигурации. Ниже описано, как это сделать:

docker network create network

Теперь, когда сеть (название network), то команды, которые были запущены ранее, нужно изменить, чтобы создать подключаемые к сети контейнеры. Ниже приведены 3 команды, используемые для создания контейнеров в предыдущих разделах, каждая из которых изменена для подключения к сети.

docker run -d --name mongocontainer --network=network mongodocker run -d --name activemqcontainer -p 8161:8161 --network=network rmohr/activemqdocker run --name application -p 4000:8080 --network=network spring-boot-jms-tutorial

После того как все они запущены, программа в целом будет работать. Каждый контейнер может видеть друг друга. Разрешая application контейнер для подключения к MongoDB и ActiveMQ в соответствующих контейнерах.

Сейчас все работает. Он работает так же, как я помню, как он работал, когда все было настроено на моем ноутбуке. Но на этот раз ничего не настроено локально… За исключением Docker!

Докер создает его

Мы могли бы остановиться на достигнутом, но следующий раздел сделает все проще. Docker Compose позволяет нам эффективно объединить все запускаемые ранее команды и запустить все контейнеры и их сеть в одной команде. Есть еще некоторые настройки, но в конце концов я думаю, что количество ввода на самом деле уменьшается.

Для этого нам нужно создать a docker-compose.yml файл:

Используйте эту версию Dockerfile:

Это почти все, что нужно сделать.

appcontainer – это контейнер программы Spring, созданный из кода проекта. The build свойство контейнера указывает Docker создать образ на основе проектов Dockerfile найден в корневом каталоге проекта. Оно проходит в JAR_FILE аргумент к Dockerfile вместо этого переместить некоторые конфигурации в этот файл.

Два других контейнера не требуют особой настройки. Как и в предыдущих командах, изображения, из которых они созданы, указываются и activemqcontainer добавляет конфигурацию вокруг сопоставленных портов.

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

Все, что осталось сделать, это запустить up команда:

docker-compose up

Это позволит создать и запустить все контейнеры. При необходимости создается образ кода программы. Выполнение этой команды выведет все журналы контейнеров на консоль, чтобы сделать это в фоновом режиме. -d флаг:

docker-compose up -d

После этого мы можем просмотреть созданные контейнеры и сеть. Бег:

docker ps -a --format "table {{.Image}}\t{{.Names}}"

Показывает нам:

IMAGE                          NAMESmongo                          spring-boot-jms_mongocontainer_1spring-boot-jms_appcontainer   spring-boot-jms_appcontainer_1rmohr/activemq                 spring-boot-jms_activemqcontainer_1

И сеть:

docker network ls

Производит:

NETWORK ID       NAME                      DRIVER            SCOPE163edcfe5ada     spring-boot-jms_default   bridge            local

К наименованию контейнеров и сети относится заглавие проекта.

Вывод

Это все, что есть… для простой настройки. Я уверен, что боги Докера могут сделать гораздо больше, но я не один из них… Пока.

В заключение мы взяли существующую программу, которую я написал, чтобы она работала локально на машине, и засунули все в несколько контейнеров. Это означало, что мы перешли от машины, на которой нужно было все настроить (с установленными как MongoDB, так и ActiveMQ), к машине, которая могла бы пропустить все это с помощью контейнеров и требовала только установки Docker. Затем Docker управляет всеми зависимостями за нас.

Мы рассмотрели, как переместить каждую часть программы в контейнер, а затем связали все вместе с помощью Docker Compose. Оставив нам, в конце всего этого, одну команду, которая может перевести нас от абсолютно ничего ко всему необходимому для запуска программы.

Код, использованный в этой публикации, можно найти на моем GitHub.

Если вы обнаружили эту публикацию полезной, вы можете подписаться на меня в Twitter на @LankyDanDev, чтобы быть в курсе моих новых публикаций.

Мнения и мнения, изложенные в моих публикациях, являются моими собственными и не представляют мнения Accenture на какую-либо тему. Посмотреть все сообщения Дена Ньютона

Первоначально опубликовано на lankydanblog.com 2 сентября 2018 года.

Добавить комментарий

Ваш адрес email не будет опубликован.