Helm入门
1. helm应用场景
对于一些复杂的k8s应用,如vault、spire等,可能需要部署很多k8s资源,如serviceaccount、service、pv、pvc、clusterrole、role、rolebinding等等。
用户可能有以下诉求:
- 资源里的某些参数需要根据实际情况调整
- 每个资源之间部署存在关联,比如“如果使用这个资源的时候,需要连带部署某个资源”或者“某些资源不部署时,其他资源的配置也跟随调整”
2. helm工程
1.1 目录结构
spire-server
├── Chart.yaml
├── README.md
├── templates
│ ├── _controller-manager-container.tpl
│ ├── _helpers.tpl
│ ├── server-resource.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ ├── tests
│ │ ├── test-connection.yaml
│ │ └── test-tornjak-connection.yaml
│ ├── ...省略部分yaml文件
│ └── upstream-ca-secret.yaml
└── values.yaml
- Chart.yaml:这个chart项目的信息
- templates:这个目录下存放资源部署的模版
- _helpers.tpl:一般定义共享模板片段、变量表达式、函数(宏函数)
- values.yaml:模板中的变量值
Chart.yaml示例
# chart基本信息
apiVersion: v2
name: spire-server
description: A Helm chart to install the SPIRE server.
# type值有application和library,library通常为一些公共定义的函数或者模板,不可直接helm install
type: application
version: 0.1.0
appVersion: "1.12.4"
keywords: ["spiffe", "spire-server", "spire-controller-manager"]
# chart所在github仓库
home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire
sources:- https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire
icon: https://spiffe.io/img/logos/spire/icon/color/spire-icon-color.png
# charts所有者信息
maintainers:- name: marcofranssenemail: marco.franssen@gmail.comurl: https://marcofranssen.nl- name: kfox1111email: Kevin.Fox@pnnl.gov- name: faisal-memonemail: fymemon@yahoo.com- name: edwbuckemail: edwbuck@gmail.com
1.2 远程仓库
以使用vault远程仓库为例
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
我们从https://helm.releases.hashicorp.com/index.yaml可以得到如下的信息:
apiVersion: v1
entries:vault:- annotations:charts.openshift.io/name: HashiCorp VaultapiVersion: v2appVersion: 1.20.1created: "2025-07-28T22:27:07.564221432Z"description: Official HashiCorp Vault Chartdigest: a52b3b16aa9afae2deeb3d63500578a62c3daa777551f2c5eb6c2cd07bfd79cchome: https://www.vaultproject.ioicon: https://github.com/hashicorp/vault/raw/f22d202cde2018f9455dec755118a9b84586e082/Vault_PrimaryLogo_Black.pngkeywords:- vault- security- encryption- secrets- management- automation- infrastructurekubeVersion: '>= 1.20.0-0'name: vaultsources:- https://github.com/hashicorp/vault- https://github.com/hashicorp/vault-helm- https://github.com/hashicorp/vault-k8s- https://github.com/hashicorp/vault-csi-providerurls:- https://helm.releases.hashicorp.com/vault-0.30.1.tgzversion: 0.30.1
其中可以得到helm charts源码仓库和helm charts的压缩包地址。
1.3 调试部署
常用的一些部署调试办法:
helm repo add [helm-project] [helm-repo]
helm repo update
helm install [release-name] [helm-project]/[chart-dir] <[--dry-run]> <[--disable-openapi-validation]> <[--values path/to/valeus.yaml]>
# --dry-run: 尝试运行看是否有异常,并输出部署脚本
# --disable-openapi-validation: 为避免语法、参数、格式问题导致helm运行错误,这里可以忽略校验异常,一般与dry-run一起用,便于调试
更多的调试方法参考:https://helm.sh/zh/docs/chart_template_guide/debugging/
2. helm常用语法
helm通过将values里定义的参数值,填入模板对应的占位符,最终输出完整的部署脚本。这个是基于go template实现。
下面整理一些常用的helm关键概念。
helm的变量对象引用都可以理解对应在values里定义对象的一个yaml path。
2.1 helm内置对象
官方文档:https://helm.sh/zh/docs/chart_template_guide/builtin_objects/
你可能会在template文件里看到下面前缀的变量
- -Release.
- 这是Helm模板渲染时,Helm内置的一个全局对象。常用的有
字段 | 说明 |
.Release.Name | 当前发布的名字 |
.Release.Namespace | 发布的Kubernetes 命名空间 |
.Release.Service | Helm服务名称,通常是 `Tiller`(Helm v2)或空(Helm v3) |
.Release.IsInstall | 是否是安装操作(true/false) |
.Release.IsUpgrade | 是否是升级操作(true/false) |
.Release.Revision | 发布的版本号(第几次发布) |
.Release.Time | 发布的时间戳 |
- -Chart.
- 引用Chart.yaml里定义的对象
- -Values.
- 引用values.yaml里定义的对象
2.2 helm内置方法
官方文档:https://helm.sh/zh/docs/chart_template_guide/function_list/
helm有很多内置的方法/函数,比如:
{{- toYaml .Values.extraContainers | nindent 8 }}
这个语句用到了两个方法(我们可以从官方文档得到方法的功能说明):
- toYaml: 将列表,切片,数组,字典或对象转换成已缩进的yaml,可以从任意源拷贝yaml块。该功能和Go的yaml.Marshal函数一样,文档详见:https://pkg.go.dev/gopkg.in/yaml.v2#Marshal
- nindent: 函数和indent函数一样,但可以在字符串开头添加新行。
2.3 命名模板
我们可以像C++的宏定义一样定义我们的模板片段,如:
{{- define "spire-server.subject" }}
subjects:
{{- if .Values.externalServer }}
- apiGroup: rbac.authorization.k8s.iokind: Username: spire-root
{{- else }}
- kind: ServiceAccountname: {{ include "spire-server.serviceAccountName" . }}namespace: {{ include "spire-server.namespace" . }}
{{- end }}
{{- end }}
然后可以使用template或者include来引用这个“宏定义模板”
template因为是直出预定义的模板片段,所以容易引起缩进问题;include方法会输出字符串,所以可以继续通过管道和缩进相关的方法(如:nindent)