Chart模板:函数与管道
常用函数:
quote:将值转换为字符串,即加双引号
示例:nodeSelector标签的值用了true正常使用会报错,这是因为它是关键字,需要加引号才可以。
replicaCount: 1 image: repository: nginx tag: "latest" selectorLabels: "nginx" nodeSelector: gpu: true
|
apiVersion: apps/v1 kind: Deployment metadata: labels: app: web2 name: {{ .Release.Name }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ .Values.selectorLabels }} template: metadata: labels: app: {{ .Values.selectorLabels }} spec: nodeSelector: gpu: {{ quote .Values.nodeSelector.gpu }} containers: - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} name: nginx
|
apiVersion: v1 kind: Service metadata: labels: app: web2 name: {{ .Release.Name }} spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: {{ .Values.selectorLabels }}
|
验证部署
helm install web2 --dry-run mychart/ helm install web2 mychart/
|


default:设置默认值,如果获取的值为空则为默认值
示例:以防止忘记定义而导致模板文件缺少字段无法创建资源,这时可以为字段定义一个默认值。
replicaCount: 1 image: repository: nginx tag: "latest" selectorLabels: "nginx" nodeSelector: gpu: true labels: app: ""
|
apiVersion: apps/v1 kind: Deployment metadata: labels: app: {{ .Values.labels.app | default "web2" }} name: {{ .Release.Name }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ .Values.selectorLabels }} template: metadata: labels: app: {{ .Values.selectorLabels }} spec: nodeSelector: gpu: {{ quote .Values.nodeSelector.gpu }} containers: - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} name: nginx
|
验证部署
helm install web3 --dry-run mychart/ helm install web3 mychart/
|
这里用到了管道符“|”,前面的值传递后函数验证是否为空。


indent和nindent函数都是缩进字符串,主要区别在于nindent会在缩进前多添加一个换行符。
示例:


toYaml:引用一块YAML内容
示例:在values.yaml里写结构化数据,引用内容块
replicaCount: 1 image: repository: nginx tag: "latest" selectorLabels: "nginx" nodeSelector: gpu: true labels: app: "" resources: limits: cpu: 100m memory: 128Mi requests: cpu: 100m memory: 128Mi
|
apiVersion: apps/v1 kind: Deployment metadata: labels: app: {{ .Values.labels.app | default "web2" }} name: {{ .Release.Name }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ .Values.selectorLabels }} template: metadata: labels: app: {{ .Values.selectorLabels }} spec: nodeSelector: gpu: {{ quote .Values.nodeSelector.gpu }} containers: - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} name: nginx resources: {{ toYaml .Values.resources | nindent 10 }}
|
验证
helm install web4 --dry-run /root/mychart/
|


helm install web4 --set resources.limits.cpu="200m" --dry-run /root/mychart/
|

Chart模板:流程控制
Helm模板语言提供以下流程控制语句:
-
if/else:条件判断
-
range:循环
-
with:指定变量作用域
Chart模板:流程控制之if/else

条件判断:根据不同的条件做不同的行为
语法:
{{ if <表达式> }}
{{ else if <表达式> }}
{{ else }}
{{ end }}
|
示例:部署一个应用,在没明确启用ingress时,默认情况下不启用
{{ if .Values.ingress.enabled }} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: minimal-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - http: paths: - path: /testpath pathType: Prefix backend: service: name: test port: number: 80 {{ end }}
|
验证
helm install web1 --set ingress.enabled=true --dry-run /root/mychart/
|


如果值为以下几种情况则为false:
条件表达式也支持操作符:
-
eq 等于
-
ne 不等于
-
lt 小于
-
gt 大于
-
and 逻辑与
-
or 逻辑或
示例:如果是一个空的集合则不启用资源配额
replicaCount: 1 image: repository: nginx tag: "latest" selectorLabels: "nginx" nodeSelector: gpu: true labels: app: "" resources: {}
ingress: enabled: false
|
apiVersion: apps/v1 kind: Deployment metadata: labels: app: {{ .Values.labels.app | default "web2" }} name: {{ .Release.Name }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ .Values.selectorLabels }} template: metadata: labels: app: {{ .Values.selectorLabels }} spec: nodeSelector: gpu: {{ quote .Values.nodeSelector.gpu }} containers: - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} name: nginx {{- if .Values.resources }} resources: {{- toYaml .Values.resources | nindent 10 }} {{- end }}
|
验证渲染结果:
helm install test --dry-run mychart/
|


渲染结果会发现有多余的空行,这是因为模板渲染时会将 指令删除,所以原有的位置就空白了。可以使用横杠“-” 消除空
Chart模板:流程控制之range

循环:一般用于遍历序列结构的数据。例如序列、键值
语法:
{{ range <值> }}
{{ end }}
|
示例:遍历数据
apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }} data: test: | {{- range.Values.test }} {{ . }} {{- end }}
|
验证渲染结果
helm install web1 --dry-run mychart/
|


Chart模板:流程控制之with
with:指定变量作用域
语法:
with语句可以允许将当前范围 . 设置为特定的对象,比如我们前面一直使用 的 .Values.nodeSelecotr,我们可以使用 with来将 . 范围指向 .Values.nodeSelecotr:
示例:
labels: project: "ms" app: "gateway"
|
apiVersion: apps/v1 kind: Deployment metadata: labels: {{- with .Values.labels }} project: {{ .project }} app: {{ .app }} {{- end }} name: {{ .Release.Name }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ .Values.selectorLabels }} template: metadata: labels: app: {{ .Values.selectorLabels }} spec: nodeSelector: gpu: {{ quote .Values.nodeSelector.gpu }} containers: - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} name: nginx {{- if .Values.resources }} resources: {{- toYaml .Values.resources | nindent 10 }} {{- end }}
|
验证渲染结果
helm install web1 --dry-run mychart/
|


with块限制了变量作用域,也就是无法直接引用模板对象,例 如.Values、.Release,如果还想使用,可以定义变量来解决该问题。
示例:
apiVersion: apps/v1 kind: Deployment metadata: labels: {{- $rs := .Values.replicaCount }} {{- with .Values.labels }} project: {{ .project }} app: {{ .app }}{{ $rs }} {{- end }} name: {{ .Release.Name }} spec: ...
|
验证
helm install web1 --dry-run mychart/
|


或者

Chart模板:变量
变量是实际应用中不多,但有时候结合with、range能更好处理数据。
示例:k8s变量是键值,可以range遍历生成
env: NAME: "gateway" JAVA_OPTS: "-Xmx1G"
|
apiVersion: apps/v1 kind: Deployment metadata: labels: {{- $rs := .Values.replicaCount }} {{- with .Values.labels }} project: {{ .project }} app: {{ .app }}{{ $.Values.replicaCount }} {{- end }} name: {{ .Release.Name }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ .Values.selectorLabels }} template: metadata: labels: app: {{ .Values.selectorLabels }} spec: nodeSelector: gpu: {{ quote .Values.nodeSelector.gpu }} containers: - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} name: nginx {{- if .Values.resources }} resources: {{- toYaml .Values.resources | nindent 10 }} {{- end }} env: {{- range $k,$v := .Values.env }} - name: {{ $k }} value: {{ quote $v }} {{- end }}
|
验证渲染结果:
helm install web1 --dry-run mychart/
|


Chart模板:命名模板
命名模板类似于开发语言中的函数。指一段可以直接被另一段程序或代码引用的程序或代码。 在编写chart时,可以将一些重复使用的内容写在命名模板文件中供公共使用,这样可减少重 复编写程序段和简化代码结构。
命名模块使用define定义,template或include引入,在templates目录中默认下划线开头的 文件为公共模板(helpers.tpl)。
示例:资源名称生成指令放到公共模板文件,作为所有资源名称
{{- define "fullname" -}} {{- .Chart.Name -}}-{{ .Release.Name }} {{- end -}}
|
apiVersion: apps/v1 kind: Deployment metadata: labels: {{- $rs := .Values.replicaCount }} {{- with .Values.labels }} project: {{ .project }} app: {{ .app }}{{ $.Values.replicaCount }} {{- end }} name: {{ template "fullname" . }}
|
验证渲染结果:
helm install web1 --dry-run mychart/
|


template指令是将一个模板包含在另一个模板中的方法。但是,template函 数不能用于Go模板管道。为了解决该问题,引入include指令。
示例:
{{- define "labels" -}} project: {{ .Values.labels.project }} app: {{ .Values.labels.app }} {{- end -}}
|
apiVersion: apps/v1 kind: Deployment metadata: labels: {{- include "labels" .| nindent 4 }} name: {{ template "fullname" . }}
|
验证渲染结果:
helm install web1 --dry-run mychart/
|


带你写一个通用的Chart
-
先创建模板示例 helm create demo
-
修改Chart.yaml,Values.yaml,参考示例预留变动的字段值
-
在templates目录下准备部署应用所需的yaml文件,并添加指令引用 Values.yaml字段
-
将重复使用的内容作为命名模板
-
使用Chart结合参数部署多个同类服务
demo-0.1.0.tgz
使用Harbor作为Chart仓库
Harbor是一个主流的镜像仓库系统,在 v1.6 版本以后的 harbor 中新增加了 helm charts 的管理功能,可以存储Chart文件。
使用步骤:
1、启用Harbor的Chart仓库服务
启用后,默认创建的项目就带有helm charts功能了。
2、安装push插件
helm plugin install https://github.com/chartmuseum/helm-push ls /root/.local/share/helm/plugins/helm-push/
|
3、推送

4、添加repo
helm repo add myrepo --username=admin --password=Harbor12345 http://192.168.0.13:/chartrepo/library helm repo update helm repo list
|
5、部署
helm install web1 --set service.type=NodePort --set service.nodeport=30010 myrepo/demo
|
公共Chart仓库
国内Chart仓库,可直接使用它们制作好的包:
添加仓库方式:
helm repo add stable http://mirror.azure.cn/kubernetes/charts helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts helm repo update helm repo list
|