Установить пакет в образ Docker, созданный плагином Spring Boot Maven

Мой проект Spring Boot содержит плагин Spring Boot Maven, который я использую для создания образа Docker, запустив mvn spring-boot:build-image.

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>build-image</goal>
            </goals>
        </execution>
    </executions>
</plugin>

При развертывании этого образа в стеке Docker мне нужно запустить проверку работоспособности с помощью curl команда но к сожалению curl не устанавливается пакетом сборки по умолчанию.

Можно ли дополнительно настроить процесс создания образа, чтобы curlустанавливается в iamge? Я не смог найти нужную информацию

2 ответа

TLDR;

Установите в образ сборки с помощью:


Идентификатор крабового контейнера остановленного контейнера с:


Создайте новый образ контейнера на основе того, в который мы установили:


Запустите новый контейнер, определяющий правильный запуск приложения Spring Boot:


Теперь все должно быть готово внутри вашего контейнера.


Детали решения:

Обоснование Cloud Native Buildpacks (CNB) и Paketo.io, которые в основном абстрагируются от build-imageцель состоит в том, чтобы освободить нас от необходимости писать/обслуживать собственные Dockerfiles. Итак, инверсия: легко настроить процесс сборки, но нелегко изменить такие вещи, как установленные пакеты.

Причина в том, что эти пакеты хранятся в так называемом стеке , который управляет используемым build-время и runизображения времени. И если стек не определяет Mixin для вашей зависимости на уровне ОС , вы не можете просто добавить еще один пакет. Также было бы недостаточно создать свой простой билдпак (я пробовал этот подход). А создание собственных стеков, сборочных пакетов и/или сборщиков также сведет на нет огромные преимущества, предоставляемые Cloud Native Buildpacks! Среди прочего, мы также были бы вынуждены сами обновлять изображения...

Но есть другое решение.Поскольку мы не хотим создавать свои собственные стеки/пакеты сборки, мы можем настроить образ контейнера, созданный CNB/ spring-boot-maven-plugin. Потому что официальные документы показывают нам, как подключиться к процессу запуска созданных контейнеров и, например, запустить сценарии оболочки. Предположим, наш mvn spring-boot:build-imageкоманда создала образ контейнера с именем my-app:0.0.1-SNAPSHOT.

Затем сначала мы устанавливаем в образ с помощью:

      docker run --user="root" --entrypoint launcher my-app:0.0.1-SNAPSHOT "apt-get update && apt-get install curl -y"

Нам нужно использовать --user="root"здесь для того, чтобы команда apt-get update && apt-get install curl -yбудет работать успешно (иначе мы столкнулись бы с такими ошибками, как List directory /var/lib/apt/lists/partial is missing. - Acquire (13: Permission denied)). Это установит curl, но мы не должны использовать полученный контейнер в продакшене. Потому что наше приложение Spring Boot будет работать от имени пользователя root, что создаст множество проблем с безопасностью. Также мы перезаписали наш контейнер, поэтому он не сможет запустить наше приложение.

Поэтому мы просто запускаем этот остановленный контейнер с новой командой , точкой входа и пользователем! Просто возьмите идентификатор контейнера остановленного контейнера с помощью docker ps -a:

      $ docker ps -a
CONTAINER ID   IMAGE                                  COMMAND                  CREATED          STATUS                       PORTS     NAMES
2ff7db32825f   my-app:0.0.1-SNAPSHOT   "launcher 'apt-get u…"   44 minutes ago   Exited (0) 44 minutes ago              reverent_swanson

И создайте новый образ контейнера на основе того, который мы установили. curlв с:

      docker commit 2ff7db32825f my-app-with-curl

Наконец , запустите новый контейнер на основе этого нового изображения, определив правильный ENTRYPOINTчтобы запустить наше приложение Spring Boot, а также с помощью cnbснова пользователем (как определено в Cloud Native Buildpacks):

      docker run --rm -p 8080:8080 --user="cnb" --entrypoint /cnb/process/web my-app-with-curl

Не по теме, но актуально :

В настоящее время ведутся дискуссии о целесообразности установки curl в производственном контейнере. См. этот пост, например .

В итоге я использовал смонтированный том ( /utilsнапример) со статическим скомпилированным завитком (https://github.com/moparisthebest/static-curl) и настроенной проверкой работоспособности, например

      /utils/curl http://localhost:8080/actuator/health
Другие вопросы по тегам