如何从具有正确上下文的子图中调用 helm 'helper' 模板?
How can you call a helm 'helper' template from a subchart with the correct context?
Helm 图表在 _helpers.tpl
中定义帮助程序模板,用于为服务创建规范化名称。服务 (DNS) 名称模板的标准格式为:
{{- define "postgresql.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
如果使用postgresql作为子图,你应该如何使用基于DNS的服务发现来引用它?一个常见的模式似乎是将子图表助手复制到父图表中。
{{- define "keycloak.postgresql.fullname" -}}
{{- $name := default "postgresql" .Values.postgresql.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
出于显而易见的原因,这完全是疯狂!!!
肯定有更好的方法来使用子图助手吗?如果您可以创建一个上下文对象,那么就可以调用它,例如:
value: {{ template "postgresql.fullname" ({Chart: {Name: 'not-used'}, Release: {Name: .Release.Name}, Values: { nameOverride: .Values.postgresql.nameOverride}}) }}
遗憾的是,我不知道如何实际动态地创建这样的上下文。如果辅助函数更改为引用新属性,这仍然会中断,但以一种显而易见的方式。
或者,从子图表中获取服务名称的不同方法?
嗯,这在某种程度上并不是很简单。
我认为这里发生的是 Helm 遵循的实践以及模板的可能性。
一种做法是“图表开箱即用”- 因此无论是子图表还是独立图表,它都应该可以正常工作。这会对您需要配置哪些内容以正确命名您部署和引用的资源产生一些影响。
我有一个非常相似的问题。参见 How to reference a value defined in a template in a sub-chart in helm for kubernetes?。
我的“解决方案”是在我自己的 _helpers.tpl:
中重新定义 postgres.fullname
{{- define "postgresql.fullname" -}}
{{- $name := printf "%s-%s" .Values.global.appId .Values.global.fkNameId -}}
{{- printf "%s-%s" $name "postgresql" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
由于每个 tiller 安装的版本名称必须是唯一的 - 我们在集群中有一个 tiller - 我有点不使用版本名称作为参考和自己的命名约定的一部分。
模板中的定义是全局的。因此,如果您熟悉默认 PostgreSQL 图表的发布名称前缀,就可以使用它们:
{{- define "postgresql.fullname" -}}
{{- $name := printf "%s-%s" .Values.global.appId .Values.global.fkNameId -}}
{{- printf "%s-%s" $name "postgresql" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
我无法想出不会重复服务名称的版本名称(“webshop-service-webshop-service”),所以我倾向于不使用它们,因为我需要每个命名空间而不是每个 tiller 实例。
一旦我从子图表中定义了名称,我就会在我的服务中引用它。我同意它,因为我知道我引用的图表以及它用于命名的内容。但这是真的:我应该升级子图表我需要检查名称是否仍然相同。但是因为那个“全名”很常见,我觉得我很好。有些测试无论如何都会失败。
但不是一个漂亮的“解决方案”。
不是答案 - 对我来说已经足够了:)
据我了解,命名模板可全局用于所有父图表和子图表。然而,对于价值观来说,这不是真的。子图表无法访问父值,但父图表可以访问子图表值。
引自The Chart Template Developer's Guide, Declaring and using templates with define and template...
"There is one really important detail to keep in mind when naming templates: template names are global. If you declare two templates with the same name, whichever one is loaded last will be the one used. Because templates in subcharts are compiled together with top-level templates, you should be careful to name your templates with chart-specific names."
参考资料
我写了一个 issue helm/helm#4535
总结了现状并提出了对 Helm 的改进以解决这个问题。
对于寻找临时解决方案的任何人,我编写了(有关详细信息,请参阅 my follow-up comment)一个元模板,它调用 "ersatz" 子图范围内的任何给定模板。它通过合成一个点对象来工作。它并不完美(并非所有字段都被合成),但它会做到:
{{- define "call-nested" }}
{{- $dot := index . 0 }}
{{- $subchart := index . 1 }}
{{- $template := index . 2 }}
{{- include $template (dict "Chart" (dict "Name" $subchart) "Values" (index $dot.Values $subchart) "Release" $dot.Release "Capabilities" $dot.Capabilities) }}
{{- end }}
用法(调用 redis
子图的 redis.fullname
模板):
{{ include "call-nested" (list . "redis" "redis.fullname") }}
从 https://github.com/helm/helm/pull/9957 开始(2021 年 8 月 31 日合并并在 Helm 3.7 中发布),您可以使用 .Subcharts.[chartName]
作为第二个参数在该子图的上下文中调用子图的命名模板。
例如,假设您的 keycloak 子图将其服务命名为 {{ template "keycloak.fullname" . }}-http
您可以从父图表中引用该服务的名称,如下所示:
{{ template "keycloak.fullname" .Subcharts.keycloak }}-http
要访问图表中的值,请执行以下操作:
{{ template "keycloak.fullname" . }}
从子图表访问值
{{ template "keycloak.fullname" .Subcharts.keycloak }}
请注意,这些值可以在 helper.tpl
Helm 图表在 _helpers.tpl
中定义帮助程序模板,用于为服务创建规范化名称。服务 (DNS) 名称模板的标准格式为:
{{- define "postgresql.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
如果使用postgresql作为子图,你应该如何使用基于DNS的服务发现来引用它?一个常见的模式似乎是将子图表助手复制到父图表中。
{{- define "keycloak.postgresql.fullname" -}}
{{- $name := default "postgresql" .Values.postgresql.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
出于显而易见的原因,这完全是疯狂!!!
肯定有更好的方法来使用子图助手吗?如果您可以创建一个上下文对象,那么就可以调用它,例如:
value: {{ template "postgresql.fullname" ({Chart: {Name: 'not-used'}, Release: {Name: .Release.Name}, Values: { nameOverride: .Values.postgresql.nameOverride}}) }}
遗憾的是,我不知道如何实际动态地创建这样的上下文。如果辅助函数更改为引用新属性,这仍然会中断,但以一种显而易见的方式。
或者,从子图表中获取服务名称的不同方法?
嗯,这在某种程度上并不是很简单。
我认为这里发生的是 Helm 遵循的实践以及模板的可能性。
一种做法是“图表开箱即用”- 因此无论是子图表还是独立图表,它都应该可以正常工作。这会对您需要配置哪些内容以正确命名您部署和引用的资源产生一些影响。
我有一个非常相似的问题。参见 How to reference a value defined in a template in a sub-chart in helm for kubernetes?。
我的“解决方案”是在我自己的 _helpers.tpl:
中重新定义 postgres.fullname{{- define "postgresql.fullname" -}}
{{- $name := printf "%s-%s" .Values.global.appId .Values.global.fkNameId -}}
{{- printf "%s-%s" $name "postgresql" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
由于每个 tiller 安装的版本名称必须是唯一的 - 我们在集群中有一个 tiller - 我有点不使用版本名称作为参考和自己的命名约定的一部分。
模板中的定义是全局的。因此,如果您熟悉默认 PostgreSQL 图表的发布名称前缀,就可以使用它们:
{{- define "postgresql.fullname" -}}
{{- $name := printf "%s-%s" .Values.global.appId .Values.global.fkNameId -}}
{{- printf "%s-%s" $name "postgresql" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
我无法想出不会重复服务名称的版本名称(“webshop-service-webshop-service”),所以我倾向于不使用它们,因为我需要每个命名空间而不是每个 tiller 实例。
一旦我从子图表中定义了名称,我就会在我的服务中引用它。我同意它,因为我知道我引用的图表以及它用于命名的内容。但这是真的:我应该升级子图表我需要检查名称是否仍然相同。但是因为那个“全名”很常见,我觉得我很好。有些测试无论如何都会失败。
但不是一个漂亮的“解决方案”。
不是答案 - 对我来说已经足够了:)
据我了解,命名模板可全局用于所有父图表和子图表。然而,对于价值观来说,这不是真的。子图表无法访问父值,但父图表可以访问子图表值。
引自The Chart Template Developer's Guide, Declaring and using templates with define and template...
"There is one really important detail to keep in mind when naming templates: template names are global. If you declare two templates with the same name, whichever one is loaded last will be the one used. Because templates in subcharts are compiled together with top-level templates, you should be careful to name your templates with chart-specific names."
参考资料
我写了一个 issue helm/helm#4535
总结了现状并提出了对 Helm 的改进以解决这个问题。
对于寻找临时解决方案的任何人,我编写了(有关详细信息,请参阅 my follow-up comment)一个元模板,它调用 "ersatz" 子图范围内的任何给定模板。它通过合成一个点对象来工作。它并不完美(并非所有字段都被合成),但它会做到:
{{- define "call-nested" }}
{{- $dot := index . 0 }}
{{- $subchart := index . 1 }}
{{- $template := index . 2 }}
{{- include $template (dict "Chart" (dict "Name" $subchart) "Values" (index $dot.Values $subchart) "Release" $dot.Release "Capabilities" $dot.Capabilities) }}
{{- end }}
用法(调用 redis
子图的 redis.fullname
模板):
{{ include "call-nested" (list . "redis" "redis.fullname") }}
从 https://github.com/helm/helm/pull/9957 开始(2021 年 8 月 31 日合并并在 Helm 3.7 中发布),您可以使用 .Subcharts.[chartName]
作为第二个参数在该子图的上下文中调用子图的命名模板。
例如,假设您的 keycloak 子图将其服务命名为 {{ template "keycloak.fullname" . }}-http
您可以从父图表中引用该服务的名称,如下所示:
{{ template "keycloak.fullname" .Subcharts.keycloak }}-http
要访问图表中的值,请执行以下操作:
{{ template "keycloak.fullname" . }}
从子图表访问值
{{ template "keycloak.fullname" .Subcharts.keycloak }}
请注意,这些值可以在 helper.tpl