0
点赞
收藏
分享

微信扫一扫

Helm Chart 兼容 Ingress 两个ApiVersion版本

四月Ren间 2023-11-21 阅读 42

实际环境

在工作中,有多个k8s集群需要同时管理,随着业务的扩充,先运行的K8s的版本和新运行的K8s版本就有出现差异,有些资源清单的apiVersion、格式、写法就会出现不兼容的情况。

Ingress 在 Kubernetes 中的 API 版本变更是从 Kubernetes 1.19 版本开始的。在 Kubernetes 1.19 版本之前,Ingress 使用的是扩展 API 组(extensions/v1beta1)。从 Kubernetes 1.19 版本开始,Ingress 被升级为稳定版本,并使用 networking.k8s.io/v1 API 组。

因此,如果你的 Kubernetes 版本是 1.19 或更高,应该使用 networking.k8s.io/v1 作为 Ingress 的 API 版本。如果你的 Kubernetes 版本低于 1.19,则应该使用 extensions/v1beta1。



要实现对不同版本的兼容核心就是利用 Helm Chart 模板提供的内置对象 Capabilities,该对象提供了关于 Kubernetes 集群支持功能的信息,包括如下特性:

  • Capabilities.APIVersions 获取集群版本集合
  • Capabilities.APIVersions.Has $version 判断集群中的某个版本 (e.g., batch/v1) 或是资源 (e.g., apps/v1/Deployment) 是否可用
  • Capabilities.KubeVersion 和 Capabilities.KubeVersion.Version 可以获取 Kubernetes 版本号
  • Capabilities.KubeVersion.Major 获取 Kubernetes 的主版本
  • Capabilities.KubeVersion.Minor 获取 Kubernetes 的次版本
  • Capabilities.HelmVersion 包含 Helm 版本详细信息的对象,和 helm version 的输出一致
  • Capabilities.HelmVersion.Version 是当前 Helm 版本的语义格式
  • Capabilities.HelmVersion.GitCommit Helm 的 git sha1 值
  • Capabilities.HelmVersion.GitTreeState 是 Helm git 树的状态
  • Capabilities.HelmVersion.GoVersion 使用的 Go 编译器版本

利用上面的几个对象我们可以判断资源对象需要使用的 API 版本或者属性,下面我们以 Ingress 资源对象为例进行说明。




修改资源清单文件

最简单的办法就是通过 helm create my-chart 的方式创建一个chart模板,ingress 自带兼容的配置。

$ helm version
version.BuildInfo{Version:"v3.12.3", GitCommit:"3a31588ad33fe3b89af5a2a54ee1d25bfe6eaa5e", GitTreeState:"clean", GoVersion:"go1.20.7"}


查看ingress

{{- if .Values.ingress.enabled -}}
{{- $fullName := include "wsj.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
  {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
  {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
  {{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
  name: {{ $fullName }}
  labels:
    {{- include "wsj.labels" . | nindent 4 }}
  {{- with .Values.ingress.annotations }}
  annotations:
    {{- toYaml . | nindent 4 }}
  {{- end }}
spec:
  {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
  ingressClassName: {{ .Values.ingress.className }}
  {{- end }}
  {{- 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: {{ .path }}
            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
            pathType: {{ .pathType }}
            {{- end }}
            backend:
              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
              service:
                name: {{ $fullName }}
                port:
                  number: {{ $svcPort }}
              {{- else }}
              serviceName: {{ $fullName }}
              servicePort: {{ $svcPort }}
              {{- end }}
          {{- end }}
    {{- end }}
{{- end }}



配置说明

配置

说明

{{- if .Values.ingress.enabled -}}

ingress的开关。

values.ingress.enabled.

判断配置是true,还是false。

{{- $fullName := include "wsj.fullname" . -}}

{{- $svcPort := .Values.service.port -}}

别名写法

{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}

{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}

{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}

{{- end }}

{{- end }}

当 Kubernetes 版本小于 1.18 且 Helm Chart 中定义了 Ingress 的 className 时,为 Ingress 配置添加 kubernetes.io/ingress.class 的 annotation,如果该 annotation 不存在的话。这可能是为了向前兼容处理,因为在 Kubernetes 1.18 版本之后,Ingress 类的 class 字段被引入,而之前的版本可能不支持这个字段。

{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}

apiVersion: networking.k8s.io/v1

{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}

apiVersion: networking.k8s.io/v1beta1

{{- else -}}

apiVersion: extensions/v1beta1

{{- end }}

if 判断,根据不同版本,使用不同的 apiVersion

metadata:

  labels:

    {{- include "wsj.labels" . | nindent 4 }}

这里的 wsj.labels 是在 _helpers.tpl 文件中定义的。

{{/*
Common labels
*/}}
{{- define "wsj.labels" -}}
helm.sh/chart: {{ include "wsj.chart" . }}
{{ include "wsj.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

  rules:
    {{- range .Values.ingress.hosts }}
    - host: {{ .host | quote }}
      http:
        paths:
          {{- range .paths }}
          - path: {{ .path }}
            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
            pathType: {{ .pathType }}
            {{- end }}
            backend:
              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
              service:
                name: {{ $fullName }}
                port:
                  number: {{ $svcPort }}
              {{- else }}
              serviceName: {{ $fullName }}
              servicePort: {{ $svcPort }}
              {{- end }}

这里的

path: {{ .path }} 

pathType: {{ .pathType }}

和原来的写法不同了。

需要对照修改 values 文件.

ingress:
  enabled: false
  className: ""
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

servicePort: {{ $svcPort }}

# 对应上门的别名写法
{{- $svcPort := .Values.service.port -}}


这里的

{{ $svcPort }}

和原来的写法不同了。

需要对照修改 values 文件.

service:
  type: ClusterIP
  port: 80


修改建议

根据上面的ingress文件,结合自己的原文件,修改即可。


举报

相关推荐

0 条评论