在使用云原生 buildpack 构建的 spring 引导应用程序中创建一个目录到 kubernetes 上的 运行

Create a directory in a spring boot application built with cloud native buildpack to run on kubernetes

我需要在使用云原生构建包构建的映像中创建特定目录。这是一个 spring-boot 应用程序,我使用它附带的标准云原生构建包。

对于 Dockerfile,这是我将如何做的一个片段:

FROM openjdk:11-jre-slim
RUN mkdir -p /data/stream-price-service
RUN addgroup kstream && useradd -m kstream -g kstream
RUN chown -R kstream:kstream /data/stream-price-service
USER kstream:kstream

因此,当应用程序启动时,它拥有文件夹 /data/stream-price-service 的访问权限和所有权,并且可以将其用作本地存储位置。

因此,对于 buildpack,我还需要在容器启动时目录 data/stream-price-service 存在并且是 spring-boot 应用程序的读写目录。我尝试使用 <directories> 配置,但它没有创建目录:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <image>
            <name>stream-price-service</name>
        </image>
        <directories>/data/stream-price-service</directories>
    </configuration>
</plugin>

以上配置无效

使用 spring 引导构建包创建映像,如何创建目录结构并分配所有权以便在容器启动时可用?

默认情况下,buildpack 运行 作为 non-root 用户和名为 cnb 的组。它不能在 root 下创建任意目录,如 /data。它只能在某些位置创建目录,例如 /layers(buildpacks 安装的地方)或 /workspace(应用程序所在的位置,尽管不推荐这样做)。

当您的应用程序 运行s 时,它也将作为 cnb 用户和组执行,这为您提供了与构建包类似的访问权限。为了增强安全性,生成的 OCI 图像可以 运行 作为不同的用户。在这种情况下,您只能写入组可写或 world-writable(如 /tmp)的位置。

最好的情况是,您可以将您的应用程序更改为在其他地方编写。使目录可配置(@Value@ConfigurationProperties),Spring 非常灵活,因此您可以通过环境变量、系统属性或参数传递配置。然后改为写入该位置。

如果你不能改变位置,那就更难了。目前,没有一种简单的方法来更改基本图像。您基本上需要创建自定义 运行 图像。

full process to create a custom stack is here,但是,您不需要完整的堆栈,只需要自定义 运行 图片。

如果您基于当前使用的 Paketo 运行 图片,例如 paketobuildpacks/builder:basepaketobuildpacks/builder:tiny,您可以将您需要的位置添加到自定义 运行 图像,将 cnb 用户的权限更改为 read/write,然后 switch the run image when you buildrunImage 属性 与 Spring 启动构建或带有 pack build.

--run-image 标志

要基于 Paketo 图像之一,只需创建一个 Dockerfile 并添加 FROM <paketo-run-image>

例如:

FROM paketobuildpacks/run:base-cnb

USER root
RUN mkdir /data && chown cnb:cnb /data
USER cnb

然后pack build cool-image --run-image custom-run-base.