使用单个 HELM 模板的多个资源
Multiple resources using single HELM template
我们一直默认为每个应用程序使用单个入口 (public),但根据最近的要求,我们还需要为某些应用程序公开(私有)端点。这意味着我们有一个看起来像这样的模板:
templates/ingress.yaml
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "app.fullname" . -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{ include "app.labels" . | indent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ . }}
backend:
serviceName: {{ $fullName }}
servicePort: http
{{- end }}
{{- end }}
{{- end }}
templates/cert.yaml
{{- if .Values.ingress.tls -}}
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: {{ .Values.ingress.name }}
namespace: {{ .Values.ingress.namespace }}
spec:
{{- range .Values.ingress.tls }}
secretName: {{ .secretName }}
duration: 24h
renewBefore: 12h
issuerRef:
name: {{ .issuerRef.name }}
kind: {{ .issuerRef.kind }}
dnsNames:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
{{- end -}}
{{- end -}}
values.yaml 看起来像这样:
ingress:
enabled: true
name: apps-ingress
namespace: app1-namespace
annotations:
kubernetes.io/ingress.class: hybrid-external
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
hosts:
- host: apps.test.cluster
paths:
- /
tls:
- secretName: app1-tls
issuerRef:
name: vault-issuer
kind: ClusterIssuer
hosts:
- "apps.test.cluster"
所以,为了适应新的设置。我在 values.yaml 文件中添加了以下块。
ingress-private:
enabled: true
name: apps-ingress-private
namespace: app1-namespace
annotations:
kubernetes.io/ingress.class: hybrid-internal
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
hosts:
- host: apps.internal.test.cluster
paths:
- /
tls:
- secretName: app1-tls
issuerRef:
name: vault-issuer
kind: ClusterIssuer
hosts:
- "apps.internal.test.cluster"
并复制了两个模板,即 templates/ingress-private.yaml 和 templates/certs-private.yaml,并且工作正常但我的问题是 - 有没有办法使用每个入口和证书的单个模板并创建条件资源?
正如我上面提到的,有些应用程序需要内部入口,有些则不需要。我想做的是;将 public ingress/certs 设置为默认值,并将私有设置为可选。我一直在使用 {{- if .Values.ingress.enabled -}}
选项来验证是否需要进入,但在 2 个不同的文件中。
此外,在 values.yaml 文件中,如果需要多个资源,有没有办法使用列表,而不是有 2 个不同的块?
有几种方法可以解决这个问题。
您现在的方式,每个资源一个文件,但有一些逻辑重复,是一种相当常见的模式。非常清楚到底创建了哪些资源,并且涉及的逻辑更少。 Go 模板语言有点专业化,因此对于从事您的项目的其他人来说,这可能更容易理解。
如果您确实想将这些东西组合在一起,有两种选择。正如@Matt 在他们的评论中指出的那样,您可以将多个 Kubernetes 资源放在同一个文件中,只要它们被 YAML ---
文档分隔符分隔即可。
{{/* ... arbitrary templating logic ... */}}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}
...
{{/* ... more logic ... */}}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}-private
...
这里唯一重要的是模板的输出是一个有效的多文档 YAML 文件。您可以使用 helm template
命令查看结果,而无需实际将其发送到集群。
这种方法与 YAML 文件中的配置规则列表相得益彰
ingresses:
- name: apps-ingress
annotations:
kubernetes.io/ingress.class: hybrid-external
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
- name: apps-ingress-private
annotations:
kubernetes.io/ingress.class: hybrid-internal
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
您可以使用 Go 模板 range
构造来遍历所有这些。请注意,这借用了 .
特殊变量,因此如果您在 .Values
中引用任意其他内容,则需要保存它的当前值。
{{- $top := . -}}
{{- range $ingress := .Values.ingresses -}}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $ingress.name }}
annotations: {{- $ingress.annotations.toYaml | nindent 4 }}
...
{{ end }}
感谢大卫让我们开始。但这对我不起作用。
我使用以下方法在单个 YAML 中生成多个资源。
{{- if .Values.nfs }}
{{- $top := . -}}
{{- range $index, $pvc := .Values.nfs }}
{{- if $pvc.persistentClaim }}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "{{ $top.Chart.Name }}-{{ $top.Release.Name }}-nfs-{{ $index }}"
namespace: {{ $top.Release.Namespace }}
....
resources:
requests:
storage: {{ $pvc.persistentClaim.storageRequest }}
{{- end }}
{{- end }}
{{- end }}
helm 文档展示了如何定义和使用范围:
https://helm.sh/docs/chart_template_guide/variables/
我们一直默认为每个应用程序使用单个入口 (public),但根据最近的要求,我们还需要为某些应用程序公开(私有)端点。这意味着我们有一个看起来像这样的模板:
templates/ingress.yaml
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "app.fullname" . -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{ include "app.labels" . | indent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ . }}
backend:
serviceName: {{ $fullName }}
servicePort: http
{{- end }}
{{- end }}
{{- end }}
templates/cert.yaml
{{- if .Values.ingress.tls -}}
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: {{ .Values.ingress.name }}
namespace: {{ .Values.ingress.namespace }}
spec:
{{- range .Values.ingress.tls }}
secretName: {{ .secretName }}
duration: 24h
renewBefore: 12h
issuerRef:
name: {{ .issuerRef.name }}
kind: {{ .issuerRef.kind }}
dnsNames:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
{{- end -}}
{{- end -}}
values.yaml 看起来像这样:
ingress:
enabled: true
name: apps-ingress
namespace: app1-namespace
annotations:
kubernetes.io/ingress.class: hybrid-external
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
hosts:
- host: apps.test.cluster
paths:
- /
tls:
- secretName: app1-tls
issuerRef:
name: vault-issuer
kind: ClusterIssuer
hosts:
- "apps.test.cluster"
所以,为了适应新的设置。我在 values.yaml 文件中添加了以下块。
ingress-private:
enabled: true
name: apps-ingress-private
namespace: app1-namespace
annotations:
kubernetes.io/ingress.class: hybrid-internal
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
hosts:
- host: apps.internal.test.cluster
paths:
- /
tls:
- secretName: app1-tls
issuerRef:
name: vault-issuer
kind: ClusterIssuer
hosts:
- "apps.internal.test.cluster"
并复制了两个模板,即 templates/ingress-private.yaml 和 templates/certs-private.yaml,并且工作正常但我的问题是 - 有没有办法使用每个入口和证书的单个模板并创建条件资源?
正如我上面提到的,有些应用程序需要内部入口,有些则不需要。我想做的是;将 public ingress/certs 设置为默认值,并将私有设置为可选。我一直在使用 {{- if .Values.ingress.enabled -}}
选项来验证是否需要进入,但在 2 个不同的文件中。
此外,在 values.yaml 文件中,如果需要多个资源,有没有办法使用列表,而不是有 2 个不同的块?
有几种方法可以解决这个问题。
您现在的方式,每个资源一个文件,但有一些逻辑重复,是一种相当常见的模式。非常清楚到底创建了哪些资源,并且涉及的逻辑更少。 Go 模板语言有点专业化,因此对于从事您的项目的其他人来说,这可能更容易理解。
如果您确实想将这些东西组合在一起,有两种选择。正如@Matt 在他们的评论中指出的那样,您可以将多个 Kubernetes 资源放在同一个文件中,只要它们被 YAML ---
文档分隔符分隔即可。
{{/* ... arbitrary templating logic ... */}}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}
...
{{/* ... more logic ... */}}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}-private
...
这里唯一重要的是模板的输出是一个有效的多文档 YAML 文件。您可以使用 helm template
命令查看结果,而无需实际将其发送到集群。
这种方法与 YAML 文件中的配置规则列表相得益彰
ingresses:
- name: apps-ingress
annotations:
kubernetes.io/ingress.class: hybrid-external
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
- name: apps-ingress-private
annotations:
kubernetes.io/ingress.class: hybrid-internal
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
您可以使用 Go 模板 range
构造来遍历所有这些。请注意,这借用了 .
特殊变量,因此如果您在 .Values
中引用任意其他内容,则需要保存它的当前值。
{{- $top := . -}}
{{- range $ingress := .Values.ingresses -}}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $ingress.name }}
annotations: {{- $ingress.annotations.toYaml | nindent 4 }}
...
{{ end }}
感谢大卫让我们开始。但这对我不起作用。 我使用以下方法在单个 YAML 中生成多个资源。
{{- if .Values.nfs }}
{{- $top := . -}}
{{- range $index, $pvc := .Values.nfs }}
{{- if $pvc.persistentClaim }}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "{{ $top.Chart.Name }}-{{ $top.Release.Name }}-nfs-{{ $index }}"
namespace: {{ $top.Release.Namespace }}
....
resources:
requests:
storage: {{ $pvc.persistentClaim.storageRequest }}
{{- end }}
{{- end }}
{{- end }}
helm 文档展示了如何定义和使用范围: https://helm.sh/docs/chart_template_guide/variables/