实际环境
在工作中,有多个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 的 |
{{- 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 }} | 这里的
|
| 这里的
和原来的写法不同了。 需要对照修改 values 文件.
|
servicePort: {{ $svcPort }}
| 这里的
和原来的写法不同了。 需要对照修改 values 文件.
|
修改建议
根据上面的ingress文件,结合自己的原文件,修改即可。