Helm的打包格式叫做chart,所谓chart就是一系列文件, 它描述了一组相关的 k8s 集群资源

文件结构

k8s采用的是声明式的资源管理,以YAML文件的形式声明资源的期望状态,Chart文件包含了大部分的资源抽象,例如kubernetes deployment,service,ingress,serviceaccount等资源。

  1. $ helm create test
  2. Creating test
  3. $ tree test -L 1
  4. test
  5. ├── Chart.yaml
  6. ├── charts
  7. ├── templates
  8. └── values.yaml
  9. 2 directories, 2 files

文件说明

Chart.yaml Chart 的基本描述信息,包括Chart名称,描述,类型,版本和应用版本
values.yaml 设置模板文件的默认值,当 install 或是 upgrade 时这些值也可以被覆盖
charts 依赖的 Chart 文件
templates 目录下存放应用一系列 k8s 资源的 yaml 文件

chart.yaml 文件结构

  1. apiVersion: # chart API 版本信息, 通常是 "v1" (必须)
  2. name: # chart 的名称 (必须)
  3. version: # chart 包的版本 (必须)
  4. kubeVersion: # 指定 Kubernetes 版本 (可选)
  5. type: # chart类型 (可选)
  6. description: # 对项目的描述 (可选)
  7. keywords:
  8. - # 有关于项目的一些关键字 (可选)
  9. home: # 项目 HOME 页面的 URL 地址 (可选)
  10. sources:
  11. - # 项目源码的 URL 地址 (可选)
  12. dependencies: # chart 必要条件列表 (可选)
  13. - name: # chart名称 (nginx)
  14. version: # chart版本 ("1.2.3")
  15. repository: # (可选)仓库URL ("https://example.com/charts") 或别名 ("@repo-name")
  16. condition: # (可选) 解析为布尔值的yaml路径,用于启用/禁用chart (e.g. subchart1.enabled )
  17. tags: # (可选)
  18. - # 用于一次启用/禁用 一组chart的tag
  19. import-values: # (可选)
  20. - # ImportValue 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项
  21. alias: # (可选) chart中使用的别名。当你要多次添加相同的chart时会很有用
  22. maintainers: # (可选)维护者信息
  23. - name: # 维护者的名称
  24. email: # 维护者的邮件地址
  25. url: # 维护者的个人主页
  26. engine: gotpl # 模板引擎的名称(可选,默认为 gotpl)
  27. icon: # (可选)指定 chart 图标的 SVG 或 PNG 图像的 URL
  28. appVersion: # 应用程序包含的版本
  29. deprecated: # (可选,使用布尔值)该 chart 是否被废弃
  30. annotations:
  31. example: # 按名称输入的批注列表 (可选).

快速入门

创建一个名称叫mychartde 简单的chart,helm会自动生成一些模板文件

  1. helm create mychart
  2. Creating mychart

查看temple目录底下文件

  1. tree mychart/templates
  2. mychart/templates
  3. ├── NOTES.txt
  4. ├── _helpers.tpl
  5. ├── deployment.yaml
  6. ├── hpa.yaml
  7. ├── ingress.yaml
  8. ├── service.yaml
  9. ├── serviceaccount.yaml
  10. └── tests
  11. └── test-connection.yaml
NOTES.txt 类似于“帮助文档”,在用户运行 helm install 时显示给用户
_helpers.tpl 作用类似于“模板助手”,在这里定义需要在 Chart 中反复使用到的模板或是结构
service.yaml 创建k8s的 service相关文件
deployment.yaml 创建k8s的 deployment对象资源清单文件
ingress.yaml 创建ingress对象的资源清单文件

删除tenplayes底下的文件

  1. rm -rf mychart/templates/*


创建mychart/templates/configmap.yaml,内容如下

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: mychart-configmap
  5. data:
  6. myvalue: "Hello Mychart"

本地安装

  1. helm install my-chart ./mychart
  2. NAME: my-chart
  3. LAST DEPLOYED: Sun Jul 11 11:41:20 2021
  4. NAMESPACE: default
  5. STATUS: deployed
  6. REVISION: 1
  7. TEST SUITE: None


使用helm 命令查看release和实际加载的模板内容

  1. helm get manifest my-chart
  2. ---
  3. # Source: mychart/templates/configmap.yaml
  4. apiVersion: v1
  5. kind: ConfigMap
  6. metadata:
  7. name: mychart-configmap
  8. data:
  9. myvalue: "Hello Mychart"

先删除mychart

  1. helm uninstall mychart
  2. release "mychart" uninstalled

修改配置文件

名称使用硬编码到资源中通常被认为是不好的做法。名称对于一个发布版本来说应该是唯一的。因此,我们可能通过插入变量名来生成名称字段。
提示:由于对DNS系统的限制,name:字段被限制为63个字符。因此,发布名被限制为53个字符。Kubernetes 1.3和更早的版本限制为只有24个字符(因此只有14个字符)。

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: {{.Release.Name}}-congfigmap
  5. data:
  6. myval: 'hello mychart'

执行

  1. helm install test-chart ./mychart
  2. NAME: test-chart
  3. LAST DEPLOYED: Sun Jul 11 14:39:57 2021
  4. NAMESPACE: default
  5. STATUS: deployed
  6. REVISION: 1
  7. TEST SUITE: None

查看

  1. helm get manifest test-chart
  2. ---
  3. # Source: mychart/templates/configmap.yaml
  4. apiVersion: v1
  5. kind: ConfigMap
  6. metadata:
  7. name: test-chart-configmap
  8. data:
  9. myvalue: "Hello Mychart"

—dry-run

当你想测试模板的渲染结果,但不实际安装时,你可以使用helm install —debug —dry-run my-chart ./mychart。这将呈现模板。但是不是安装chart,它会返回渲染模板,这样你就可以看到输出:

  1. helm install --debug --dry-run my-chart ./mychart
  2. ...
  3. ---
  4. # Source: mychart/templates/configmap.yaml
  5. apiVersion: v1
  6. kind: ConfigMap
  7. metadata:
  8. name: my-chart-configmap
  9. data:
  10. myvalue: "Hello Mychart"

使用——dry-run将使测试chart变得简易,但它不能确保Kubernetes会执行生生成的模板。因此不能认为试运行是可行的。就一定可以在k8s执行成功。

Chart操作

创建

  1. $ helm create mychart
  2. Creating mychart

打包helm package

打包一个 Chart 模板

  1. helm package test

安装

  1. helm install foo ./
  2. NAME: foo
  3. LAST DEPLOYED: Sat Dec 12 22:24:11 2020
  4. NAMESPACE: default
  5. STATUS: deployed
  6. REVISION: 1
  7. TEST SUITE: None

查看

  1. helm get manifest foo
  2. ---
  3. # Source: mychart/templates/configmap.yaml
  4. apiVersion: v1
  5. kind: ConfigMap
  6. metadata:
  7. name: foo-congfigmap
  8. data:
  9. myval: 'hello mychart'

使用参数 --debug --dry-run,这样会返回渲染的模板、同时不会立刻执行安装操作:

  1. helm install --debug --dry-run bar ./
  2. ....
  3. HOOKS:
  4. MANIFEST:
  5. ---
  6. # Source: mychart/templates/configmap.yaml
  7. apiVersion: v1
  8. kind: ConfigMap
  9. metadata:
  10. name: bar-congfigmap
  11. data:
  12. myval: 'hello mychart'

修改配置文件

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: {{.Release.Name}}-congfigmap
  5. data:
  6. myval: {{.Values.myval}}

执行

  1. helm install --debug --dry-run bar ./
  2. ...
  3. HOOKS:
  4. MANIFEST:
  5. ---
  6. # Source: mychart/templates/configmap.yaml
  7. apiVersion: v1
  8. kind: ConfigMap
  9. metadata:
  10. name: bar-congfigmap
  11. data:
  12. myval: hello world


—set

  1. helm install --debug --dry-run --set myval="hello helm" bar ./
  2. ...
  3. HOOKS:
  4. MANIFEST:
  5. ---
  6. # Source: mychart/templates/configmap.yaml
  7. apiVersion: v1
  8. kind: ConfigMap
  9. metadata:
  10. name: bar-congfigmap
  11. data:
  12. myval: hello helm

Nginx

创建mynginx

  1. $ helm create mynginx

目录结构

  1. tree -L 2
  2. .
  3. ├── Chart.yaml
  4. ├── charts
  5. ├── templates
  6. ├── NOTES.txt
  7. ├── _helpers.tpl
  8. ├── deployment.yaml
  9. ├── hpa.yaml
  10. ├── ingress.yaml
  11. ├── service.yaml
  12. ├── serviceaccount.yaml
  13. └── tests
  14. └── values.yaml

修改values.yaml

  1. service:
  2. type: NodePort
  3. port: 80
  4. nodePort: 30080

修改sever.yaml

  1. spec:
  2. type: {{ .Values.service.type }}
  3. ports:
  4. - port: {{ .Values.service.port }}
  5. targetPort: http
  6. protocol: TCP
  7. name: http
  8. nodePort: {{ .Values.service.nodePort }}

只是渲染当前的chart 不按照当前的chart

  1. $ helm template --debug my-nginx mynginx
  2. install.go:172: [debug] Original chart version: ""
  3. install.go:189: [debug] CHART PATH: /Users/baxiang/Documents/k8s/helm/mynginx
  4. ---
  5. # Source: mynginx/templates/serviceaccount.yaml
  6. apiVersion: v1
  7. kind: ServiceAccount
  8. metadata:
  9. name: my-nginx-mynginx
  10. labels:
  11. helm.sh/chart: mynginx-0.1.0
  12. app.kubernetes.io/name: mynginx
  13. app.kubernetes.io/instance: my-nginx
  14. app.kubernetes.io/version: "1.16.0"
  15. app.kubernetes.io/managed-by: Helm
  16. ---
  17. # Source: mynginx/templates/service.yaml
  18. apiVersion: v1
  19. kind: Service
  20. metadata:
  21. name: my-nginx-mynginx
  22. labels:
  23. helm.sh/chart: mynginx-0.1.0
  24. app.kubernetes.io/name: mynginx
  25. app.kubernetes.io/instance: my-nginx
  26. app.kubernetes.io/version: "1.16.0"
  27. app.kubernetes.io/managed-by: Helm
  28. spec:
  29. type: NodePort
  30. ports:
  31. - port: 80
  32. targetPort: http
  33. protocol: TCP
  34. name: http
  35. nodePort: 30080
  36. selector:
  37. app.kubernetes.io/name: mynginx
  38. app.kubernetes.io/instance: my-nginx
  39. ---
  40. # Source: mynginx/templates/deployment.yaml
  41. apiVersion: apps/v1
  42. kind: Deployment
  43. metadata:
  44. name: my-nginx-mynginx
  45. labels:
  46. helm.sh/chart: mynginx-0.1.0
  47. app.kubernetes.io/name: mynginx
  48. app.kubernetes.io/instance: my-nginx
  49. app.kubernetes.io/version: "1.16.0"
  50. app.kubernetes.io/managed-by: Helm
  51. spec:
  52. replicas: 1
  53. selector:
  54. matchLabels:
  55. app.kubernetes.io/name: mynginx
  56. app.kubernetes.io/instance: my-nginx
  57. template:
  58. metadata:
  59. labels:
  60. app.kubernetes.io/name: mynginx
  61. app.kubernetes.io/instance: my-nginx
  62. spec:
  63. serviceAccountName: my-nginx-mynginx
  64. securityContext:
  65. {}
  66. containers:
  67. - name: mynginx
  68. securityContext:
  69. {}
  70. image: "nginx:1.15"
  71. imagePullPolicy: IfNotPresent
  72. ports:
  73. - name: http
  74. containerPort: 80
  75. protocol: TCP
  76. livenessProbe:
  77. httpGet:
  78. path: /
  79. port: http
  80. readinessProbe:
  81. httpGet:
  82. path: /
  83. port: http
  84. resources:
  85. {}
  86. ---
  87. # Source: mynginx/templates/tests/test-connection.yaml
  88. apiVersion: v1
  89. kind: Pod
  90. metadata:
  91. name: "my-nginx-mynginx-test-connection"
  92. labels:
  93. helm.sh/chart: mynginx-0.1.0
  94. app.kubernetes.io/name: mynginx
  95. app.kubernetes.io/instance: my-nginx
  96. app.kubernetes.io/version: "1.16.0"
  97. app.kubernetes.io/managed-by: Helm
  98. annotations:
  99. "helm.sh/hook": test
  100. spec:
  101. containers:
  102. - name: wget
  103. image: busybox
  104. command: ['wget']
  105. args: ['my-nginx-mynginx:80']
  106. restartPolicy: Never

上面的命令还可以执行

  1. helm install my-nginx mynginx --dry-run --debug

安装当前的chart

  1. $ helm install my-nginx mynginx
  2. NAME: my-nginx
  3. LAST DEPLOYED: Tue Dec 29 22:36:02 2020
  4. NAMESPACE: default
  5. STATUS: deployed
  6. REVISION: 1
  7. NOTES:
  8. 1. Get the application URL by running these commands:
  9. export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services my-nginx-mynginx)
  10. export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  11. echo http://$NODE_IP:$NODE_PORT

查看当前k8s的service

  1. $kubectl get svc
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. my-nginx-mynginx NodePort 10.96.21.211 <none> 80:30080/TCP 2m8s

执行

  1. curl localhost:30080

参考

https://helm.sh/docs/chart_template_guide/getting_started/