Spring application.yaml 从 helm 值中读取复杂的结构,这些值是从 k8s 配置映射中读取的

问题描述 投票:0回答:1

我的 application.yml 中有一个自定义地图,我想更新它而无需每次重新部署,它看起来像这样:

devices:
  RDR:
    name: Radar
    networks:
      - local
  VDR:
    name: VRadar
    networks:
      - local
      - external

我有一个配置映射,其中有经典的键值对:

metadata:
  name: app-env-config
data:
  device-name: vdr

我在 helm value.yaml 中阅读了它

env:
  - name: DEV_NAME
    valueFrom: 
       configMapKeyRef:
         name: app-env-config
         key: device-name

当我的 application.yaml 中有一个简单的值时,这可以完美地工作,但是我想要自定义对象,所以我想将整个设备对象从 configMap 传递到 helm values.yaml 到 application.yaml,但是到目前为止,我还没有找到一种方法来做到这一点,除了覆盖整个 application.yaml 这是我不想做的事情,所以除了只做一个键值对之外,还有什么方法,其中值是一个 json 或其他对象,我将其作为 application.yaml 中的字符串并以某种方式进行解析。这可行,但非常丑陋,而且感觉不对......

spring kubernetes kubernetes-helm
1个回答
0
投票

Spring Boot 可以在很多地方找到配置。它可以读取应用程序 jar 文件中内置的

application.yml
和文件系统中的内容;您可以设置环境变量
SPRING_CONFIG_ADDITIONALLOCATION
来指定额外的非默认配置文件。

这意味着您可以将显示的 YAML 放入 ConfigMap 中,将其安装到容器中,然后将 Spring 指向它。

让我们采取一种方法,将 YAML 内容编写为 Helm 值中的结构化内容

# values-devices.yaml
device:
  name: VDR
  config:
    name: VRadar
    networks:
      - local
      - external

然后您可以将其写入 ConfigMap。我们将在此处生成 YAML。单个 ConfigMap 项需要是字符串,我们将使用 YAML 块标量语法来嵌入 YAML。

# templates/properties-cm.yaml
apiVersion: v1
type: ConfigMap
metadata:
  name: {{ include "app.name" . }}-properties
  labels:
{{ include "app.labels" . | indent 4 }}
data:
  devices.yml: |
    devices:
      {{ .Values.device.name }}:
{{ .Values.device.config | toYaml | indent 8 }}

注意最后一行:我们采用结构化的

config
,将其渲染为
toYaml
,并且
indent
的每一行都位于结构中的正确位置。包含
indent
的模板行从第一列开始,它本身不缩进。

现在在您的 Deployment 中,您需要从 ConfigMap 声明一个容器卷;将其挂载到容器文件系统中;并设置环境变量。

# templates/deployment.yaml
spec:
  template:
    metadata:
      annotations:
        properties-hash: {{ .Values.device | toYaml | sha256sum }}
    spec:
      volumes:
        - name: properties
          configMap:
            name: {{ include "app.name" . }}-properties
      containers:
        - name: ...
          volumeMounts:
            - name: properties
              mountPath: /etc/properties
          env:
            - name: SPRING_CONFIG_ADDITIONALLOCATION
              value: file:/etc/properties/devices.yml

默认情况下,如果更改

values-devices.yaml
文件并重新运行
helm upgrade -f values-devices.yaml
,ConfigMap 将更新,但 Deployment 将保持不变。容器将看到
/etc/properties/devices.yml
文件 change。发生这种情况时,Spring 可以重新加载配置(如何在 Java EE 和 Spring Boot 中热重载属性?),但通常您需要重新启动应用程序。我的示例中的
annotations:
在每个 Pod 元数据中嵌入了设备配置的哈希值,因此如果配置发生变化,Pod 也会被重新创建。

© www.soinside.com 2019 - 2024. All rights reserved.