根据Helm图表中的变量值动态访问值 [英] Dynamically accessing values depending on variable values in a Helm chart

查看:154
本文介绍了根据Helm图表中的变量值动态访问值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently writing a Helm chart for a multi-container application. We have a bunch of microservice containers (we call them "applications") that are very similar in the way they can be handled through K8s, and can (and thus should) be handled by the same Helm template to avoid duplicating things. On the other hand, it makes sense to be able to configure certain settings individually for the different applications (e.g., resource requests). I am currently doing something like this:

{{- $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 }}
[...]

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

What I would like to do now is be able to set some application specific values (take K8s resources.requests.memory or number of replicas as an example) that can be set individually inside values.yaml for each application, but falls back to a default if they are not set. The idea was to have such a section in values.yaml:

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

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

The idea is that I use the value from the "default" section for applications, unless there is an application-specific value specified in the section for the respective application. In my example, I have a custom value for the memory request of applicationA and one for the CPU request of application B, but all other values should come from the default section. There can also be applications where no application-specific settings are defined at all (in which case everything is coming from the default section of values.yaml). The "index" function seemed to allow me to do what I want, so in my template, I tried this (line break for readability):

resources:
  requests:
    memory: {{ default \
(index $.Values "applications" "default" "resources" "requests" "memory") \
(index $.Values "applications" $app "resources" "requests" "memory") }}  

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

Since the index allows me to use the value of my loop variable "$app" to "dereference" a value from values.yaml, this actually works... alas, index fails with error calling index: index of nil pointer in those cases where I do not specify an appliation-specific value for one of the settings, and thus the dereferencing fails. What I would need is index to NOT fail in that situation, but just return an empty value, so that the default would kick in. Unfortunately, I cannot seem to find a way to do this.

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

But maybe there is a complete different way of handling this problem, so any ideas and suggestions are appreciated. Of course as a fallback I could just explicitly set every value for each application in values.yaml, but that just does not feel right.

推荐答案

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

I do something similar with my charts, but based on environment instead of application.

在我的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时,将获得为临时环境设置的配置.

The pluck command returns a list, and first selects the first item from that list. In the event that nothing is returned, it falls back to the _default value. So when I run helm template --set env=staging, I get the configuration I set for my staging environment.

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

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

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

And your template would have something like this:

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

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

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

I think this makes the values.yaml more-or-less readable, but the template gets a bit ugly.

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

You could potentially use a combination of pluck with your original values file for something like this:

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

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

I haven't tried that, so YMMV. (You'll definitely have to change N to match the level of indentation where you insert the block.) Just an idea. Seems like high potential for brittle config.

这篇关于根据Helm图表中的变量值动态访问值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆