Почему контейнеры?
В мире, где пользователи обращаются к приложениям, способным возвращать данные за считанные миллисекунды, есть единственный в своем роде инструмент, который любая компания стремится использовать для решения проблем, связанных с увеличением емкости запросов… Контейнеры.
Независимо от того, пользуетесь ли вы Docker, Kubernetes или Amazon Elastic Compute Service (ECS) — все они упрощают управление увеличенной нагрузкой на систему, поскольку они предоставляют механизм автоматического масштабирования приложений всякий раз, когда оказывается превышен определенный порог (метрики для процессора, оперативной памяти и т. д.).
Старая ситуация с образами в Docker
Когда Docker только выпустили, разработчикам потребовалось некоторое время, чтобы привыкнуть к синтаксису и понять, как им контейнеризировать свои приложения, учитывая монтирование томов, экспозицию портов и многое другое.
FROM openjdk:8-jdk-alpine
COPY ./build/libs/*.jar application.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","application.jar"]
Это пример очень простого файла DockerFile, который позволит развернуть приложение на порту 8080. Для тех, кто ничего не знает о докере, это, вероятно, похоже на китайский язык…
Мне доводилось видеть файлы длиной более 100 строк, соответствующие таким простым вещам, как приложение для потоковой передачи видео.
Милые ребята из Pivotal, приобретенной VMWare, решили, что могут помочь в этом деле, поэтому добавили кое-что в последний релиз Spring!
Облачные нативные пакеты сборки
Если вам когда-либо доводилось работать с приложением на управляемой платформе, например CloudFoundry, вы так или иначе задействовали пакеты сборки, даже если не осознавали этого! Из-за недавнего обновления способа обработки они были отделены от платформ, и родился новый тип, известный как Cloud Native Build Packs (CNBP). Облачные нативные пакеты сборки — это в точности то, что предполагает их название: один раз пишете, запускаете где угодно.
В Spring 2.3, если говорить более конкретно, есть Paketo.
Генерация команды
Spring 2.3 теперь поддерживает CNBP (Paketo) из коробки. Вы можете создать и запустить приложение Spring внутри Docker без какой-либо дополнительной настройки — одной-единственной командой из терминала!
Maven: ./mvnw spring-boot:build-image
Gradle: ./gradlew bootBuildImage
Да, для запуска требуется определенное время — но постарайтесь вспомнить: мы получаем всё прямо “из коробки”.
Теперь, когда сборка завершена, подготовьте Docker-демона к работе, а потом просто запустите контейнер (имя образа у вас будет отличаться).
docker run -p 8080:8080 docker.io/library/docker:0.0.1-SNAPSHOT
Вот и всё! Ваше приложение теперь работает в Docker, и вы готовы развернуть его на любой выбранной вами платформе!
Библиотека JIB от Google
Альтернативный способ автоматического создания и развертывания контейнеров — библиотека JIB от Google. Хотя выходные данные по-прежнему представляют собой облачный Docker-образ, который может работать где угодно, Google решил дополнительно оптимизировать способ построения слоев образа, чтобы добиться максимальной производительности (времени сборки) при каждом развертывании.
Куда делись контекст сборки и кэш изображений, спросите вы? Хороший вопрос. Google решил, что JIB разбирает ваше приложение на логические слои (к примеру, уровень приложения, уровень зависимостей, так далее), собирает только те части приложения, которые изменились (в то время как Docker собирает всё целиком), и автоматически генерирует образ, отправив его прямо в реестр контейнеров по вашему выбору или локальному демону Docker.
Генерация команды
Когда речь заходит о создании образа, у вас есть два варианта: либо удаленный репозиторий, либо прямой доступ к локальному демону Docker.
mvn compile jib:build (remote registry)
mvn compile jib:dockerBuild (local Daemon)
./gradlew jib (remote registry)
./gradlew jibDockerBuild (local Daemon)
Итоги
Итак, мы рассмотрели два различных метода создания образов Docker для приложения Spring Boot, совместимого со всеми платформами, которые можно себе представить. Хотя результат один и тот же, каждый из этих способов имеет свои преимущества и подводные камни, поэтому убедитесь, что тщательно продумали вариант использования, изучили документацию, а затем уже приняли обоснованное решение о том, какой метод применять для следующего проекта.
Надеюсь, статья была полезной!
Ресурсы
Документация Spring 2.3 по Docker: https://spring.io/blog/2020/01/27/creating-docker-images-with-spring-boot-2-3-0-m1
Документация Cloud Native Build Packs: https://buildpacks.io
Документация Paketo: https://paketo.io
Библиотека JIB: https://cloud.google.com/java/getting-started/jib
Читайте также:
- Советы по Docker: очистка локального компьютера
- Docker: привязываем порты
- Учимся избегать null-значений в современном Java. Часть 1
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи: Emile Bronkhorst, “Generate Docker images with Spring Boot”