簡體   English   中英

在 Spring Boot Maven 插件創建的 Docker 鏡像中安裝包

[英]Install package in Docker image created by Spring Boot Maven plugin

我的 Spring Boot 項目包含 Spring Boot Maven 插件,我使用它通過運行mvn spring-boot:build-image來構建 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命令運行運行狀況檢查,但不幸的是默認 buildpack 未安裝curl

是否可以進一步調整圖像構建過程,以便將curl安裝到圖像中? 我找不到必要的信息

TLDR;

使用以下命令將curl安裝到構建映像中:

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

使用docker ps -a已停止容器的 Crab 容器 ID:

$ 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 應用程序:

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

現在curl應該在你的容器中准備好了。


解決方案詳情:

Cloud Native Buildpacks (CNBs) 和 Paketo.io 背后的原因,基本上被spring-boot-maven-pluginbuild-image目標抽象出來,是讓我們無需編寫/維護我們自己的Dockerfiles 所以這個倒過來是:配置構建過程很容易,但改變安裝包之類的東西並不容易。

原因是,這些包維護在所謂的堆棧中,它管理使用的buildrun映像。 如果堆棧沒有為您的操作系統級依賴項定義Mixin ,那么您不能簡單地添加另一個包。 創建自己的簡單 buildpack也是不夠的(我嘗試過這種方法)。 創建自己的堆棧、構建包和/或構建器也會抵消雲原生構建包提供的巨大好處! 除其他事項外,我們還將被迫自行更新圖像......

但還有另一種解決方案。 由於我們不想創建自己的堆棧/構建包,我們可以調整由 CNBs/ spring-boot-maven-plugin創建的容器鏡像。 因為官方文檔向我們展示了如何掛鈎生成的容器的啟動過程並運行 shell 腳本。 假設我們的mvn spring-boot:build-image命令生成了一個名為my-app:0.0.1-SNAPSHOT的容器鏡像。

然后首先我們將curl安裝到圖像中:

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 用戶運行,這會引入各種安全問題。 此外,我們已經覆蓋了容器的ENTRYPOINT ,因此它無法啟動我們的應用程序。

因此,我們只需使用新命令、入口點和用戶啟動這個停止的容器 只需使用docker ps -a獲取已停止容器的容器 ID:

$ 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 )和一個靜態編譯的 curl( https://github.com/moparistthebest/static-curl )和配置的健康檢查器,比如

/utils/curl http://localhost:8080/actuator/health

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM