Helm的打包格式叫做chart,所谓chart就是一系列文件, 它描述了一组相关的 k8s 集群资源
文件结构
k8s采用的是声明式的资源管理,以YAML文件的形式声明资源的期望状态,Chart文件包含了大部分的资源抽象,例如kubernetes deployment,service,ingress,serviceaccount等资源。
$ helm create testCreating test$ tree test -L 1test├── Chart.yaml├── charts├── templates└── values.yaml2 directories, 2 files
文件说明
| Chart.yaml | Chart 的基本描述信息,包括Chart名称,描述,类型,版本和应用版本 |
|---|---|
| values.yaml | 设置模板文件的默认值,当 install 或是 upgrade 时这些值也可以被覆盖 |
| charts | 依赖的 Chart 文件 |
| templates | 目录下存放应用一系列 k8s 资源的 yaml 文件 |
chart.yaml 文件结构
apiVersion: # chart API 版本信息, 通常是 "v1" (必须)name: # chart 的名称 (必须)version: # chart 包的版本 (必须)kubeVersion: # 指定 Kubernetes 版本 (可选)type: # chart类型 (可选)description: # 对项目的描述 (可选)keywords:- # 有关于项目的一些关键字 (可选)home: # 项目 HOME 页面的 URL 地址 (可选)sources:- # 项目源码的 URL 地址 (可选)dependencies: # chart 必要条件列表 (可选)- name: # chart名称 (nginx)version: # chart版本 ("1.2.3")repository: # (可选)仓库URL ("https://example.com/charts") 或别名 ("@repo-name")condition: # (可选) 解析为布尔值的yaml路径,用于启用/禁用chart (e.g. subchart1.enabled )tags: # (可选)- # 用于一次启用/禁用 一组chart的tagimport-values: # (可选)- # ImportValue 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项alias: # (可选) chart中使用的别名。当你要多次添加相同的chart时会很有用maintainers: # (可选)维护者信息- name: # 维护者的名称email: # 维护者的邮件地址url: # 维护者的个人主页engine: gotpl # 模板引擎的名称(可选,默认为 gotpl)icon: # (可选)指定 chart 图标的 SVG 或 PNG 图像的 URLappVersion: # 应用程序包含的版本deprecated: # (可选,使用布尔值)该 chart 是否被废弃annotations:example: # 按名称输入的批注列表 (可选).
快速入门
创建一个名称叫mychartde 简单的chart,helm会自动生成一些模板文件
helm create mychartCreating mychart
查看temple目录底下文件
tree mychart/templatesmychart/templates├── NOTES.txt├── _helpers.tpl├── deployment.yaml├── hpa.yaml├── ingress.yaml├── service.yaml├── serviceaccount.yaml└── tests└── test-connection.yaml
| NOTES.txt | 类似于“帮助文档”,在用户运行 helm install 时显示给用户 |
|---|---|
| _helpers.tpl | 作用类似于“模板助手”,在这里定义需要在 Chart 中反复使用到的模板或是结构 |
| service.yaml | 创建k8s的 service相关文件 |
| deployment.yaml | 创建k8s的 deployment对象资源清单文件 |
| ingress.yaml | 创建ingress对象的资源清单文件 |
删除tenplayes底下的文件
rm -rf mychart/templates/*
创建mychart/templates/configmap.yaml,内容如下
apiVersion: v1kind: ConfigMapmetadata:name: mychart-configmapdata:myvalue: "Hello Mychart"
本地安装
helm install my-chart ./mychartNAME: my-chartLAST DEPLOYED: Sun Jul 11 11:41:20 2021NAMESPACE: defaultSTATUS: deployedREVISION: 1TEST SUITE: None
使用helm 命令查看release和实际加载的模板内容
helm get manifest my-chart---# Source: mychart/templates/configmap.yamlapiVersion: v1kind: ConfigMapmetadata:name: mychart-configmapdata:myvalue: "Hello Mychart"
先删除mychart
helm uninstall mychartrelease "mychart" uninstalled
修改配置文件
名称使用硬编码到资源中通常被认为是不好的做法。名称对于一个发布版本来说应该是唯一的。因此,我们可能通过插入变量名来生成名称字段。
提示:由于对DNS系统的限制,name:字段被限制为63个字符。因此,发布名被限制为53个字符。Kubernetes 1.3和更早的版本限制为只有24个字符(因此只有14个字符)。
apiVersion: v1kind: ConfigMapmetadata:name: {{.Release.Name}}-congfigmapdata:myval: 'hello mychart'
执行
helm install test-chart ./mychartNAME: test-chartLAST DEPLOYED: Sun Jul 11 14:39:57 2021NAMESPACE: defaultSTATUS: deployedREVISION: 1TEST SUITE: None
查看
helm get manifest test-chart---# Source: mychart/templates/configmap.yamlapiVersion: v1kind: ConfigMapmetadata:name: test-chart-configmapdata:myvalue: "Hello Mychart"
—dry-run
当你想测试模板的渲染结果,但不实际安装时,你可以使用helm install —debug —dry-run my-chart ./mychart。这将呈现模板。但是不是安装chart,它会返回渲染模板,这样你就可以看到输出:
helm install --debug --dry-run my-chart ./mychart...---# Source: mychart/templates/configmap.yamlapiVersion: v1kind: ConfigMapmetadata:name: my-chart-configmapdata:myvalue: "Hello Mychart"
使用——dry-run将使测试chart变得简易,但它不能确保Kubernetes会执行生生成的模板。因此不能认为试运行是可行的。就一定可以在k8s执行成功。
Chart操作
创建
$ helm create mychartCreating mychart
打包helm package
打包一个 Chart 模板
helm package test
安装
helm install foo ./NAME: fooLAST DEPLOYED: Sat Dec 12 22:24:11 2020NAMESPACE: defaultSTATUS: deployedREVISION: 1TEST SUITE: None
查看
helm get manifest foo---# Source: mychart/templates/configmap.yamlapiVersion: v1kind: ConfigMapmetadata:name: foo-congfigmapdata:myval: 'hello mychart'
使用参数 --debug --dry-run,这样会返回渲染的模板、同时不会立刻执行安装操作:
helm install --debug --dry-run bar ./....HOOKS:MANIFEST:---# Source: mychart/templates/configmap.yamlapiVersion: v1kind: ConfigMapmetadata:name: bar-congfigmapdata:myval: 'hello mychart'
修改配置文件
apiVersion: v1kind: ConfigMapmetadata:name: {{.Release.Name}}-congfigmapdata:myval: {{.Values.myval}}
执行
helm install --debug --dry-run bar ./...HOOKS:MANIFEST:---# Source: mychart/templates/configmap.yamlapiVersion: v1kind: ConfigMapmetadata:name: bar-congfigmapdata:myval: hello world
—set
helm install --debug --dry-run --set myval="hello helm" bar ./...HOOKS:MANIFEST:---# Source: mychart/templates/configmap.yamlapiVersion: v1kind: ConfigMapmetadata:name: bar-congfigmapdata:myval: hello helm
Nginx
创建mynginx
$ helm create mynginx
目录结构
tree -L 2.├── Chart.yaml├── charts├── templates│ ├── NOTES.txt│ ├── _helpers.tpl│ ├── deployment.yaml│ ├── hpa.yaml│ ├── ingress.yaml│ ├── service.yaml│ ├── serviceaccount.yaml│ └── tests└── values.yaml
修改values.yaml
service:type: NodePortport: 80nodePort: 30080
修改sever.yaml
spec:type: {{ .Values.service.type }}ports:- port: {{ .Values.service.port }}targetPort: httpprotocol: TCPname: httpnodePort: {{ .Values.service.nodePort }}
只是渲染当前的chart 不按照当前的chart
$ helm template --debug my-nginx mynginxinstall.go:172: [debug] Original chart version: ""install.go:189: [debug] CHART PATH: /Users/baxiang/Documents/k8s/helm/mynginx---# Source: mynginx/templates/serviceaccount.yamlapiVersion: v1kind: ServiceAccountmetadata:name: my-nginx-mynginxlabels:helm.sh/chart: mynginx-0.1.0app.kubernetes.io/name: mynginxapp.kubernetes.io/instance: my-nginxapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helm---# Source: mynginx/templates/service.yamlapiVersion: v1kind: Servicemetadata:name: my-nginx-mynginxlabels:helm.sh/chart: mynginx-0.1.0app.kubernetes.io/name: mynginxapp.kubernetes.io/instance: my-nginxapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helmspec:type: NodePortports:- port: 80targetPort: httpprotocol: TCPname: httpnodePort: 30080selector:app.kubernetes.io/name: mynginxapp.kubernetes.io/instance: my-nginx---# Source: mynginx/templates/deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: my-nginx-mynginxlabels:helm.sh/chart: mynginx-0.1.0app.kubernetes.io/name: mynginxapp.kubernetes.io/instance: my-nginxapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helmspec:replicas: 1selector:matchLabels:app.kubernetes.io/name: mynginxapp.kubernetes.io/instance: my-nginxtemplate:metadata:labels:app.kubernetes.io/name: mynginxapp.kubernetes.io/instance: my-nginxspec:serviceAccountName: my-nginx-mynginxsecurityContext:{}containers:- name: mynginxsecurityContext:{}image: "nginx:1.15"imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80protocol: TCPlivenessProbe:httpGet:path: /port: httpreadinessProbe:httpGet:path: /port: httpresources:{}---# Source: mynginx/templates/tests/test-connection.yamlapiVersion: v1kind: Podmetadata:name: "my-nginx-mynginx-test-connection"labels:helm.sh/chart: mynginx-0.1.0app.kubernetes.io/name: mynginxapp.kubernetes.io/instance: my-nginxapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helmannotations:"helm.sh/hook": testspec:containers:- name: wgetimage: busyboxcommand: ['wget']args: ['my-nginx-mynginx:80']restartPolicy: Never
上面的命令还可以执行
helm install my-nginx mynginx --dry-run --debug
安装当前的chart
$ helm install my-nginx mynginxNAME: my-nginxLAST DEPLOYED: Tue Dec 29 22:36:02 2020NAMESPACE: defaultSTATUS: deployedREVISION: 1NOTES:1. Get the application URL by running these commands:export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services my-nginx-mynginx)export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")echo http://$NODE_IP:$NODE_PORT
查看当前k8s的service
$kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEmy-nginx-mynginx NodePort 10.96.21.211 <none> 80:30080/TCP 2m8s
执行
curl localhost:30080
