如何在 Helm Chart 中兼容不同的 Kubernetes 版本?

2025-05-27 0 88

如何在 Helm Chart 中兼容不同的 Kubernetes 版本?

随着 Kubernetes 的版本不断迭代发布,很多 Helm Chart 包压根跟不上更新的进度,导致在使用较新版本的 Kubernetes 的时候很多 Helm Chart 包不兼容,所以我们在开发 Helm Chart 包的时候有必要考虑到对不同版本的 Kubernetes 进行兼容。

如何在 Helm Chart 中兼容不同的 Kubernetes 版本?

要实现对不同版本的兼容核心就是利用 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 资源对象为例进行说明。

Kubernetes 在 1.19 版本为 Ingress 资源引入了一个新的 API:networking.k8s.io/v1,这与之前的 networking.k8s.io/v1beta1 beta 版本使用方式基本一致,但是和前面的 extensions/v1beta1 这个版本在使用上有很大的不同,资源对象的属性上有一定的区别,所以要兼容不同的版本,我们就需要对模板中的 Ingress 对象做兼容处理。

新版本的资源对象格式如下所示:

  1. apiVersion:networking.k8s.io/v1
  2. kind:Ingress
  3. metadata:
  4. name:minimal-ingress
  5. annotations:
  6. nginx.ingress.kubernetes.io/rewrite-target:/
  7. spec:
  8. rules:
  9. -http:
  10. paths:
  11. -path:/testpath
  12. pathType:Prefix
  13. backend:
  14. service:
  15. name:test
  16. port:
  17. number:80

而旧版本的资源对象格式如下:

  1. apiVersion:extensions/v1beta1
  2. kind:Ingress
  3. metadata:
  4. name:minimal-ingress
  5. annotations:
  6. nginx.ingress.kubernetes.io/rewrite-target:/
  7. spec:
  8. rules:
  9. -http:
  10. paths:
  11. -path:/testpath
  12. backend:
  13. serviceName:test
  14. servicePort:80

具体使用哪种格式的资源对象需要依赖我们的集群版本,首先我们在 Chart 包的 _helpers.tpl 文件中添加几个用于判断集群版本或 API 的命名模板:

  1. {{/*AllowKubeVersiontobeoverridden.*/}}
  2. {{-define\”ydzs.kubeVersion\”-}}
  3. {{-default.Capabilities.KubeVersion.Version.Values.kubeVersionOverride-}}
  4. {{-end
  5. {{/*GetIngressAPIVersion*/}}
  6. {{-define\”ydzs.ingress.apiVersion\”-}}
  7. {{-ifand(.Capabilities.APIVersions.Has\”networking.k8s.io/v1\”)(semverCompare\”>=1.19-0\”(include\”ydzs.kubeVersion\”.))-}}
  8. {{-print\”networking.k8s.io/v1\”-}}
  9. {{-elseif.Capabilities.APIVersions.Has\”networking.k8s.io/v1beta1\”-}}
  10. {{-print\”networking.k8s.io/v1beta1\”-}}
  11. {{-else-}}
  12. {{-print\”extensions/v1beta1\”-}}
  13. {{-end-}}
  14. {{-end-}}
  15. {{/*CheckIngressstability*/}}
  16. {{-define\”ydzs.ingress.isStable\”-}}
  17. {{-eq(include\”ydzs.ingress.apiVersion\”.)\”networking.k8s.io/v1\”-}}
  18. {{-end-}}
  19. {{/*CheckIngresssupportspathType*/}}
  20. {{/*pathTypewasaddedtonetworking.k8s.io/v1beta1inKubernetes1.18*/}}
  21. {{-define\”ydzs.ingress.supportsPathType\”-}}
  22. {{-or(eq(include\”ydzs.ingress.isStable\”.)\”true\”)(and(eq(include\”ydzs.ingress.apiVersion\”.)\”networking.k8s.io/v1beta1\”)(semverCompare\”>=1.18-0\”(include\”ydzs.kubeVersion\”.)))-}}
  23. {{-end-}}

上面我们通过 .Capabilities.APIVersions.Has 来判断我们应该使用的 APIVersion,如果版本为 networking.k8s.io/v1,则定义为 isStable,此外还根据版本来判断是否需要支持 pathType 属性,然后在 Ingress 对象模板中就可以使用上面定义的命名模板来决定应该使用哪些属性,如下 ingress.yaml 文件所示:

  1. {{-$apiIsStable:=eq(include\”ydzs.ingress.isStable\”.)\”true\”-}}
  2. {{-$ingressSupportsPathType:=eq(include\”ydzs.ingress.supportsPathType\”.)\”true\”-}}
  3. {{-$ingressClass:=index.Values\”ingress-nginx\”\”controller\”\”ingressClass\”}}
  4. apiVersion:{{include\”ydzs.ingress.apiVersion\”.}}
  5. kind:Ingress
  6. metadata:
  7. name:portal-ingress
  8. annotations:
  9. {{-if$ingressClass}}
  10. kubernetes.io/ingress.class:{{$ingressClass}}
  11. {{-end}}
  12. nginx.ingress.kubernetes.io/proxy-connect-timeout:\”120\”
  13. nginx.ingress.kubernetes.io/proxy-read-timeout:\”3600\”
  14. nginx.ingress.kubernetes.io/proxy-send-timeout:\”3600\”
  15. nginx.ingress.kubernetes.io/ssl-redirect:\”false\”
  16. labels:
  17. {{-include\”ydzs.labels\”.|nindent4}}
  18. spec:
  19. rules:
  20. {{-ifeq.Values.endpoint.type\”FQDN\”}}
  21. -host:{{required\”.Values.endpoint.FQDNisrequiredforFQDN\”.Values.endpoint.FQDN}}
  22. http:
  23. {{-else}}
  24. -http:
  25. {{-end}}
  26. paths:
  27. -path:/
  28. {{-if$ingressSupportsPathType}}
  29. pathType:Prefix
  30. {{-end}}
  31. backend:
  32. {{-if$apiIsStable}}
  33. service:
  34. name:portal
  35. port:
  36. number:80
  37. {{-else}}
  38. serviceName:portal
  39. servicePort:80
  40. {{-end}}

在 Ingress 模板中使用命名模板中的变量来判断应该使用哪些属性,这样我们定义的这个 Chart 模板就可以兼容 Kubernetes 的不同版本了,如果还有其他版本之间的差异,我们也可以分别判断进行定义即可,对于其他的资源对象,比如 Deployment 也可以用同样的方式进行兼容。

原文链接:https://mp.weixin.qq.com/s/P0GcWIj1fhcrxwVhdR6Y4w

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 行业资讯 如何在 Helm Chart 中兼容不同的 Kubernetes 版本? https://www.kuaiidc.com/62957.html

相关文章

发表评论
暂无评论