【问题标题】:Managing Dockerfile dynamically for different tenants in CI/CD pipeline implementation在 CI/CD 管道实现中为不同租户动态管理 Dockerfile
【发布时间】:2019-10-21 09:53:31
【问题描述】:

我正在尝试使用 Docker、Kubernetes 和 Jenkins 为我的项目实施 CI/CD 管道。我的应用程序是多租户应用程序,其中数据库应用程序变量对于不同的租户来说都是不同的。

应用策略

当我构建 Docker 映像时,我使用的是 Dockerfile。我将 Dockerfile 保存在我的 SVN 代码存储库中。对于每个租户,代码存储库都是相同的。当我在构建镜像时,我需要为不同的租户构建不同的镜像。

Dockerfile 实现

在我的 docker 文件中,我添加如下入口点,

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=tenant1config" , "TestProject.war"]

如果我需要为其他租户构建 Docker 镜像,需要添加
-Dspring.profiles.active=tenant2config

所以 Dockerfile 中的入口点是动态的。

我的困惑

  1. 用于管理 Dockerfile 中的入口点命令是否可以通过动态方式实现?
  2. 或者我是否需要为另一个租户添加另一个 Dockerfile?并且需要为单独的租户单独运行 docker build 命令?

我怎样才能找到一个很好的标准方法来解决这个问题?

【问题讨论】:

  • 您可以在ENTRYPOINT 中使用环境变量,即... -Dspring.profiles.active=${TENANT},然后在部署期间设置正确的环境。

标签: docker dockerfile


【解决方案1】:

引用12 Factor - Config

应用的配置是在部署(暂存、生产、开发人员环境等)之间可能发生变化的所有内容。这包括:

  • 数据库、Memcached 和其他支持服务的资源句柄

  • Amazon S3 或 Twitter 等外部服务的凭据

  • 每个部署的值,例如部署的规范主机名

您应该为每个租户构建单独的 docker 映像,因为二进制文件应该相同,并且任何运行时配置都应该通过环境注入。

注入运行时配置有不同的选项

  1. 环境变量

不要在入口点中硬编码配置文件,而是添加一个环境变量

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=$TENANT_PROFILE" , "TestProject.war"]

然后从kubernetes部署配置中注入环境变量参考https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/

  1. 将配置文件配置挂载为配置并引用它

你的入口点看起来像

ENTRYPOINT ["java", "-jar", --spring.config.location="file:/path/to/tenantconfig.yaml" , "TestProject.war"] 然后将所需的配置文件挂载为 kubernetes 配置。

无论哪种方式,将运行时配置从 docker 映像外部化,并通过部署配置将其作为环境变量或配置注入。

【讨论】:

  • SPRING_PROFILES_ACTIVE 作为环境变量应该可以开箱即用。不需要java附加参数。
【解决方案2】:

您可以使用 docker ARGS,这仅在构建时可用,并且可以在入口点使用。

docker build --build-arg CONFIG_FILE=<file_name> -t tag_name .

CONFIG_FILE 将保存配置文件的位置,您可以动态传递它。将您的入口点替换为$CONFIG_FILE

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=$CONFIG_FILE" , "TestProject.war"]

【讨论】:

  • ARG CONFIG_FILE - 应该在 Dockerfile 中声明
【解决方案3】:

参考 - Dockerfile Best Practices

ENTRYPOINT 帮助您将容器配置为作为可执行文件运行,该可执行文件可以在运行时接受参数

您想要覆盖的任何动态属性都可以在运行时使用相同的图像完成。

您可以在运行时传递必要的参数。

【讨论】:

    猜你喜欢
    • 2018-10-17
    • 2021-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多