本文介绍了使用单个 HELM 模板的多个资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We had been using single ingress per application(public) by default but with the recent requirement we need to expose (private) endpoint as well for some of the apps. That means we had a single template that looks like this:

模板/ingress.yaml

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 }}

模板/cert.yaml

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 如下所示:

And the values.yaml looks like this:

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 文件中添加了以下块.

So, to accomodate the new setup. I have added the below block on values.yaml file.

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"

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

And duplicated both templates i.e templates/ingress-private.yaml and templates/certs-private.yaml, and is working fine but my question here is - is there a way using a single template for each ingress and certs and create conditional resource?

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

As I mentioned above, some apps need internal ingress and some don't. What I want to do is; make public ingress/certs as default and private as optional. i have been using {{- if .Values.ingress.enabled -}} option to validate if ingress is required but in 2 different files.

此外,在 values.yaml 文件中,如果需要多个资源,是否可以使用列表而不是 2 个不同的块?

Also, in values.yaml file, rather than having 2 different block is there a way to use the list if multiple resources are required?

推荐答案

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

There are a couple of ways to approach this problem.

您现在拥有的方式,每个资源一个文件,但有一些逻辑重复,是一种相当常见的模式.正在创建哪些资源非常清楚,而且涉及的逻辑较少.Go 模板语言有点专业化,因此这对于在您的项目中工作的其他人来说更容易上手.

The way you have it now, with one file per resource but some duplication of logic, is a reasonably common pattern. It's very clear exactly what resources are being created, and there's less logic involved. The Go templating language is a little bit specialized, so this can be more approachable to other people working on your project.

如果您确实想将事物组合在一起,有几种选择.正如@Matt 在他们的评论中指出的那样,您可以将多个 Kubernetes 资源放在同一个文件中,只要它们由 YAML --- 文档分隔符分隔即可.

If you do want to combine things together there are a couple of options. As @Matt notes in their comment, you can put multiple Kubernetes resources in the same file so long as they're separated by the YAML --- document separator.

{{/* ... 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 命令查看结果,而无需实际将其发送到集群.

The only thing that matters here is that the output of the template is a valid multi-document YAML file. You can use the helm template command to see what comes out without actually sending it to the cluster.

这种方法与 YAML 文件中的配置规则列表相得益彰

This approach pairs well with having a list of configuration rules in your YAML file

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 中的任意其他内容,则需要保存它的当前值.

You can use the Go template range construct to loop over all of these. Note that this borrows the . special variable, so if you do refer to arbitrary other things in .Values you need to save away the current value of it.

{{- $top := . -}}
{{- $ingress := range .Values.ingresses -}}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ $ingress.name }}
  annotations: {{- $ingress.annotations.toYaml | nindent 4 }}
...
{{ end }}

这篇关于使用单个 HELM 模板的多个资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 20:41