根据Helm图表中的变量值动态访问值

时间:2018-10-10 14:13:00

标签: kubernetes-helm

我目前正在为多容器应用程序编写Helm图表。我们有一堆微服务容器(我们称它们为“应用程序”),它们在通过K8进行处理的方式上非常相似,并且可以(因此也应该)由相同的Helm模板处理,以避免重复。另一方面,有意义的是能够针对不同的应用程序(例如资源请求)单独配置某些设置。我目前正在做这样的事情:

token-based

我现在想做的是能够设置一些特定于应用程序的值(以K8s resources.requests.memory或副本数为例),这些值可以在每个应用程序的values.yaml中单独设置,但落入如果未设置,则返回默认值。 想法是在values.yaml中有这样一个部分:

{{- $applications:= <obtain list of applications> }}
{{ range $app:= $applications }}
apiVersion: apps/v1
kind: StatefulSet
spec:
[...]
    spec:
      containers:
      - name: {{ $app }}
        image: {{ $.Values.image.registry }}mycompany/myproduct-{{ $app }}:{{ $.Values.image.version }}
[...]

这个想法是,我将“默认”部分中的值用于应用程序,除非在该部分中为各个应用程序指定了特定于应用程序的值。在我的示例中,对于应用程序A的内存请求有一个自定义值,对于应用程序B的CPU请求有一个自定义值,但是所有其他值都应来自默认部分。也可能有一些应用程序根本没有定义任何特定于应用程序的设置(在这种情况下,所有内容都来自values.yaml的默认部分)。 “索引”功能似乎允许我做我想做的事,因此在我的模板中,我尝试了此操作(为提高可读性而换行):

applications:
  default:
    replicas: 1
    resources:
      requests:
        memory: 512Mi
        cpu: 250m
  applicationA:
    resources:
      requests:
        memory: 7Gi
  applicationB:
    resources:
      requests:
        cpu: 500m
[...]

由于索引允许我使用循环变量“ $ app”的值来“解引用” values.yaml中的值,因此这实际上可行......,索引失败      错误调用索引:nil指针的索引 在那些我没有为其中一个设置指定特定于应用程序的值的情况下,因此取消引用失败。我需要的是在这种情况下不会失败的索引,而只是返回一个空值,以便默认值生效。不幸的是,我似乎找不到解决方法。

但是也许有一种完全不同的方法来处理此问题,所以任何想法和建议都值得赞赏。当然,作为备用,我可以在values.yaml中为每个应用程序显式设置每个值,但这感觉并不正确。

1 个答案:

答案 0 :(得分:3)

我对图表进行了类似的操作,但是基于环境而不是应用程序。

在我的values.yaml中:

env: dev

replicaCount:
  _default: 1
  staging: 2
  prod: 4

在我的模板中:

  replicas: {{ pluck .Values.env .Values.replicaCount | first | default .Values.replicaCount._default }}

pluck命令返回一个列表,first从该列表中选择第一项。如果什么也没有返回,它将退回到_default值。因此,当我运行helm template --set env=staging时,将获得为暂存环境设置的配置。

您的values.yaml文件如下所示:

replicas:
  _default: 1
resources:
  requests:
    memory:
      _default: 512Mi
      applicationA: 7Gi
    cpu:
      _default: 250m
      applicationB: 500m

您的模板将具有以下内容:

memory: {{ pluck .Values.app .Values.resources.requests.memory | first | default .Values.resources.requests.memory._default }}

然后,您只需要在Helm命令中添加--set app=applicationA

我认为这使values.yaml更具可读性,但是模板有点难看。

您可能将pluck与原始值文件结合使用,例如:

{{ pluck .Values.app .Values.applications | default .Values.applications.default | toYaml | indent N }}

我还没有尝试过,所以YMMV。 (您肯定必须更改N来匹配插入块的缩进级别。)只是一个想法。似乎很可能会导致配置脆弱。