Helm简介
Helm 是 Kubernetes 的包管理器,类似CentOS 的yum、dnf,类似Ubuntu的apt。概括起来就是优雅 。
Helm 工作流程的概述:
helm有以下几个核心功能:
(1)将变量从”value.yaml”文件中获取,并渲染到chart模板文件中;
(2)chart模板文件对应的是一系列yaml文件,会基于这些yaml清单来部署应用到kuberntes集群;
(3)helm也有其对应的Chart仓库,这些公共仓库是一些其他开发或者运维人员编写好的chart,如果他们写的chart在我们工作中能用到就是最好的了;
Helm安装 下载及安装 方式一: 使用脚本安装
1 2 3 $ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 $ chmod 700 get_helm.sh $ ./get_helm.sh
方式二:下载二进制文件安装
1 2 3 4 5 6 7 8 wget -O helm-v3.0.0-linux-amd64.tar.gz https://get.helm.sh/helm-v3.17.1-linux-amd64.tar.gz tar -zxvf helm-v3.0.0-linux-amd64.tar.gz mv linux-amd64/helm /usr/local/bin/helm
helm命令自动补全 1 $ helm completion bash > /etc/bash_completion.d/helm && source /etc/bash_completion.d/helm
使用Helm创建Chart Chart 目录结构 创建一个Chart:
1 2 $ helm create kelvyn-chart
目录结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 $ tree kelvyn-chart/ kelvyn-chart/ ├── charts ├── Chart.yaml ├── templates │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── hpa.yaml │ ├── ingress.yaml │ ├── NOTES.txt │ ├── serviceaccount.yaml │ ├── service.yaml │ └── tests │ └── test-connection.yaml └── values.yaml --- 官方文档的说明: wordpress/ Chart.yaml LICENSE README.md values.yaml values.schema.json charts/ crds/ templates/ templates/NOTES.txt
Helm保留使用 charts/,crds/, templates/目录,以及列举出的文件名。其他文件保持原样。
Chart.yaml 文件说明 Chart.yaml
文件是chart必需的。包含了以下字段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 apiVersion: chart API 版本 (必需) name: chart名称 (必需) version: 语义化2 版本(必需) kubeVersion: 兼容Kubernetes版本的语义化版本(可选) description: 一句话对这个项目的描述(可选) type: chart类型 (可选) keywords: - 关于项目的一组关键字(可选) home: 项目home页面的URL (可选) sources: - 项目源码的URL列表(可选) dependencies: - 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的tag import-values: - ImportValue 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项 alias: (可选) chart中使用的别名。当你要多次添加相同的chart时会很有用 maintainers: - name: 维护者名字 (每个维护者都需要) email: 维护者邮箱 (每个维护者可选) url: 维护者URL (每个维护者可选) icon: 用做icon的SVG或PNG图片URL (可选) appVersion: 包含的应用版本(可选)。不需要是语义化,建议使用引号 deprecated: 不被推荐的chart (可选,布尔值) annotations: example: 按名称输入的批注列表 (可选).
从 v3.3.2,不再允许额外的字段。推荐的方法是在 annotations 中添加自定义元数据。
模板文件说明 模板文件遵守书写Go模板的标准惯例(查看 文本/模板 Go 包文档 了解更多)。 模板文件的例子看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 apiVersion: v1 kind: ReplicationController metadata: name: deis-database namespace: deis labels: app.kubernetes.io/managed-by: deis spec: replicas: 1 selector: app.kubernetes.io/name: deis-database template: metadata: labels: app.kubernetes.io/name: deis-database spec: serviceAccount: deis-database containers: - name: deis-database image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }} imagePullPolicy: {{ .Values.pullPolicy }} ports: - containerPort: 5432 env: - name: DATABASE_STORAGE value: {{ default "minio" .Values.storage }}
上面的例子,松散地基于 https://github.com/deis/charts , 是一个Kubernetes副本控制器的模板。可以使用下面四种模板值(一般被定义在values.yaml文件):
imageRegistry
: Docker镜像的源注册表
dockerTag
: Docker镜像的tag
pullPolicy
: Kubernetes的拉取策略
storage
: 后台存储,默认设置为”minio”
所有的值都是模板作者定义的。Helm不需要或指定参数。
预定义的values values通过模板中.Values对象可访问的values.yaml文件(或者通过 –set 参数)提供, 但可以模板中访问其他预定义的数据片段。
以下值是预定义的,对每个模板都有效,并且可以被覆盖。和所有值一样,名称 区分大小写。
Release.Name
: 版本名称(非chart的)
Release.Namespace
: 发布的chart版本的命名空间
Release.Service
: 组织版本的服务
Release.IsUpgrade
: 如果当前操作是升级或回滚,设置为true
Release.IsInstall
: 如果当前操作是安装,设置为true
Chart
: Chart.yaml
的内容。因此,chart的版本可以从 Chart.Version 获得, 并且维护者在Chart.Maintainers里。
Files
: chart中的包含了非特殊文件的类图对象。这将不允许您访问模板, 但是可以访问现有的其他文件(除非被.helmignore
排除在外)。 使用{{ index .Files "file.name" }}
可以访问文件或者使用{{.Files.Get name }}
功能。 您也可以使用{{ .Files.GetBytes }}
作为[]byte访问文件内容。
Capabilities
: 包含了Kubernetes版本信息的类图对象。({{ .Capabilities.KubeVersion }}
) 和支持的Kubernetes API 版本({{ .Capabilities.APIVersions.Has "batch/v1" }}
)
注意: 任何未知的Chart.yaml字段会被抛弃。在Chart对象中无法访问。因此, Chart.yaml不能用于将任意结构的数据传递到模板中。不过values文件可用于此。
values.yaml 文件说明 考虑到前面部分的模板,values.yam
文件提供的必要值如下:
1 2 3 4 imageRegistry: "quay.io/deis" dockerTag: "latest" pullPolicy: "Always" storage: "s3"
基于 Helm 部署应用 创建文件 首先初始化以下文件结构:
1 2 3 4 5 $ mkdir -p /helm_data && cd /helm_data $ helm create kelvyn-chart $ cd kelvyn-chart/templates/ $ rm -rf *.yaml tests
Chart.yaml
1 2 3 4 5 6 7 apiVersion: v2 name: kelvyn-chart description: Kelvyn Nginx Demo Chart. type: application version: 0.1 .0 appVersion: "1.16.0"
values.yaml
1 2 3 4 5 6 7 8 9 10 11 12 podLabel: key: app value: nginx-deploy replicas: 2 images: image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx imageTag: 1.27 .3 -alpine imagePullPolicy: IfNotPresent service: type: NodePort nodePort: 30060
templates/nginx-deployment.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deploy namespace: kelvyn-helm spec: replicas: {{ .Values.replicas }} selector: matchLabels: {{ .Values.podLabel.key }}: {{ .Values.podLabel.value }} template: metadata: name: nginx labels: {{ .Values.podLabel.key }}: {{ .Values.podLabel.value }} spec: containers: - name: nginx image: {{ .Values.images.image }}:{{ .Values.images.imageTag }} imagePullPolicy: {{ .Values.images.imagePullPolicy }} args: ["sh" , "-c" , "echo 111 >> /usr/share/nginx/html/index.html && nginx -g 'daemon off;'" ] ports: - containerPort: 80 protocol: TCP resources: limits: cpu: 100m memory: 100Mi requests: cpu: 100m memory: 100Mi
templates/nginx-service.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion: v1 kind: Service metadata: name: nginx-deploysvc namespace: kelvyn-helm spec: type: {{ .Values.service.type }} ports: - port: 80 targetPort: 80 nodePort: {{ .Values.service.nodePort }} selector: {{ .Values.podLabel.key }}: {{ .Values.podLabel.value }}
templates/NOTES.txt
1 This is Kelvyn's Test Helm Package, Welcome to Test!!!
最后目录结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 $ tree . ├── charts ├── Chart.yaml ├── templates │ ├── _helpers.tpl │ ├── nginx-deployment.yaml │ ├── nginx-service.yaml │ └── NOTES.txt └── values.yaml 2 directories, 6 files
使用 Helm Cli 部署应用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 $ kubectl create ns kelvyn-helm $ helm install kelvyn-nginx /helm_data/kelvyn-chart/ -n kelvyn-helm $ helm list -n kelvyn-helm $ kubectl -n kelvyn-helm get all $ helm uninstall kelvyn-nginx -n kelvyn-helm
在 helm install
阶段,可以使用参数 --dry-run
进行测试安装
使用了”–dry-run”选项并未真正部署!它会列出要执行的yaml文件内容!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 $ helm install kelvyn-nginx /helm_data/kelvyn-chart/ -n kelvyn-helm --dry-run NAME: kelvyn-nginx LAST DEPLOYED: Sun Feb 23 20:51:01 2025 NAMESPACE: kelvyn-helm STATUS: pending-install REVISION: 1 TEST SUITE: None HOOKS: MANIFEST: --- apiVersion: v1 kind: Service metadata: name: nginx-deploysvc namespace: kelvyn-helm spec: type : NodePort ports: - port: 80 targetPort: 80 nodePort: 30060 selector: app: nginx-deploy --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deploy namespace: kelvyn-helm spec: replicas: 2 selector: matchLabels: app: nginx-deploy template: metadata: name: nginx labels: app: nginx-deploy spec: containers: - name: nginx image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.3-alpine imagePullPolicy: IfNotPresent args: ["sh" , "-c" , "echo 111 >> /usr/share/nginx/html/index.html && nginx -g 'daemon off;'" ] ports: - containerPort: 80 protocol: TCP resources: limits: cpu: 100m memory: 100Mi requests: cpu: 100m memory: 100Mi NOTES: This is Kelvyn's Test Helm Package, Welcome to Test!!!
基于 Helm 升级 Chart 的 Release
概述 1 2 3 4 5 6 7 8 9 为了实现Chart复用,可动态传参修改"values.yaml"文件中的变量值,有以下两种方式: --values,-f: 基于yaml配置文件方式升级Release。 例如:"helm upgrade -f /oldboyedu/data/oldboyedu-nginx/values.yaml myweb02 /oldboyedu/data/oldboyedu-nginx" --set: 基于命令行方式升级Release。例如:"helm upgrade --set imageTag=1.18 myweb02 /oldboyedu/data/oldboyedu-nginx" 如下图所示,对比了基于yaml配置文件和基于命令行方式升级Release的差别。
基于配置文件升级 helm upgrade
使用 -f
参数升级:
可以多次指定’–values’/‘-f’参数,最后(最右边)指定的文件优先级最高。比如如果myvalues.yaml和override.yaml同时包含了名为 ‘Test’的key,override.yaml中的设置会优先使用:
$ helm upgrade -f myvalues.yaml -f override.yaml redis ./redis
实战:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 $ helm history kelvyn-nginx -n kelvyn-helm REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION 1 Sun Feb 23 21:00:50 2025 deployed kelvyn-chart-0.1.0 1.16.0 Install complete $ kubectl -n kelvyn-helm get svc nginx-deploysvc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-deploysvc NodePort 10.98.56.127 <none> 80:30060/TCP 16m $ curl -I 10.98.56.127 HTTP/1.1 200 OK Server: nginx/1.27.3 Date: Sun, 23 Feb 2025 13:17:21 GMT Content-Type: text/html Content-Length: 619 Last-Modified: Sun, 23 Feb 2025 13:00:51 GMT Connection: keep-alive ETag: "67bb1c03-26b" Accept-Ranges: bytes $ sed -i 's/1.27.3-alpine/1.27.4-alpine/' /root/helm/kelvyn-chart/values.yaml $ helm upgrade -f /root/helm/kelvyn-chart/values.yaml kelvyn-nginx /root/helm/kelvyn-chart/ -n kelvyn-helm $ helm history kelvyn-nginx -n kelvyn-helm REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION 1 Sun Feb 23 21:37:03 2025 superseded kelvyn-chart-0.1.0 1.16.0 Install complete 2 Sun Feb 23 21:38:37 2025 deployed kelvyn-chart-0.1.0 1.16.0 Upgrade complete $ curl -I 10.98.56.127 HTTP/1.1 200 OK Server: nginx/1.27.4 Date: Sun, 23 Feb 2025 13:41:30 GMT Content-Type: text/html Content-Length: 619 Last-Modified: Sun, 23 Feb 2025 13:38:40 GMT Connection: keep-alive ETag: "67bb24e0-26b" Accept-Ranges: bytes
基于命令行升级 以多次指定’–set’参数,最后(最右边)指定的优先级最高。比如’bar’ 和 ‘newbar’都设置了一个名为’foo’的可以, ‘newbar’的值会优先使用:
$ helm upgrade --set foo=bar --set foo=newbar redis ./redis
实战:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ helm upgrade --set images.imageTag=1.27.4-alpine,replicas=1 kelvyn-nginx ./kelvyn-chart/ -n kelvyn-helm $ curl -I 10.98.56.127 HTTP/1.1 200 OK Server: nginx/1.27.4 Date: Sun, 23 Feb 2025 13:41:30 GMT Content-Type: text/html Content-Length: 619 Last-Modified: Sun, 23 Feb 2025 13:38:40 GMT Connection: keep-alive ETag: "67bb24e0-26b" Accept-Ranges: bytes $ kubectl -n kelvyn-helm get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy-689f6b998b-87m5f 1/1 Running 0 2m8s 10.244.2.57 worker02 <none> <none>
基于 Helm 回滚应用版本 回滚到上一个版本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $ helm history kelvyn-nginx -n kelvyn-helm REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION 1 Sun Feb 23 21:53:34 2025 superseded kelvyn-chart-0.1.0 1.16.0 Install complete 2 Sun Feb 23 21:55:06 2025 superseded kelvyn-chart-0.1.0 1.16.0 Upgrade complete 3 Sun Feb 23 21:57:11 2025 deployed kelvyn-chart-0.1.0 1.16.0 Upgrade complete $ helm rollback kelvyn-nginx -n kelvyn-helm Rollback was a success! Happy Helming! $ helm history kelvyn-nginx -n kelvyn-helm REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION 1 Sun Feb 23 21:53:34 2025 superseded kelvyn-chart-0.1.0 1.16.0 Install complete 2 Sun Feb 23 21:55:06 2025 superseded kelvyn-chart-0.1.0 1.16.0 Upgrade complete 3 Sun Feb 23 21:57:11 2025 superseded kelvyn-chart-0.1.0 1.16.0 Upgrade complete 4 Sun Feb 23 22:01:35 2025 deployed kelvyn-chart-0.1.0 1.16.0 Rollback to 2
回滚到指定版本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $ helm history kelvyn-nginx -n kelvyn-helm REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION 1 Sun Feb 23 21:53:34 2025 superseded kelvyn-chart-0.1.0 1.16.0 Install complete 2 Sun Feb 23 21:55:06 2025 superseded kelvyn-chart-0.1.0 1.16.0 Upgrade complete 3 Sun Feb 23 21:57:11 2025 superseded kelvyn-chart-0.1.0 1.16.0 Upgrade complete 4 Sun Feb 23 22:01:35 2025 deployed kelvyn-chart-0.1.0 1.16.0 Rollback to 2 $ helm rollback kelvyn-nginx 1 -n kelvyn-helm Rollback was a success! Happy Helming! $ helm history kelvyn-nginx -n kelvyn-helm REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION 1 Sun Feb 23 21:53:34 2025 superseded kelvyn-chart-0.1.0 1.16.0 Install complete 2 Sun Feb 23 21:55:06 2025 superseded kelvyn-chart-0.1.0 1.16.0 Upgrade complete 3 Sun Feb 23 21:57:11 2025 superseded kelvyn-chart-0.1.0 1.16.0 Upgrade complete 4 Sun Feb 23 22:01:35 2025 superseded kelvyn-chart-0.1.0 1.16.0 Rollback to 2 5 Sun Feb 23 22:06:13 2025 deployed kelvyn-chart-0.1.0 1.16.0 Rollback to 1
公有仓库管理及使用 主流仓库 1 2 3 4 5 6 7 8 9 10 11 12 国内仓库: - 微软巨硬: https://mirror.azure.cn/kubernetes/charts/ - 阿里云仓库: https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts 当然还有一些其他搭建的用户较小的仓库,比如: - helm-charts.itboon.top: https://helm-charts.itboon.top/docs/ - https://charts.ost.ai/ https://charts.ost.ai
仓库管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ helm repo list $ helm repo add azure https://mirror.azure.cn/kubernetes/charts $ helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts $ helm repo update $ helm repo update aliyun $ helm search repo mysql $ helm search repo aliyun $ helm repo remove azure
实战练习 使用 Helm 公有仓库部署一个 MySQL :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 $ helm search repo mysql $ helm pull aliyun/mysql --untar $ tree mysql/ mysql/ ├── Chart.yaml ├── README.md ├── templates │ ├── configmap.yaml │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── NOTES.txt │ ├── pvc.yaml │ ├── secrets.yaml │ └── svc.yaml └── values.yaml $ sed -i "s/extensions\/v1beta1/apps\/v1/" ./mysql/templates/deployment.yaml $ sed -i '10a\ selector:\ matchLabels:\ app: {{ template "mysql.fullname" . }}' ./mysql/templates/deployment.yamlcat > ./mysql/templates/pv.yaml << EOF apiVersion: v1 kind: PersistentVolume metadata: name: kelvyn-mysql-helm-pv spec: capacity: storage: 10Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle hostPath: path: "/tmp/kelvyn-mysql" EOF $ helm install kelvyn-mysql mysql/ -n kelvyn-mysql-helm --create-namespace $ kubectl get pods -o wide $ mysql -h 10.244.1.35 -p`kubectl get secret --namespace default kelvyn-mysql-mysql -o jsonpath="{.data.mysql-root-password}" | base64 -d`
还得记得注意,修改文件 values.yaml 中的 image 值 !!!!!!
私有仓库搭建及使用 使用 docker 部署 ChartMuseum 私有 Chart 仓库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $ mkdir -p /data/chartmuseum $ docker run -d \ -p 8090:8080 \ -e DEBUG=1 \ -e STORAGE=local \ -e STORAGE_LOCAL_ROOTDIR=/charts \ -v /data/chartmuseum:/charts \ --restart=always \ swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/helm/chartmuseum:v0.16.2 $ curl http://192.168.1.51:8090/api/charts $ curl http://192.168.1.51:8090/ $ chmod 777 /data/chartmuseum
下载公有仓库的 Chart 至私有仓库 1 2 3 4 5 6 7 8 cd /data/chartmuseum$ helm pull azure/mysql $ helm pull azure/redis curl http://192.168.1.51:8090/api/charts | jq .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 { "mysql" : [ { "name" : "mysql" , "home" : "https://www.mysql.com/" , "sources" : [ "https://github.com/kubernetes/charts" , "https://github.com/docker-library/mysql" ] , "version" : "1.6.9" , "description" : "DEPRECATED - Fast, reliable, scalable, and easy to use open-source relational database system." , "keywords" : [ "mysql" , "database" , "sql" ] , "icon" : "https://www.mysql.com/common/logos/logo-mysql-170x115.png" , "apiVersion" : "v1" , "appVersion" : "5.7.30" , "deprecated" : true , "urls" : [ "charts/mysql-1.6.9.tgz" ] , "created" : "2025-02-24T07:40:46.457698552Z" , "digest" : "35f232f0b4df50e85c6d65cbe7e5291b8ac8fab2c5a6afa8a0b816c7ce594390" } ] } , ...
打包自定义的 Chart 1 2 3 4 5 6 $ helm package kelvyn-chart/ $ helm repo add chartmuseum http://192.168.1.51:8090/
使用插件 cm-push 推送自定义的 Chart https://github.com/chartmuseum/helm-push
1 2 3 4 5 6 7 8 9 10 $ dnf install -y git $ helm plugin install https://github.com/chartmuseum/helm-push $ helm cm-push kelvyn-chart-0.1.0.tgz chartmuseum Pushing kelvyn-chart-0.1.0.tgz to chartmuseum... Done.