使用单个 HELM 模板的多个资源

raz*_*raz 2 kubernetes kubernetes-helm amazon-eks

默认情况下,我们一直为每个应用程序(公共)使用单个入口,但根据最近的要求,我们还需要为某些应用程序公开(私有)端点。这意味着我们有一个看起来像这样的模板:

模板/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 }}
Run Code Online (Sandbox Code Playgroud)

模板/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 -}}
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

所以,为了适应新的设置。我在 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"
Run Code Online (Sandbox Code Playgroud)

并复制了两个模板,即模板/ingress-private.yaml 和模板/certs-private.yaml,并且工作正常,但我的问题是 - 有没有办法为每个入口和证书使用单个模板并创建条件资源?

正如我上面提到的,有些应用程序需要内部入口,有些则不需要。我想做的是;将公共入口/证书设为默认,将私有设为可选。我一直在使用{{- if .Values.ingress.enabled -}}选项来验证是否需要 ingress 但在 2 个不同的文件中。

另外,在 values.yaml 文件中,如果需要多个资源,有没有办法使用列表而不是 2 个不同的块?

Che*_*tan 7

感谢大卫让我们开始。但这对我不起作用。我使用以下方法在单个 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 }}
Run Code Online (Sandbox Code Playgroud)

helm 文档展示了如何定义和使用范围: https: //helm.sh/docs/chart_template_guide/variables/


Dav*_*aze 6

有几种方法可以解决这个问题。

您现在拥有的方式,每个资源一个文件,但有一些逻辑重复,是一种相当常见的模式。正在创建哪些资源非常清楚,而且涉及的逻辑较少。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
...
Run Code Online (Sandbox Code Playgroud)

这里唯一重要的是模板的输出是一个有效的多文档 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"
Run Code Online (Sandbox Code Playgroud)

您可以使用 Go 模板range构造来循环所有这些。请注意,这借用了.特殊变量,因此如果您确实引用了任意其他内容,则.Values需要保存它的当前值。

{{- $top := . -}}
{{- $ingress := range .Values.ingresses -}}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ $ingress.name }}
  annotations: {{- $ingress.annotations.toYaml | nindent 4 }}
...
{{ end }}
Run Code Online (Sandbox Code Playgroud)