【问题标题】:Dynamically accessing values depending on variable values in a Helm chart根据 Helm 图表中的变量值动态访问值
【发布时间】:2018-12-04 01:05:35
【问题描述】:

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

{{- $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 中有这样一个部分:

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 的默认部分)。 “索引”功能似乎让我可以做我想做的事,所以在我的模板中,我尝试了这个(为了便于阅读而换行):

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

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

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

【问题讨论】:

  • 难道你不能有一个通用图表代表application 并使用默认值并将其用作父图表吗?因此,然后定义特定于您想要使用父/通用图表作为子图表的每个应用程序的图表。然后这些图表中的每一个都可以覆盖来自父/通用图表的值。然后,您可以创建一个包含所有特定图表作为子图表的进一步伞形图表,以便可以将它们安装在单个图表中。另见stackoverflow.com/questions/52724344/…
  • 嗨瑞恩,谢谢你的回复。这可能是另一种选择,但应用程序特定的设置是用户可调整的(因此 - 至少在我对 helm 的理解仍然非常有限的情况下 - 意味着它们应该转到 values.yaml)。不同应用程序的大多数实际默认值(K8s 特有的东西除外)已经在容器本身中设置,并且可以通过 env vars 覆盖。另一方面,对于不同但不意味着用户可调整的事物(想到活跃度和就绪性探测器 - 我还没有这些),子图表方法适合。
  • 作为用户,我可以在我正在安装的图表的任何子图表的任何 values.yml 文件中设置任何变量 -github.com/helm/helm/issues/2927#issuecomment-328902868 我只需输入子图表的名称当我像在github.com/helm/helm/blob/master/docs/chart_template_guide/… 中一样引用它时,在变量前面我可以在命令行以及伞形图表中以用户身份执行此操作

标签: kubernetes-helm


【解决方案1】:

我对我的图表做了类似的事情,但基于环境而不是应用程序。

在我的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 }}

那么您只需将--set app=applicationA 添加到您的 Helm 命令中。

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

您可能会使用pluck 与您的原始值文件的组合,如下所示:

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

我还没有尝试过,所以 YMMV。 (您肯定必须更改N 以匹配插入块的缩进级别。)只是一个想法。看起来脆弱配置的潜力很大。

【讨论】:

    猜你喜欢
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    相关资源
    最近更新 更多