Helm开发/调试的最佳实践

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 本文的目标不限于对Helm官方文档的翻译或解释,更在于帮助开发者能够快速编写出一个标准且合理的helm chart。## Helm简介一句话描述:Helm是Kubernetes的包管理工具### Helm vs OperatorHelm 和 Operator都可以实现在k8s上安装应用。但二者有着不同的适用场景。Helm适用于:- 开发者群体- 门槛低:熟悉k8s即可-

本文的目标不限于对Helm官方文档的翻译或解释,更在于帮助开发者能够快速编写出一个标准且合理的helm chart。

Helm简介

一句话描述:Helm是Kubernetes的包管理工具

Helm vs Operator

Helm 和 Operator都可以实现在k8s上安装应用。但二者有着不同的适用场景。
Helm适用于:

  • 开发者群体
  • 门槛低:熟悉k8s即可
  • 重点在于实现应用的“安装-升级-删除”

Operator适用于:

  • 运维或SRE团队
  • 门槛高:对k8s精通,并能结合k8s编写自运维脚本,实现复杂且定制化的配置
  • 重点在于实现应用的自运维、高可靠。

Helm2 or Helm3

Helm2和Helm3,从开发者的视角有如下差别:

  • 增加了JSON格式的校验,可以输出更容易让人理解的错误报告
  • Release name从可选变成必选
  • Release name作用域从全局被限制到了namespace级别
  • Namespaces不再自动创建。如果chart中的namespace不存在,需要手动创建namespace
  • 将requirements.yaml,requirements.lock的内容合并到Chart.yaml,Chart.lock
  • Chart.yaml的apiVersion从v1到v2

其实对开发者来说,helm2 与helm3差异不大,就是helm3对于helm编写体验更加友好。

Heml的安装

Helm的github地址:https://github.com/helm/helm
可以选择安装最新的Helm3,也可以使用Helm2,通过tag找到2.x的最新版本:2.17. 在release中有编译好的mac二进制程序可以下载直接使用。

Helm 开发技巧

命名模板(named templates)

命名模板(named templates)也可以成为子模板,但他是有个名称的,可以结合include使用。
我们可以方便把一个模板文件中,公共或通用的部分,提取出来,放到一个新的文件中,并给其命名,这样就可以带其他地方使用

通过 define 定义模板

{{ define "MY.NAME" }}
  # body of template here
{{ end }}

include

记住标准用法

{{ include "named template" . }}

解释: . 表示的是scope。 这里也可以改成 .Values

空格

注意:换行也算空格

{{- 表示左边的空格和换行会移除
-}} 表示右边的空格和换行会移除

实例:

  food: {{ .Values.favorite.food | upper | quote }}
  {{ if eq .Values.favorite.drink "coffee" -}}
  mug: "true"
  {{ end }}

会渲染出

food: "PIZZA"

mug: "true"

  food: {{ .Values.favorite.food | upper | quote }}
  {{- if eq .Values.favorite.drink "coffee" -}}
  mug: "true"
  {{- end -}}

会渲染出

food: "PIZZA"mug: "true"

正确的写法是

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ .Values.favorite.drink | default "tea" | quote }}
  food: {{ .Values.favorite.food | upper | quote }}
  {{- if eq .Values.favorite.drink "coffee" }}
  mug: "true"
  {{- end }}

Helm 本地测试技巧

格式化校验

helm lint Path [flag]
  • Path: a path of chart

本地渲染

helm template path [flag]

helm template命令来自于开源的 https://github.com/technosophos/helm-template

Helm chart最佳实践

基本规约

Chart命名

必须是小写字母,分割符用-

版本规范

版本号遵循SemVer2的规范

Yaml缩进

使用两个空格缩进,不能用tab

Values 自定义变量

values.yaml编写的最佳实践

命名规范

首字母小写的驼峰式命名

反例:

Chicken: true  # initial caps may conflict with built-ins
chicken-noodle-soup: true # do not use hyphens in the name

所有Helm内置的变量都是大写开头(如.Chart.Name, .Capabilities.KubeVersion),这样可以和用户自定义的变量区分开

变量平铺 Or 层叠

Yaml格式灵活,里面的变量既可以平铺也可以层叠编写
层叠:

server:
  name: nginx
  port: 80

平铺:

serverName: nginx
serverPort: 80

通常:平铺更好,因为简单

当相关的一些变量是可选的,为了安全起见,使用层叠方式,并在每个层级中都对变量进行校验。

{{ if .Values.server }}
  {{ default "none" .Values.server.name }}
{{ end }}

类型清醒

Yaml的类型转化的规则有时是反直觉的。比如foo: falsefoo: "false"不一样。 大数 foo:1234567在某些场景下会变成科学计数法表达。

最简单,清醒的做法:所有变量都用 ""引号 表达成字符串。

在需要使用数字时,用 {{ int $value }} 进行变量转换

使用字典而不是数组

由于values.yaml的变量是可以支持被命令行的参数 --set--set-string 改写,而参数的写法有限。
所以values.yaml变量的写法尽可能使用map,而不是数组

反例:

servers:
  - name: foo
    port: 80
  - name: bar
    port: 81

如何用--set改写端口, Helm2.4之前不支持, 2.5之后可以用 --set servers[0].port=80。 但表意不明确,万一values里的顺序改变了,就糟糕了。

正例:

servers:
  foo:
    port: 80
  bar:
    port: 81

改foo的端口 --set servers.foo.port=80

注释

每个变量都应该注释。
注释必须以变量名开头

正例

# serverHost is the host name for the webserver
serverHost: example
# serverPort is the HTTP listener port for the webserver
serverPort: 9191

变量名开头的注释有利于在grep时,可以快速抓取变量及其文档说明

Templates 模板

templates的结构化规范:

  • 所有的yaml模板必须有.yaml后缀, 非格式化内容的模板使用.tpl后缀
  • 模板文件的命名使用小写,-虚线表示法。如(my-example-configmap.yaml)
  • 每种资源的定义必须单独的模板文件
  • 模板文件名必须反应出其表示的资源。如:foo-pod.yaml, bar-svc.yaml

命名模板

{{ define }}创建出命名模板是全局可见的,为了避免名称冲突,命名中应该带上命名空间。
正例

{{- define "nginx.fullname" }}
{{/* ... */}}
{{ end -}}

反例

{{- define "fullname" -}}
{{/* ... */}}
{{ end -}}

推荐使用helm create 创建新的chart,它会自动循序最佳实践

模板命令

{{ }}表示模板命令。在{{后和}}前需要用一个空格隔开

正例

{{ .foo }}
{{ print "foo" }}
{{- print "bar" -}}

反例

{{.foo}}
{{print "foo"}}
{{-print "bar"-}}

注释

Yaml注释: 常用注释,而且在helm install --debug 调试时可见

# This is a comment
type: sprocket

模板注释:多行注释,常用于对模块、方法的说明

{{- /*
This is a comment.
*/}}
type: frobnitz

Lable和Anonotation

二者都是元数据,有着各自的适用场景。
Label

  • 被k8s用来标识资源
  • 被运维用来查询

上述两个目的外的场景,都应该使用Annonation

标准标签

Name Status Description
app.kubernetes.io/name 推荐 {{ .Chart.Name }}
helm.sh/chart 推荐 {{ .Chart.Name }}-{{ .Chart.Version replace "+" "_" }}
app.kubernetes.io/managed-by 推荐 {{ .Release.Service }}, 可用来找Helm托管的应用
app.kubernetes.io/instance 推荐 {{ .Release.Name }}
app.kubernetes.io/version 可选 {{ .Chart.AppVersion }}
app.kubernetes.io/component 可选 标记应用在系统的角色。如app.kubernetes.io/component: frontend
app.kubernetes.io/part-of 可选 标记所属的整体

Pod 容器

Image

镜像需要用固定的标签或镜像的sha值,不能用 latest,head, canary这些“引用”性质标签

ImagePullPolicy

deployment.yaml

imagePullPolicy: {{ .Values.image.pullPolicy }}

values.yaml

image:
  pullPolicy: IfNotPresent

PodTemplates

必须定义一个selector

selector:
  matchLabels:
      app.kubernetes.io/name: MyName
template:
  metadata:
    labels:
      app.kubernetes.io/name: MyName

一个标准的Helm Chart

待补充

引用

https://helm.sh/docs

https://cloudblogs.microsoft.com/opensource/2020/04/02/when-to-use-helm-operators-kubernetes-ops/

https://searchitoperations.techtarget.com/tip/When-to-use-Kubernetes-operators-vs-Helm-charts

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
6月前
|
Kubernetes NoSQL Redis
第五章 使用Helm部署一个应用
第五章 使用Helm部署一个应用
144 2
|
2月前
|
jenkins 持续交付 Docker
自动化部署:从源代码到生产环境
在这篇文章中,我们将一起探索如何将代码从源代码库自动部署到生产环境。我们将通过一个简单的Python Flask应用示例,展示如何使用Docker和Jenkins实现自动化部署。在这个过程中,我们将学习如何编写Dockerfile,创建Jenkins任务,以及如何将这两个工具结合起来实现自动化部署。无论你是运维新手还是经验丰富的老手,这篇文章都将为你提供有价值的参考。【8月更文挑战第31天】
|
3月前
|
Kubernetes Java 开发工具
Kubernetes部署项目流程(新手上线新版本服务整个流程)
【8月更文挑战第1天】Kubernetes(k8s)新手上线新版本服务整个流程
|
6月前
|
JSON Kubernetes Go
无缝集成:在IntelliJ IDEA中利用Kubernetes插件轻松管理容器化应用
无缝集成:在IntelliJ IDEA中利用Kubernetes插件轻松管理容器化应用
287 0
无缝集成:在IntelliJ IDEA中利用Kubernetes插件轻松管理容器化应用
|
6月前
|
监控 前端开发 jenkins
Jenkins在前端项目持续部署中的应用,介绍了Jenkins作为自动化部署工具的基本概念和流程
【4月更文挑战第29天】本文探讨了Jenkins在前端项目持续部署中的应用,介绍了Jenkins作为自动化部署工具的基本概念和流程。前端持续部署涉及代码提交、构建、测试和部署四个步骤。实现过程中需配置代码仓库、构建、测试和部署任务,安装相关插件并确保环境一致性。注意事项包括代码质量控制、环境一致性、监控预警和安全管理。通过Jenkins,可提升前端开发效率和质量,但需不断学习以应对技术发展。
93 0
|
域名解析 Kubernetes 应用服务中间件
Rainbond的 Gateway API 插件制作实践
Gateway API 作为新一代的流量管理标准,对原有 Ingress 的扩展不规范、移植性差等问题做出了改进
|
存储 Kubernetes 应用服务中间件
部署和体验Helm(2.16.1版本)
在Kubernetes上进行容器化部署并非易事,docker、环境变量、存储、网络等方面都会涉及到,这些复杂的操作可以被Helm应用包管理工具实现,避免了全手工操作的
539 0
部署和体验Helm(2.16.1版本)
|
运维 Kubernetes Cloud Native
KubeVela v1.2 发布:你要的图形化操作控制台 VelaUX 终于来了!
时间来到 2022 年,KubeVela 也正式进入了第四个阶段,在原先核心控制器 API 基本稳定的基础上,我们以插件的形式增加了一系列开箱即用的功能。让开发者可以通过 UI 控制台的方式,连接 CI/CD 完整流程,端到端发布多集群应用,进一步提升开发者体验。
KubeVela v1.2 发布:你要的图形化操作控制台 VelaUX 终于来了!
|
存储 Kubernetes 监控
Lens5 指南:专为Kubernetes人员设计的IDE
Lens5 指南:专为Kubernetes人员设计的IDE
1920 0
Lens5 指南:专为Kubernetes人员设计的IDE
|
Kubernetes 开发工具 git
Knative 实践:从源代码到服务的自动化部署
通过之前的文章,相信大家已经熟悉了 Serving、Eventing 以及 Tekton。那么在实际使用中,我们往往会遇到一些复杂的场景,这时候就需要各个组件之间进行协作处理。例如我们提交源代码之后是否直接可以部署服务到 K8s 中? 这个场景对于用户来说很有吸引力。
下一篇
无影云桌面