Spring Boot:从 Kubernetes ConfigMap 覆盖 application.yml 属性

时间:2021-02-13 12:03:22

标签: spring-boot kubernetes

我需要检查在 k8s 中运行的 Spring Boot 应用程序的 application.yml 中定义的一些属性。我怎样才能做到这一点?我发现的唯一方法是挂载整个 application.yml,但我只需要覆盖一个属性。

3 个答案:

答案 0 :(得分:1)

Spring Boot 应用程序应该使用环境变量覆盖配置文件中的属性(也就是大多数情况下在它们的 application.yml 中)。

假设应用程序使用 Pod 部署在 Kubernetes 上(但没关系,部署、StatefulSet、作业在环境方面都是相同的),您可以通过将环境变量直接分配给部署本身来将环境变量注入容器内,或使用 ConfigMap(或 Secret,如果属性更安全和屏蔽)

apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
  - name: example-container
    image: example-image:latest
    env:
    - name: THIS_IS_AN_ENV_VARIABLE
      value: "Hello from the environment"
    - name: spring.persistence.url
      value: "The persistence url, for example"

更好的是,您可以将 ConfigMap 的所有内容作为环境变量注入:

apiVersion: v1
kind: ConfigMap
metadata:
  name: example-config
data:
  spring.persistence.url: "your persistence url"
  spring.mail.user: "your mail user"

然后是您的 Pod:

apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
  - name: example-container
    image: example-image:latest
    envFrom:
    - configMapRef:
        name: example-config

在容器内部,变量将在环境中..Spring 应该使用它们来覆盖在 application.yml 中定义(甚至可能未定义)的同名变量

更多信息:

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/ https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/ https://docs.spring.io/spring-boot/docs/1.3.3.RELEASE/reference/html/boot-features-external-config.html

答案 1 :(得分:0)

我们不得不做类似的事情。我向你解释我们是怎么做的。可能这会有所帮助。

如果您可以修改 Dockerfile,则创建一个 entrypoint.sh 脚本。 它可能包含以下内容:

入口点.sh

#!/bin/bash
set -e

# Source custom scripts, if any
if [ -d /etc/spring.d ]; then
    for f in /etc/spring.d/*; do
        if [ -x "$f" ]; then
            echo "Running $f ..." >&2
            "$f"
        else
            echo "Could not run $f, because it's missing execute permission (+x)." >&2
        fi
    done
    unset f
fi

exec "$@"

entrypoint.sh 在启动时执行 /etc/spring.d 目录中的自定义脚本。您可以将任何 exectuble 脚本放入其中,随心所欲。

/etc/spring.d 中,您可以创建一个复制脚本,该脚本将 application.yml 复制到 spring 启动所在的同一目录中jar 文件 位于。示例如下。

您的 Dockerfile 可能看起来像

FROM adoptopenjdk:15-jre
RUN mkdir /app
COPY application.jar /app/
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["java", "-jar", "/app/application.jar"]

如果准备好了,您可以使用 configMap 定义复制脚本并将其挂载到目录 /etc/spring.d

apiVersion: v1
kind: ConfigMap
metadata:
name: spring-d
data:
  copy-yaml.sh: |
    #!/bin/bash
    cp /config/application.yml /app/application.yml

复制脚本将负责将您的 application.yaml(也将作为 configMap 挂载)复制到正确的位置。

以及你的 application.yml 的进一步 configMap

apiVersion: v1
kind: ConfigMap
metadata:
name: app-yaml
data:
  application.yml: |
    spring:
      application:
        name: This is just an example, add as many values as you want.

在您的 pod yaml 中,您可以执行以下操作:

...
    volumeMounts:
    - name: spring-d
      mountPath: /etc/spring.d
    - name: app-yaml
      mountPath: /config
  - name: spring-d
    configMap:
      name: spring-d
      defaultMode: 0777
  - name: app-yaml
    configMap:
      name: app-yaml
...

此代码目前未经测试,只是向您展示了如何以非常灵活的方式解决问题的示例。

我使用了脚本中的片段并将其复制到此处,因此内部可能存在小错误。请告诉我。

答案 2 :(得分:0)

可能以另一种方式可行,这就是我再次回答的原因。 以简单的方式完成。

在 configmap 中创建 application.yml 并将其作为名为 config 的子目录挂载到 spring boot jar ins 所在的同一目录中。

spring boot (external application properties) 的文档说:

<块引用>

当您的应用程序启动时,Spring Boot 会自动从以下位置查找并加载 application.properties 和 application.yaml 文件:

类路径根

类路径 /config 包

当前目录

当前目录下的/config子目录

/config 子目录的直接子目录

这意味着我们不需要设置任何东西。它应该在子目录 config 中找到配置。

apiVersion: v1
kind: ConfigMap
metadata:
name: spring-application-config
data:
  application.yml: |
    spring:
      application:
        name: This is just an example, add as many values as you want.

pod.yaml:

...
    volumeMounts:
    - name: spring-application-config
      mountPath: /app/config
  - name: spring-application-config
    configMap:
      name: spring-application-config
...

假设您的 spring boot jar 文件位于路径 /app

相关问题