Контейнеризация приложения Java
В этом уроке вы будете контейнеризировать приложение Java.
Как упоминалось ранее, контейнеры выполняются непосредственно поверх операционной системы узла, ядра и оборудования, как по сути, просто другой системный процесс. Контейнеры требуют меньше системных ресурсов, что приводит к меньшему объему ресурсов, снижению нагрузки и более быстрому времени запуска приложения. Это отличные варианты использования для масштабирования по требованию.
Существуют контейнеры Windows и контейнеры Linux. В этом модуле вы будете использовать широко используемую среду выполнения Docker для создания образа контейнера Linux. Затем вы развернете образ контейнера Linux в операционной системе узла локального компьютера. Наконец, вы развернете образ контейнера Linux в службе Azure Kubernetes.
Обзор Docker
Среда выполнения Docker используется для создания, извлечения, запуска и отправки образов контейнеров. На следующем рисунке показаны эти варианты использования, за которым следует описание каждого варианта использования или команды Docker.
Команда Docker | Описание |
---|---|
docker build |
Создает образ контейнера; по сути, инструкции и уровни, необходимые для Docker, чтобы в конечном итоге создать запущенный контейнер из образа. Результатом этой команды является изображение. |
docker pull |
Контейнеры инициализируются из образов, которые загружаются из реестров, таких как Реестр контейнеров Azure, откуда их будет загружать служба Azure Kubernetes. Результатом этой команды является извлечение образа из сети, которое будет происходить в Azure. Обратите внимание, что вы можете при необходимости извлекать изображения локально; это часто происходит при создании образов, требующих зависимостей или слоев, для которых может потребоваться приложение, например сервер приложений. |
docker run |
Запущенный экземпляр образа — это контейнер, и эта команда выполняет все уровни, необходимые для запуска и взаимодействия с запущенным приложением контейнера. Результатом этой команды является запущенный процесс приложения в операционной системе узла. |
docker push |
Реестр контейнеров Azure будет хранить образы так, чтобы они были легко доступны и находились в сетевой близости для развертываний и масштабирования Azure. |
Клонирование приложения Java
Сначала клонируйте репозиторий "Flight Booking System for Airline Reservations" и перейдите в папку проекта веб-приложения Airlines.
Заметка
Если создание службы Azure Kubernetes успешно завершено на вкладке CLI, используйте ее; если все еще выполняется, откройте новую вкладку и перейдите в каталог, где вы предпочитаете клонировать систему бронирования авиабилетов.
Выполните следующую команду в интерфейсе командной строки:
git clone https://github.com/Azure-Samples/containerize-and-deploy-Java-app-to-Azure.git
Выполните следующую команду в интерфейсе командной строки:
cd containerize-and-deploy-Java-app-to-Azure/Project/Airlines
Заметка
При необходимости, если установлен Java и Maven, можно выполнить следующие команды в интерфейсе командной строки, чтобы получить представление о создании приложения без Docker. Если у вас нет java и Maven, вы можете безопасно перейти к следующему разделу, Создать файл Docker. В этом разделе вы будете использовать Docker для загрузки Java и Maven, чтобы выполнить сборки для вас.
При необходимости, если у вас есть Maven и JDK(8) или более поздней версии, можно выполнить следующую команду в интерфейсе командной строки:
mvn clean install
Заметка
Мы использовали команду mvn clean install
, чтобы проиллюстрировать трудности, связанные с неиспользованием многоэтапных сборок Docker, которые мы рассмотрим далее. Опять же, этот шаг является необязательным; в любом случае можно безопасно перемещаться по пути, не выполняя команду Maven.
Maven должен успешно построить систему резервирования полетов для резервирования веб-приложений в архиве веб-приложений FlightBookingSystemSample-0.-SNAPSHOT.war, как показано в следующих выходных данных:
[INFO] Building war: /mnt/c/Users/chtrembl/dev/git/containerize-and-deploy-Java-app-to-Azure/Project/FlightBookingSystemSample/target/FlightBookingSystemSample-0.0.1-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 17.698 s
[INFO] Finished at: 2021-09-28T15:18:07-04:00
[INFO] ------------------------------------------------------------------------
Представьте, что вы разработчик Java, и вы только что создали этот FlightBookingSystemSample-0.0.1-SNAPSHOT.war
. Следующий шаг — это, вероятно, работа с инженерами операций, чтобы развернуть этот артефакт на локальном сервере или виртуальной машине. Для успешного запуска и запуска приложения требуется, чтобы серверы и виртуальные машины были доступны и настроены с необходимыми зависимостями. Это сложно и занимает много времени, особенно по требованию, когда увеличивается нагрузка на приложение. С помощью контейнеров эти проблемы устраняются.
Создайте Dockerfile
На этом этапе вы готовы создать Dockerfile. Dockerfile — это текстовый документ, содержащий все команды, которые пользователь может выполнить в командной строке для сборки образа контейнера, каждый из которых является слоем, который можно кэшировать для повышения эффективности и который создаётся на основе предыдущего.
Например, система бронирования полетов для резервирования авиакомпаний должна развертываться и запускаться внутри сервера приложений. Сервер приложений не упаковирован внутри FlightBookingSystemSample-0.0.1-SNAPSHOT.war
; это внешняя зависимость, необходимая для выполнения FlightBookingSystemSample-0.0.1-SNAPSHOT.war
, прослушивания и обработки HTTP-запросов, управления сеансами пользователей и упрощения бронирования полетов. Если это было традиционное неконтейнерное развертывание, инженеры операций установят и настроят сервер приложений на каком-либо физическом сервере и (или) виртуальной машине перед развертыванием FlightBookingSystemSample-0.0.1-SNAPSHOT.war
на нем. Эти инженеры операций также должны убедиться, что JDK используется на вашем компьютере (то, что mvn clean install
использовалось для компиляции .war), фактически соответствует тому же JRE, который используется сервером приложений. Управление этими зависимостями является сложным и трудоемким.
С помощью Dockerfile вы можете написать инструкции (слои), необходимые для автоматизации этого процесса, пошагово добавляя этапы, необходимые для обеспечения, что система бронирования авиабилетов имеет все зависимости, необходимые для развертывания в среду выполнения Docker-контейнеров. Это очень впечатляюще, когда вы начинаете задумываться о масштабировании по запросу в непредвиденные интервалы. Следует отметить, что каждый слой использует кэш Docker, содержащий состояние образа контейнера на каждой вехе инструкции, оптимизируя время вычислений и повторное использование. Если слой не изменяется, используются кэшированные слои. Распространенные варианты использования кэшированных уровней — среда выполнения Java, сервер приложений или другие зависимости для веб-приложения "Система бронирования авиабилетов". Если и когда версия изменяется на ранее кэшированном слое, создается новая кэшированная запись.
На следующем рисунке показаны слои образа контейнера. Вы заметите, что верхний слой — это система бронирования авиабилетов с возможностью чтения и записи, встроенная в уровень веб-приложения, который построен на основе предыдущих уровней только для чтения, формируемых из команд в Dockerfile.
Docker также имеет концепцию многофакторных сборок, функцию, которая позволяет создавать меньший образ контейнера с улучшенным кэшированием и меньшим объемом безопасности, что позволяет повысить оптимизацию и обслуживание Dockerfile с течением времени; Например, инструкции можно использовать для выполнения компиляции приложения (FlightBookingSystemSample-0.0.1-SNAPSHOT.war
), а также сборки самого образа контейнера, оставляя остатки FlightBookingSystemSample-0.0.1-SNAPSHOT.war
компиляции, что приведет к меньшему объему. В долгосрочной перспективе это приносит дивиденды, когда вы начинаете думать об этих изображениях, которые перемещаются по сети. При использовании многоэтапных сборок в Dockerfile используется несколько инструкций FROM. Каждая инструкция FROM может использовать другую базу, и каждая из этих инструкций начинается с чистого листа, удаляя ненужные файлы на уровне кэширования, которые обычно кэшируются.
Необходимо убедиться, что приложение создается тем же JDK, соответствующим той же JRE, которая будет изолирована в образе контейнера во время выполнения. В следующем примере у вас будет этап сборки, который использует определенную версию Maven и определенную версию JDK для компиляции FlightBookingSystemSample-0.0.1-SNAPSHOT.war
. Этот этап гарантирует, что любая среда выполнения Docker-runtime, выполняющая этот этап, получит ожидаемый генерированный байт-код, указанный автором Dockerfile (в противном случае инженеры операций должны будут сопоставлять среды выполнения Java и серверов приложений с параметрами, заданными разработчиком). Затем на этапе упаковки будет использоваться определенная версия Tomcat и JRE, соответствующая JDK на этапе сборки. Опять же, это делается для обеспечения контроля и изоляции всех зависимостей (JDK пакета разработки Java, среды выполнения Java JRE, сервера приложений), чтобы обеспечить ожидаемое поведение на всех компьютерах, на которых будет выполняться этот образ.
Также стоит отметить, что с этой многоэтапной сборкой технически нет необходимости устанавливать Maven и Java на системе. Docker загрузит их для использования как для создания приложения, так и для его выполнения, избегая любых потенциальных конфликтов версий и неожиданного поведения; если, конечно, вы компилируете код и создаете артефакты за пределами Docker.
На следующем рисунке показана многоэтапная сборка и то, что происходит на каждом этапе на основе команд, указанных в Dockerfile. На этапе 0, этапе сборки, компилируется веб-приложение "Система бронирования рейсов для авиарезервирования", и создается FlightBookingSystemSample-0.0.1-SNAPSHOT.war
. Этот этап позволяет обеспечить согласованность версий Maven и Java, используемых для компиляции этого приложения. После создания FlightBookingSystemSample-0.0.1-SNAPSHOT.war
это единственный уровень, необходимый для этапа 1 (этап выполнения), и все предыдущие слои можно отменить. Затем Docker будет использовать этот уровень FlightBookingSystemSample-0.0.1-SNAPSHOT.war
с этапа 0 для создания оставшихся слоев, необходимых для среды выполнения; В этом случае настройте сервер приложений и запустите приложение.
В корневом каталоге проекта, containerize-and-deploy-Java-app-to-Azure/Project/Airlines, создайте файл с именем Dockerfile:
vi Dockerfile
Добавьте следующее содержимое в Dockerfile, а затем сохраните и закройте, нажав клавиши ESC, затем введя :wq! и нажимая Enter.
#
# Build stage
#
FROM maven:3.6.0-jdk-11-slim AS build
WORKDIR /build
COPY pom.xml .
COPY src ./src
COPY web ./web
RUN mvn clean package
#
# Package stage
#
FROM tomcat:8.5.72-jre11-openjdk-slim
COPY tomcat-users.xml /usr/local/tomcat/conf
COPY --from=build /build/target/*.war /usr/local/tomcat/webapps/FlightBookingSystemSample.war
EXPOSE 8080
CMD ["catalina.sh", "run"]
Заметка
При желании файл Dockerfile_Solution в корне вашего проекта содержит нужные данные.
На этом этапе сборки Dockerfile есть шесть инструкций:
Команда Docker | Описание |
---|---|
FROM |
FROM maven будет базовым слоем, на основе которого создается эта FlightBookingSystemSample-0.0.1-SNAPSHOT.war , с конкретной версией Maven и конкретной версией JDK, чтобы обеспечить одинаковую компиляцию байт-кода на всех компьютерах, на которых выполняется эта сборка. |
WORKDIR |
WORKDIR используется для определения рабочего каталога контейнера в каждый конкретный момент времени; В данном случае, это место, где будут находиться скомпилированные артефакты. |
COPY |
COPY добавляет файлы из текущего каталога клиента Docker. Настройка файлов, необходимых для компиляции Maven, pom.xml потребуется контексту Docker. |
COPY |
Настраивает необходимые файлы для компиляции с помощью Maven. Контекст Docker будет нуждаться в папке src, которая содержит систему бронирования полетов для веб-приложения резервации авиабилетов. |
COPY |
Настраивает файлы, необходимые для компиляции с использованием Maven. В веб-докете потребуется папка, содержащая зависимости веб-приложения для системы бронирования авиабилетов. |
БЕЖАТЬ | Инструкция RUN mvn clean package используется для выполнения любой команды на вершине текущего образа. В этом случае run используется для выполнения сборки Maven, которая компилирует FlightBookingSystemSample-0.0.1-SNAPSHOT.war . |
На этом этапе пакета файла Docker есть пять инструкций:
Команда Docker | Описание |
---|---|
FROM |
FROM tomcat будет базовым слоем, поверх которого будет построен образ контейнера. Образ контейнера для системы бронирования авиарейсов будет построен на основе образа Tomcat. Среда выполнения Docker попытается найти образ tomcat локально. Если этой версии нет, она будет загружена из реестра. Если вы проверили образ tomcat, на который ссылается ссылка здесь, вы найдете, что он построен с помощью многих других слоев, все из которых делают его повторно используемым как один упакованный образ контейнера сервера приложений для всего мира, который будет использоваться при развертывании приложения Java. Мы выбрали и проверили tomcat:8.5.72-jre11-openjdk-slim для целей модуля. Обратите внимание, что все предыдущие слои из первого этапа сборки удаляются после того, как Docker распознает эту вторую инструкцию FROM. |
COPY |
COPY tomcat-users.xml скопирует файл tomcat-users.xml, который управляет системой бронирования рейсов для пользователей авиалиний (управляется в системе контроля версий с использованием удостоверения Tomcat; обычно это будет находиться во внешней системе управления удостоверениями) в образ контейнера Tomcat, чтобы он присутствовал в образе контейнера каждый раз при создании образа контейнера. |
ADD |
ADD target/*.war /usr/local/tomcat/webapps/FlightBookingSystemSample.war скопирует скомпилированный maven FlightBookingSystemSample-0.0.1-SNAPSHOT.war в папку webapps образов Tomcat, чтобы убедиться, что при инициализации Tomcat он найдет FlightBookingSystemSample-0.0.1-SNAPSHOT.war для установки на сервере приложений. |
EXPOSE |
EXPOSE 8080 требуется, так как Tomcat настроен для прослушивания трафика через порт 8080. Это гарантирует, что процесс Docker будет прослушивать этот порт. |
CMD |
Инструкция CMD задает команду, выполняемую при запуске контейнера. В этом случае CMD ["catalina.sh", "run"] указывает Docker инициализировать сервер приложений Tomcat. |
Заметка
Без тега версии в строке FROM tomcat
будет применена последняя версия. Как правило, вы хотите использовать тег версии (помните, кэширование применяется, поэтому если слои постоянно изменяются, вы будете нести пропускную способность, задержку, время вычислений и /или побочные эффекты непроверенных сборок или слоев). Для этого модуля мы предварительно выбрали определенные теги Maven, Tomcat и Java JRE/JDK, которые тестируются для работы с FlightBookingSystemSample-0.0.1-SNAPSHOT.war
во время выполнения.
Дополнительные сведения о построении Dockerfile смотрите в справочнике по Dockerfile