从现有清单创建你的第一个 Helm Chart
将 Deployment、Service 和 ConfigMap 变成模板化的 chart,然后安装并升级它。
学习 Helm 模板最快的方式,是拿一份你已经理解的清单,一次模板化一个字段。本指南从一个普通的 Deployment、Service 和 ConfigMap 出发,生成 chart 脚手架,并把应该变化的字段替换为 values。
生成 chart 脚手架并清理示例
helm create webapp
cd webapp
rm -rf templates/tests templates/hpa.yaml templates/ingress.yaml \
templates/serviceaccount.yaml templates/_helpers.tpl
生成的 templates/deployment.yaml 和 templates/service.yaml 是一个可用的示例,但为了学习,从头编写你自己的会更清晰。清空它们的内容(保留文件),并清空 values.yaml:
: > values.yaml
添加你自己的清单
先像不使用 Helm 时那样,把普通的 Kubernetes YAML 写出来:
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-webapp
labels:
app: my-webapp
spec:
replicas: 3
selector:
matchLabels:
app: my-webapp
template:
metadata:
labels:
app: my-webapp
spec:
containers:
- name: my-webapp
image: myorg/webapp:1.0
envFrom:
- configMapRef:
name: my-webapp-config
ports:
- containerPort: 8080
# templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-webapp
spec:
selector:
app: my-webapp
ports:
- port: 80
targetPort: 8080
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-webapp-config
data:
CUSTOM_HEADER: "this app was deployed with Helm"
注意同一个字符串 my-webapp 在名称、标签、selector 和 ConfigMap 引用中重复出现。这种重复正是手工维护的多环境清单容易出错的原因:给应用改一次名,就有四个地方需要留意。
用模板值替换重复的值
引入一个 value,并在名称出现的每个地方引用它:
# values.yaml
appName: my-webapp
# templates/deployment.yaml (excerpt)
metadata:
name: {{ .Values.appName }}
labels:
app: {{ .Values.appName }}
spec:
selector:
matchLabels:
app: {{ .Values.appName }}
template:
metadata:
labels:
app: {{ .Values.appName }}
spec:
containers:
- name: {{ .Values.appName }}
envFrom:
- configMapRef:
name: {{ .Values.appName }}-config
在 service.yaml 和 configmap.yaml 中凡是出现 my-webapp 的地方也这样做。.Values 由 values.yaml 填充,所以在那里改一处,现在就会一致地重命名每个资源。
将镜像和 ConfigMap 的数据模板化
把镜像拆成各自的 values,使标签可以独立于仓库而变化:
# values.yaml (add)
image:
repository: myorg/webapp
tag: "1.0"
- name: {{ .Values.appName }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
以及 ConfigMap 的内容:
# values.yaml (add)
config:
customHeader: "this app was deployed with Helm"
# templates/configmap.yaml
data:
CUSTOM_HEADER: {{ .Values.config.customHeader | quote }}
| quote 过滤器会用双引号把值包起来,当特定于环境的值开始包含空格或特殊字符时,这一点很重要。命名 values 的一条好规则:镜像清单自身的结构(config.customHeader 对应 ConfigMap 的 data.CUSTOM_HEADER),这样任何阅读模板的人都能猜到某个值来自哪里。
安装之前先预览
有两个命令可以在不触碰集群的情况下渲染 chart:
helm template ./webapp
helm install my-webapp ./webapp --dry-run --debug
helm template 在本地渲染,完全不需要集群。install 上的 --dry-run --debug 还会针对集群的 API 进行验证,但不持久化任何东西。每次修改模板之后都运行其中一个;{{ .Values.appname }}(大小写错误)的拼写错误会悄无声息地渲染为空而不是报错,而这是捕获它的最快方式。
安装并确认
helm install my-webapp ./webapp
kubectl get all -l app=my-webapp
这里的 my-webapp 是 release 名称,./webapp 是 chart 目录。安装手写的 chart 与安装已发布的 chart 没有任何区别。
修改一个 value 并升级
编辑 values.yaml(升级 image.tag、更改 config.customHeader,或你正在测试的任何东西),然后应用变更:
helm upgrade my-webapp ./webapp
helm list
helm list 现在显示修订版本 2。每次 upgrade 都会用当前的 values 重新应用整个 chart,所以日常部署新版本也是这样做的。
添加 NOTES.txt
# templates/NOTES.txt
Your release "{{ .Release.Name }}" has been deployed.
To access {{ .Values.appName }}, run:
kubectl port-forward svc/{{ .Values.appName }} 8080:80
.Release.Name 是 Helm 始终提供的内置值,和 .Chart、.Release.Namespace 一样;你不需要自己设置它。再次运行 helm upgrade my-webapp ./webapp,这段文字就会打印到终端,其中的 port-forward 命令已为在场的人填好。