Helm:从 json 个文件覆盖配置,有没有更好的方法?
Helm: Overwrite configuration from json files, is there a better way?
我们使用 helm 在不同的系统上部署一个微服务。
除其他外,我们有一个 ConfigMap 模板,当然还有一个包含服务回购中默认值的值文件。其中一些值是 JSON,目前存储为 JSON 字符串:
apiVersion: v1
data:
Configuration.json: {{ toYaml .Values.config | indent 4 }}
kind: ConfigMap
metadata:
name: service-cm
config: |-
{
"val1": "key1",
"val2": "key2"
}
我们还有一个部署仓库,其中定义了不同的系统。在这里,我们也用 json 字符串覆盖了值。
由于这些 json 字符串的可用性不太好,我们想将它们移动到 json 文件中。
我们使用 AKS 和 Azure Pipelines 来部署服务。
我们创建图表:
helm chart save Chart $(acr.name).azurecr.io/$(acr.repo.name):$(BUILD_VERSION)
并推送:
helm chart push $(acr.name).azurecr.io/$(acr.repo.name):$(BUILD_VERSION)
并在另一个作业中拉取和导出后升级:
helm upgrade --install --set image-name --wait -f demo-values.yaml service service-chart
我们已经完成的是使用 --set-file:
在升级命令中设置 json 配置
upgrade --install --set image-name --wait -f demo-values.yaml --set-file config=demo-config.json service service-chart
虽然仅适用于不同系统的值,但不适用于默认值。但我们也想外包这些,也不想没有它们。
因此此时第一个问题,是否有办法为每个文件注入默认值,以便它们位于保存的图表中?
我们知道您可以使用以下语法读取模板中的文件:
Configuration.json: |-
{{ .Files.Get "default-config.json" | indent 4 }}
但我们不能推翻它。另一个想法是从值中注入路径:
Configuration.json: |-
{{ .Files.Get (printf "%s" .Values.config.filename) | indent 4 }}
但是路径好像是相对于图表文件夹的。所以没有部署 repo 的路径。
我们现在有以下带有条件模板的解决方案:
data:
{{ if .Values.config.overwrite }}
Configuration.json: {{ toYaml .Values.config.value | indent 4 }}
{{ else }}
Configuration.json: |-
{{ .Files.Get "default-config" | indent 4 }}
{{ end }}
在部署回购中,值文件如下所示:
config:
overwrite: true
value: will_be_replaced_by_file_content
并且demo-config.json
是通过管道中的升级命令设置的。
这可行,但对我们来说似乎有点繁琐。那么问题来了:你知道更好的方法吗?
在您的第一个设置中,.Values.config
是一个字符串。 key: |-
语法创建了一个 YAML block scalar,其中包含一个恰好是 JSON 的缩进文本块。 helm install --set-file
也将一个值设置为一个字符串,.Files.Get
returns 一个字符串。
所有这些都是字符串,这意味着您可以简化围绕它们的逻辑。例如,考虑 Helm default
模板函数:如果它的参数是一个空字符串,它在逻辑上是假的,所以 default
回退到它的默认值。
在您的最终布局中,您希望将默认配置保留在单独的文件中,但只有在未提供覆盖配置时才使用它。因此,您可以采用以下方法:
在values.yaml
中,config
为空串。 (null
或者根本不定义它也适用于此设置。)
# config is a string containing JSON-format application configuration.
config: ''
因为你已经有了它,.Files.Get "default-config.json"
可以作为后备值。
使用 default
函数检查 .Values.config
是否为 non-empty,如果不是,则返回默认值。
使用 helm install --set-file config=demo-config.json
在部署时提供备用配置。
更新后的 ConfigMap 可能如下所示:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "myapp.fullname" . }}
data:
Configuration.json:
{{ .Values.config | default (.Files.Get "default-config.json") | indent 4 }}
(因为任何形式的 .Values.config
都是字符串,所以它不是一个复杂的结构,您不需要对其调用 toYaml
。)
我们使用 helm 在不同的系统上部署一个微服务。
除其他外,我们有一个 ConfigMap 模板,当然还有一个包含服务回购中默认值的值文件。其中一些值是 JSON,目前存储为 JSON 字符串:
apiVersion: v1
data:
Configuration.json: {{ toYaml .Values.config | indent 4 }}
kind: ConfigMap
metadata:
name: service-cm
config: |-
{
"val1": "key1",
"val2": "key2"
}
我们还有一个部署仓库,其中定义了不同的系统。在这里,我们也用 json 字符串覆盖了值。
由于这些 json 字符串的可用性不太好,我们想将它们移动到 json 文件中。
我们使用 AKS 和 Azure Pipelines 来部署服务。 我们创建图表:
helm chart save Chart $(acr.name).azurecr.io/$(acr.repo.name):$(BUILD_VERSION)
并推送:
helm chart push $(acr.name).azurecr.io/$(acr.repo.name):$(BUILD_VERSION)
并在另一个作业中拉取和导出后升级:
helm upgrade --install --set image-name --wait -f demo-values.yaml service service-chart
我们已经完成的是使用 --set-file:
在升级命令中设置 json 配置upgrade --install --set image-name --wait -f demo-values.yaml --set-file config=demo-config.json service service-chart
虽然仅适用于不同系统的值,但不适用于默认值。但我们也想外包这些,也不想没有它们。 因此此时第一个问题,是否有办法为每个文件注入默认值,以便它们位于保存的图表中?
我们知道您可以使用以下语法读取模板中的文件:
Configuration.json: |-
{{ .Files.Get "default-config.json" | indent 4 }}
但我们不能推翻它。另一个想法是从值中注入路径:
Configuration.json: |-
{{ .Files.Get (printf "%s" .Values.config.filename) | indent 4 }}
但是路径好像是相对于图表文件夹的。所以没有部署 repo 的路径。
我们现在有以下带有条件模板的解决方案:
data:
{{ if .Values.config.overwrite }}
Configuration.json: {{ toYaml .Values.config.value | indent 4 }}
{{ else }}
Configuration.json: |-
{{ .Files.Get "default-config" | indent 4 }}
{{ end }}
在部署回购中,值文件如下所示:
config:
overwrite: true
value: will_be_replaced_by_file_content
并且demo-config.json
是通过管道中的升级命令设置的。
这可行,但对我们来说似乎有点繁琐。那么问题来了:你知道更好的方法吗?
在您的第一个设置中,.Values.config
是一个字符串。 key: |-
语法创建了一个 YAML block scalar,其中包含一个恰好是 JSON 的缩进文本块。 helm install --set-file
也将一个值设置为一个字符串,.Files.Get
returns 一个字符串。
所有这些都是字符串,这意味着您可以简化围绕它们的逻辑。例如,考虑 Helm default
模板函数:如果它的参数是一个空字符串,它在逻辑上是假的,所以 default
回退到它的默认值。
在您的最终布局中,您希望将默认配置保留在单独的文件中,但只有在未提供覆盖配置时才使用它。因此,您可以采用以下方法:
在
values.yaml
中,config
为空串。 (null
或者根本不定义它也适用于此设置。)# config is a string containing JSON-format application configuration. config: ''
因为你已经有了它,
.Files.Get "default-config.json"
可以作为后备值。使用
default
函数检查.Values.config
是否为 non-empty,如果不是,则返回默认值。使用
helm install --set-file config=demo-config.json
在部署时提供备用配置。
更新后的 ConfigMap 可能如下所示:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "myapp.fullname" . }}
data:
Configuration.json:
{{ .Values.config | default (.Files.Get "default-config.json") | indent 4 }}
(因为任何形式的 .Values.config
都是字符串,所以它不是一个复杂的结构,您不需要对其调用 toYaml
。)