010-Kubernetes Helm

一、引言

没有使用 Helm 之前,在 Kubernetes 部署应用,我们要依次部署 deployment、service 等,步骤比较繁琐。况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂。

helm 通过打包的方式,支持发布的版本管理和控制,很大程度上简化了 Kubernetes 应用的部署和管理。Helm 本质就是让 k8s 的应用管理(Deployment、Service等)可配置,能动态生成。通过动态生成K8S资源清单文件(deployment.yaml、service.yaml)。然后 kubectl 自动调用 K8S 资源部署。

官网:Helm

Helm 具备如下的能力:

  • 简化部署 :Helm允许使用单个命令轻松部署和管理应用程序,从而简化了整个部署过程;
  • 高度可配置:Helm Charts提供了高度可配置的选项,可以轻松自定义和修改应用程序的部署配置;
  • 版本控制 :Helm允许管理应用程序的多个版本,从而轻松实现版本控制和回滚;
  • 模板化:Helm Charts使用YAML模板来定义Kubernetes对象的配置,从而简化了配置过程,并提高了可重复性和可扩展性;
  • 应用程序库:Helm具有应用程序库的概念,可以轻松地共享和重用Helm Charts,从而简化了多个应用程序的部署和管理;
  • 插件系统:Helm拥有一个强大的插件系统,允许您扩展和定制Helm的功能,以满足特定的需求和要求。

二、Helm V2 与 V3 的区别

Helm v2 是 C/S 架构,主要分为客户端 helm 和服务器端 tiller。而由于 RBAC 等权限控制体系的逐渐完善,多租户和安全的需求日益兴起,tiller 变得越来越不安全,社区在权限控制领域遇到了极大的阻碍。所以在 Helm3 版本中,直接将 tiller 这一核心组件移除,helm 直接和 kubernetes API 进行通信。直接带来的好处如下:

  • Helm 的架构变的更为简单和灵活
  • 不再需要创建 ServiceAccount,直接使用当前环境中的 kubeconfig 配置
  • 可以直接和 kubernetes API 交互,更为安全
  • 不再需要使用 helm init 来进行初始化

三、Helm工作流程

以下是Helm的工作流程(注意:这里使用的是Helm的v3版本,该版本没有了tiller并并使用更加简单和灵活的架构,直接通过 kubeconfig 连接 apiserver ,简化安全模块,降低了用户的使用壁垒):

Helm工作流程

如上图所示,Helm的工作流程总结如下:

  1. 开发者首先创建并编辑 chart 的配置;
  2. 接着打包并发布至 Helm 的仓库(Repository);
  3. 当管理员使用 helm 命令安装时,相关的依赖会从仓库下载;
  4. 接着helm 会根据下载的配置部署资源至 k8s ;

四、Helm概念

在使用Helm的过程中,需要理解如下的几个核心的概念:

概念 描述
Chart 一个 Helm 包,其中包含了运行一个应用所需要的镜像、依赖和资源定义等,还可能包含 Kubernetes 集群中的服务定义,类似 Homebrew 中的 formula、APT 的 dpkg 或者 Yum 的 rpm 文件
Repository 存储 Helm Charts 的地方
Release Chart 在 k8s上运行的 Chart 的一个实例,例如,如果一个 MySQL Chart 想在服务器上运行两个数据库,可以将这个 Chart 安装两次,并在每次安装中生成自己的 Release 以及 Release 名称。
Value Helm Chart 的参数,用于配置 Kubernetes 对象
Template 使用 Go 模板语言生成 Kubernetes 对象的定义文件
Namespace Kubernetes 中用于隔离资源的逻辑分区

五、Helm的使用

1. 安装Helm

参考官方文档:安装Helm

1.1 用二进制版本安装

下载二进制安装包

下载地址:https://github.com/helm/helm/releases

解压二进制包

$ tar -zxvf helm-v3.12.3-linux-amd64.tar.gz

将二进制文件移动到对应的目录中

$ mv linux-amd64/helm /usr/local/bin/helm

测试

# 查看Helm版本
$ helm version
version.BuildInfo{Version:"v3.12.3", GitCommit:"3a31588ad33fe3b89af5a2a54ee1d25bfe6eaa5e", GitTreeState:"clean", GoVersion:"go1.20.7"}

1.2 使用脚本安装

Helm现在有个安装脚本可以自动拉取最新的Helm版本并在 本地安装

# 在线安装脚本
$ 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

2. Helm 初始化

当您已经安装好了Helm之后,您可以添加一个 chart 仓库。从 Artifact Hub 中查找有效的 Helm chart 仓库

$ helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories

当添加完成,您将可以看到可以被您安装的 charts 列表:

$ helm search repo bitnami
NAME                                        	CHART VERSION	APP VERSION  	DESCRIPTION                                       
bitnami/airflow                             	24.1.4       	3.0.2        	Apache Airflow is a tool to express and execute...
bitnami/apache                              	11.3.16      	2.4.63       	Apache HTTP Server is an open-source HTTP serve...
bitnami/apisix                              	5.0.3        	3.12.0       	Apache APISIX is high-performance, real-time AP...
bitnami/appsmith                            	6.0.11       	1.77.0       	Appsmith is an open source platform for buildin...
bitnami/argo-cd                             	9.0.22       	3.0.9        	Argo CD is a continuous delivery tool for Kuber...

3. Helm 仓库管理

3.1 添加仓库

# 添加 bitnami 仓库
$ helm repo add bitnami https://charts.bitnami.com/bitnami

# 添加阿里云仓库
$ helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

# 添加微软仓库
$ helm repo add ms http://mirror.azure.cn/kubernetes/charts/

3.2 查看仓库

$ helm repo list
NAME   	URL                                                   
bitnami	https://charts.bitnami.com/bitnami                    
aliyun 	https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
ms     	http://mirror.azure.cn/kubernetes/charts/

3.3 更新仓库索引

$ helm repo update

3.4 删除仓库

$ helm repo remove [仓库名称]

3.5 在仓库中搜索 Chart 应用

# 只在 ms 仓库搜索应用
$ helm search repo ms/redis

# 在添加的所有仓库搜索应用
$ helm search repo redis

3.6 查看指定仓库中Chart的版本

helm search repo [chart名称] --versions

$ helm search repo ms/redis --versions
NAME       	CHART VERSION	APP VERSION    	DESCRIPTION                                       
ms/redis   	10.5.7       	5.0.7          	DEPRECATED Open source, advanced key-value stor...
ms/redis   	9.5.4        	5.0.6          	Open source, advanced key-value store. It is of...
ms/redis   	9.5.3        	5.0.6          	Open source, advanced key-value store. It is of...
ms/redis   	9.5.2        	5.0.5          	Open source, advanced key-value store. It is of...

3.7 拉取远程仓库的 Chart

# 语法,--version对应的是chart version,--untar自动解压,
# --destination:指定下载的 Chart 文件(.tgz)保存的目标目录(默认当前目录)。
# --repo [仓库URL]	直接从指定 URL 下载 Chart,而不使用已添加的仓库名称。
helm pull [chart名出] --version [版本号] --untar --destination [/path] --repo [仓库URL]
 
# 示例
$ helm pull ms/redis --version 10.5.7
$ ll
-rw-r--r-- 1 root root      31909 Jun 22 15:52 redis-10.5.7.tgz

4. 安装 chart 示例

4.1 在线安装

# 更新 charts 列表
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈

# 显示 Bitnami 提供的 Apache Helm chart 的默认配置文件(values.yaml)内容
$ helm show values bitnami/apache

# 在 Kubernetes 集群中安装 Bitnami 提供的 Apache Helm chart,并自动生成一个唯一的 release 名称
$ helm install bitnami/apache --generate-name

上面的操作用的 chart 源是 bitnami , 而 bitnami 服务器在国外,国内无法访问,我尝试服务器翻墙,依然报错,错误信息如下:

$ helm install my-apache bitnami/apache --version 11.3.16
Error: INSTALLATION FAILED: failed to do request: Head "https://registry-1.docker.io/v2/bitnamicharts/apache/manifests/11.3.16": dial tcp: lookup registry-1.docker.io: i/o timeout

4.2 离线安装

# 下载chart安装包
wget https://charts.bitnami.com/bitnami/apache-11.3.16.tgz

# 解压
tar -zxvf apache-11.3.16.tgz 

# 进入解压后的chart目录
cd apache

# 安装Chart,运行生成一个Release
# 方式一:使用解压后的chart安装, . 表示当前解压的目录
$ helm install my-apache .
# 方式二:直接使用下载的 chart 压缩包安装
helm install my-apache apache-11.3.16.tgz

# 查看Release实例
$ helm list -n default
NAME     	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART         	APP VERSION
my-apache	default  	1       	2025-06-22 14:05:26.557276416 +0800 CST	deployed	apache-11.3.16	2.4.63

查看运行的Pod

# 查看运行的Service
$ kubectl get svc -o wide
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE    SELECTOR
kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP                      54d    <none>
my-apache    LoadBalancer   10.108.203.41   <pending>     80:31349/TCP,443:32630/TCP   105s   app.kubernetes.io/instance=my-apache,app.kubernetes.io/name=apache

# 查看Deployment
$ kubectl get deployment -o wide
NAME        READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES                                          SELECTOR
my-apache   0/1     1            0           112s   apache       docker.io/bitnami/apache:2.4.63-debian-12-r16   app.kubernetes.io/instance=my-apache,app.kubernetes.io/name=apache

# 查看Pod
$ kubectl get pods -o wide
NAME                         READY   STATUS              RESTARTS   AGE    IP              NODE         NOMINATED NODE   READINESS GATES
my-apache-74b6d9f88b-lknsr   0/1     Init:ErrImagePull   0          114s   172.16.58.254   k8s-node02   <none>           <none>

Pod未能运行成功,查找原因

$ kubectl describe pod my-apache-74b6d9f88b-lknsr
Name:             my-apache-74b6d9f88b-lknsr
Namespace:        default
Priority:         0
Service Account:  my-apache
Node:             k8s-node02/192.168.6.141
......
......
Events:
  Type     Reason     Age                    From               Message
  ----     ------     ----                   ----               -------
  Normal   Scheduled  6m39s                  default-scheduler  Successfully assigned default/my-apache-74b6d9f88b-lknsr to k8s-node02
  Warning  Failed     5m51s (x2 over 6m21s)  kubelet            Failed to pull image "docker.io/bitnami/apache:2.4.63-debian-12-r16": Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
  Warning  Failed     5m10s                  kubelet            Failed to pull image "docker.io/bitnami/apache:2.4.63-debian-12-r16": Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded
  Normal   Pulling    4m17s (x4 over 6m36s)  kubelet            Pulling image "docker.io/bitnami/apache:2.4.63-debian-12-r16"
  Warning  Failed     4m1s (x4 over 6m21s)   kubelet            Error: ErrImagePull
  Warning  Failed     4m1s                   kubelet            Failed to pull image "docker.io/bitnami/apache:2.4.63-debian-12-r16": Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
  Warning  Failed     3m46s (x6 over 6m20s)  kubelet            Error: ImagePullBackOff
  Normal   BackOff    91s (x14 over 6m20s)   kubelet            Back-off pulling image "docker.io/bitnami/apache:2.4.63-debian-12-r16"

原因:镜像 docker.io/bitnami/apache:2.4.63-debian-12-r16 拉取失败,可以通过修改 chart 解压路径中的 value.yaml 文件,将镜像替换成国内的镜像即可。

也可以添加国内的阿里云 chart 仓库,地址:https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts (chart包没有官网那么全),

还有微软的chart 仓库地址http://mirror.azure.cn/kubernetes/charts/ (官网有的,它大多都有, 推荐使用

$ helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
$ helm repo add ms http://mirror.azure.cn/kubernetes/charts/

$ helm repo update

$ helm search repo ms

# 显示 微软 提供的 Apache Helm chart 的默认配置文件(values.yaml)内容
$ helm show values ms/redis

# 在 Kubernetes 集群中安装 Bitnami 提供的 Apache Helm chart,并自动生成一个唯一的 release 名称
$ helm install ms/redis --generate-name

4.3 Chart 安装资源顺序

Namespace	>	NetworkPolicy	>	ResourceQuota	>	LimitRange	>	PodSecurityPolicy	>	PodDisruptionBudget	>	ServiceAccount	>	Secret	>	SecretList	>	ConfigMap	>	StorageClass
PersistentVolume	>	PersistentVolumeClaim	>	CustomResourceDefinition	>	ClusterRole
ClusterRoleList	>	ClusterRoleBinding	>	ClusterRoleBindingList	>	Role	>	RoleList
RoleBinding	>	RoleBindingList	>	Service	>	DaemonSet	>	Pod	>	ReplicationController	>	ReplicaSet	>	Deployment	>	HorizontalPodAutoscaler	>	StatefulSet	>	Job	>	CronJob	>	Ingress	>	APIService

4.4 安装过程中有两种方式传递配置数据

  • --values (或 -f):使用 YAML 文件覆盖配置。可以指定多次,优先使用最右边的文件
  • --set:通过命令行的方式对指定项进行覆盖

如果同时使用两种方式,则 --set 中的值会被合并到 --values 中,但是 --set 中的值优先级更高。在--set 中覆盖的内容会被被保存在 ConfigMap 中。可以通过 helm get values <release-name> 来查看指定 release 中 --set 设置的值。也可以通过运行 helm upgrade 并指定 --reset-values 字段来清除 --set 中设置的值

4.4.1 --set 的格式和限制

--set 选项使用0或多个 name/value 对。最简单的用法类似于: --set name=value ,等价于如下 YAML 格式:

name: value

多个值使用逗号分割,因此 --set a=b,c=d 的 YAML 表示是:

a: b
c: d

支持更复杂的表达式。例如,--set outer.inner=value 被转换成了:

outer:
  inner: value

列表使用花括号({})来表示。例如,--set name={a, b, c} 被转换成了:

name:
  - a
  - b
  - c

某些 name/key 可以设置为 null 或者空数组,例如 --set name=[],a=null

name: []
a: null

从 2.5.0 版本开始,可以使用数组下标的语法来访问列表中的元素。例如 --set servers[0].port=80 就变成了:

servers:
  - port: 80

多个值也可以通过这种方式来设置。--set servers[0].port=80,servers[0].host=example 变成了:

servers:
  - port: 80
    host: example

如果需要在 --set 中使用特殊字符,你可以使用反斜线来进行转义;--set name=value1\,value2 就变成了:

name: "value1,value2"

–set nodeSelector.”kubernetes.io/role”=master

nodeSelector:
  kubernetes.io/role: master

4.5 安装、升级、回滚时的有用选项

  • –timeout:一个 Go duration 类型的值, 用来表示等待 Kubernetes 命令完成的超时时间,默认值为 5m0s。such as “300ms”, “-1.5h” or “2h45m”. Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”。
  • –wait:表示必须要等到所有的 Pods 都处于 ready 状态,PVC 都被绑定,Deployments 都至少拥有最小 ready 状态 Pods 个数(Desired 减去 maxUnavailable ),并且 Services 都具有 IP 地址(如果是 LoadBalancer, 则为 Ingress ),才会标记该 release 为成功。最长等待时间由 –timeout 值指定。如果达到超时时间,release 将被标记为 FAILED。注意:当 Deployment 的 replicas 被设置为1,但其滚动升级策略中的 maxUnavailable 没有被设置为0时,–wait 将返回就绪,因为已经满足了最小 ready Pod 数
  • --no-hooks:不运行当前命令的钩子,即为安装此 chart 时的已定义的安装前或者安装后的动作
  • –recreate-pods:(仅适用于 upgraderollback):这个参数会导致重建所有的 Pod(deployment 中的 Pod 除外)。(在 Helm 3 中已被废弃)

5. 卸载Chart应用

卸载一个已安装的 Release 实例

# 查看当前运行的 release 
$ helm list
NAME            	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART         	APP VERSION
chart-1750577584	default  	1       	2025-06-22 15:33:04.623161176 +0800 CST	deployed	apache-11.3.16	2.4.63

# 卸载应用
$ helm uninstall chart-1750577584

# 再次查看 release ,应用已卸载
$ helm list
NAME	NAMESPACE	REVISION	UPDATED	STATUS	CHART	APP VERSION

六、案例-安装Nginx

1. 下载 Nginx Chart 安装包

# 搜索要下载的 Chart 版本
$ helm search repo bitnami/nginx --versions
NAME                            	CHART VERSION	APP VERSION	DESCRIPTION                                       
bitnami/nginx                   	20.1.3       	1.28.0     	NGINX Open Source is a web server that can be a...
bitnami/nginx                   	20.1.2       	1.28.0     	NGINX Open Source is a web server that can be a...

# 使用 pull 拉取Chart, 失败
$ helm pull bitnami/nginx --version 20.1.3
Error: failed to do request: Head "https://registry-1.docker.io/v2/bitnamicharts/nginx/manifests/20.1.3": dial tcp 199.59.148.202:443: i/o timeout

# 使用 wget 命令下载安装包,成功
$ wget https://charts.bitnami.com/bitnami/nginx-20.1.3.tgz

2. 安装 Nginx Chart

# 执行命令,根据Chart压缩包创建实例,生成 svc、deployment、pod
$ helm install my-nginx nginx-20.1.3.tgz \
	--set service.type=NodePort \
	--set service.nodePorts.http=30003 \
    --namespace default --create-namespace
    
    
# --set service.type=NodePort  手动设置Service类型为NodePort,模板文件 values.yaml 中默认为 LoadBalance
# --set service.nodePorts.http=30003 手动设置NodePort端口,模板文件中默认为空,自动生成端口
# --namespace default --create-namespace 指定 Pod、SVC、Deployment 所在的工作空间,不存在则创建

由于模板文件中的镜像默认都从 docker hub 下载,国内存在网络限制,在执行下面的命令前,先将镜像下载下来,导入到集群的 Node 节点。

关于如下下载外网镜像,参考这篇博客:Docker配置网络代理实现外网镜像下载

查看结果:

# 查看 Release
$ helm list
NAME    	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART       	APP VERSION
my-nginx	default  	1       	2025-06-22 16:57:21.546051288 +0800 CST	deployed	nginx-20.1.3	1.28.0

# 查看 SVC
$ kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE   SELECTOR
my-nginx     NodePort    10.105.158.179   <none>        80:30003/TCP,443:31458/TCP   12m   app.kubernetes.io/instance=my-nginx,app.kubernetes.io/name=nginx

# 查看 Deploy
$ kubectl get deploy -o wide
NAME       READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                                        SELECTOR
my-nginx   1/1     1            1           12m   nginx        docker.io/bitnami/nginx:1.28.0-debian-12-r3   app.kubernetes.io/instance=my-nginx,app.kubernetes.io/name=nginx

# 查看 Pod
$ kubectl get pod -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
my-nginx-58cf875b74-tp8ct   1/1     Running   0          13m   172.16.58.223   k8s-node02   <none>           <none>

浏览器访问 SVC

Helm 安装 Nginx

3. 更新Chart

# 更新 Realse , 将Pod 副本数从 1 变成 3
$ helm upgrade my-nginx nginx-20.1.3.tgz --set replicaCount=3

# 再次查看 Realse
# 版本号REVISION 更新了,从 1 变成了 2
$ helm list
NAME    	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART       	APP VERSION
my-nginx	default  	2       	2025-06-22 17:24:48.296877982 +0800 CST	deployed	nginx-20.1.3	1.28.0

# 查看 Pod
$ kubectl get pods -o wide
NAME                        READY   STATUS    RESTARTS   AGE     IP              NODE         NOMINATED NODE   READINESS GATES
my-nginx-58cf875b74-gszn4   1/1     Running   0          2m54s   172.16.58.208   k8s-node02   <none>           <none>
my-nginx-58cf875b74-q76q6   1/1     Running   0          17s     172.16.58.210   k8s-node02   <none>           <none>
my-nginx-58cf875b74-zgbtp   1/1     Running   0          2m42s   172.16.85.193   k8s-node01   <none>           <none>

4. 卸载Nginx

$ helm uninstall my-nginx

七、Helm 常用命令

1. Repository 相关命令

见本文 helm的使用 / Helm 仓库管理

2. Chart 相关命令

2.1 helm create

该命令用于创建一个新的 Chart 目录:

$ helm create demo
Creating demo

创建的 Chart 目录是下面这样的结构:

$ tree demo
demo
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

3 directories, 10 files

2.2 helm package

将 Chart 目录(必须包含 Chart.yaml 文件)打包成 Chart 归档文件:

$ helm package demo
Successfully packaged chart and saved it to: /opt/k8s/10/demo-0.1.0.tgz

2.3 helm lint

验证 Chart 是否存在问题:

$ helm lint ./demo
==> Linting ./demo
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

2.4 helm show

该命令用于显示 Chart 的基本信息,包括:

  • helm show chart - 显示 Chart 定义,实际上就是 Chart.yaml 文件的内容
  • helm show crds - 显示 Chart 的 CRD
  • helm show readme - 显示 Chart 的 README.md 文件中的内容
  • helm show values - 显示 Chart 的 values.yaml 文件中的内容
  • helm show all - 显示 Chart 的所有信息
$ helm show chart demo-0.1.0.tgz
$ helm show values demo-0.1.0.tgz

2.5 helm pull

从仓库中将 Chart 安装包下载到本地:

$ helm pull bitnami/nginx
$ ls
nginx-13.2.23.tgz

2.6 helm push

将 Chart 安装包推送到远程仓库:

$ helm push [chart] [remote]

3. Release 相关命令

3.1 helm install

将 Chart 安装到 Kubernetes 集群:

$ helm install my-nginx bitnami/nginx --version 20.1.3

安装时可以通过 --set 选项修改配置参数:

$ helm install my-nginx bitnami/nginx --version 20.1.3 \
    --set service.ports.http=8080

其中 bitnami/nginx 是要安装的 Chart,这种写法是最常用的格式,被称为 Chart 引用,一共有六种不同的 Chart 写法:

  • 通过 Chart 引用:helm install my-nginx bitnami/nginx
  • 通过 Chart 包:helm install my-nginx ./nginx-13.2.23.tgz
  • 通过未打包的 Chart 目录:helm install my-nginx ./nginx
  • 通过 Chart URL:helm install my-nginx https://example.com/charts/nginx-13.2.23.tgz
  • 通过仓库 URL 和 Chart 引用:helm install --repo https://example.com/charts/ my-nginx nginx
  • 通过 OCI 注册中心:helm install my-nginx --version 13.2.23 oci://example.com/charts/nginx

3.2 helm list

显示某个命名空间下的所有 Release:

$ helm list --namespace default
NAME    	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART       	APP VERSION
my-nginx	default  	1       	2025-06-22 17:50:26.273823328 +0800 CST	deployed	nginx-20.1.3	1.28.0

3.3 helm status

查询某个 Release 的状态信息:

$ helm status my-nginx
NAME: my-nginx
LAST DEPLOYED: Sun Jun 22 17:50:26 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: nginx
CHART VERSION: 20.1.3
APP VERSION: 1.28.0

Did you know there are enterprise versions of the Bitnami catalog? For enhanced secure software supply chain features, unlimited pulls from Docker, LTS support, or application customization, see Bitnami Premium or Tanzu Application Catalog. See https://www.arrow.com/globalecs/na/vendors/bitnami for more information.

** Please be patient while the chart is being deployed **
NGINX can be accessed through the following DNS name from within your cluster:

    my-nginx.default.svc.cluster.local (port 80)

3.4 helm get

获取某个 Release 的扩展信息,包括:

  • helm get hooks - 获取 Release 关联的钩子信息
  • helm get manifest - 获取 Release 的清单信息
  • helm get notes - 获取 Release 的注释
  • helm get values - 获取 Release 的 values 文件
  • helm get all - 获取 Release 的所有信息
$ helm get values my-nginx
USER-SUPPLIED VALUES:
service:
  nodePorts:
    http: 30003
  type: NodePort

3.5 helm upgrade

将 Release 升级到新版本的 Chart:

$ helm upgrade my-nginx ./nginx
Release "my-nginx" has been upgraded. Happy Helming!

升级时可以通过 --set 选项修改配置参数:

$ helm upgrade my-nginx ./nginx \
    --set service.ports.http=8080

3.6 helm history

查看某个 Release 的版本记录:

$ helm history my-nginx
REVISION	UPDATED                 	STATUS    	CHART       	APP VERSION	DESCRIPTION     
1       	Sun Jun 22 17:50:26 2025	superseded	nginx-20.1.3	1.28.0     	Install complete
2       	Sun Jun 22 17:55:25 2025	deployed  	nginx-20.1.3	1.28.0     	Upgrade complete

3.7 helm rollback

将 Release 回滚到某个版本:

$ helm rollback my-nginx 1
Rollback was a success! Happy Helming!

再查看版本记录可以看到多了一条记录:

$ helm history my-nginx
REVISION	UPDATED                 	STATUS    	CHART       	APP VERSION	DESCRIPTION     
1       	Sun Jun 22 17:50:26 2025	superseded	nginx-20.1.3	1.28.0     	Install complete
2       	Sun Jun 22 17:55:25 2025	superseded	nginx-20.1.3	1.28.0     	Upgrade complete
3       	Sun Jun 22 17:56:48 2025	deployed  	nginx-20.1.3	1.28.0     	Rollback to 1

3.8 helm uninstall

卸载 Release:

$ helm uninstall my-nginx
release "my-nginx" uninstalled

八、搭建 Chart 私有仓库

1. 创建一个 HTTP Server 作为chart仓库

# 创建挂载目录
$ mkdir -p /var/www/charts

# 拉取 httpd 镜像
$ docker pull httpd:2.4.63

# 启动容器
$ docker run -d -p 8899:80 --name=my-chart --restart=always -v /var/www:/usr/local/apache2/htdocs httpd:2.4.63

浏览器访问 Chart 仓库

Chart 私有仓库

需要注意:

  • 宿主机的/var/www目录需要存在,且有一定的访问权限。
  • 容器内部的 httpd 配置不要和宿主机 8081 端口冲突。
  • 可以添加-v宿主机日志目录:容器日志目录来收集日志。
  • 可以设置时区等参数对容器进行定制。

2. Helm Chart上传到私有仓库

这里为了测试方便,将前面案例中所使用的Chart 安装包:nginx-20.1.3.tgz 解压,然后打包上传到 Chart 私有仓库

# 1.将 nginx 目录打包成tgz文件,用于发布。
$ helm package nginx/
Successfully packaged chart and saved it to: /opt/software/nginx-20.1.3.tgz

# 2.创建文件夹作为chart仓库目录。
$ mkdir myrepo

# 3. 将打包好的chart移动到仓库目录下。
$ mv nginx-20.1.3.tgz myrepo/

# 4. 在myrepo目录生成index.yaml索引文件,用于仓库查询。
$ helm repo index myrepo --url http://192.168.6.203:8899/charts

# 5. 将index和chart复制到Web服务器目录下,提供下载。
$ cd myrepo/
$ scp index.yaml nginx-20.1.3.tgz /var/www/charts

# 6. 在本地Helm中添加这个chart仓库源,名为newrepo。
$ helm repo add newrepo http://192.168.6.203:8899/charts

# 7. 列出已知的仓库列表,确保newrepo添加成功。
$ helm repo list

# 8. 更新本地缓存的仓库index文件。
$ helm repo update

# 9. 在newrepo仓库中搜索 nginx 是否可用。
$ helm search repo newrepo/nginx
NAME         	CHART VERSION	APP VERSION	DESCRIPTION                                       
newrepo/nginx	20.1.3       	1.28.0     	NGINX Open Source is a web server that can be a...

3. 测试私有仓库

# 使用本地仓库的Chart 安装Nginx
$ helm install newrepo/nginx --generate-name

# 查看Release
$ helm list
NAME            	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART       	APP VERSION
nginx-1750588514	default  	1       	2025-06-22 18:35:14.639466957 +0800 CST	deployed	nginx-20.1.3	1.28.0

浏览器查看私有仓库

私有Chart仓库

九、自定义Chart

1. 创建模板

# 创建chart模板
$ helm create myapp

# 查看模板目录结构
$ tree myapp/
myapp/
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

2. 删除多余的文件

# 当前案例比较简单,暂时用不到这些文件,先删除
$ rm -rf templates/_helpers.tpl templates/hpa.yaml templates/ingress.yaml templates/serviceaccount.yaml templates/tests/test-connection.yaml templates/NOTES.txt

3. service.yaml

$ vim service.yaml

apiVersion: v1
kind: Service
metadata:
  name: myapp-test
  labels:
    app: myapp-svc
spec:
  # Service 类型,从 values.yaml 文件取
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }} # Service 端口,从 values.yaml 文件取
      targetPort: 80
      protocol: TCP
      name: 80-80
      nodePort: 30003
  selector:
    app: myapp-test

4. deployment.yaml

$ vim deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myapp-deploy
  name: myapp-deploy
spec:
  replicas: {{ .Values.replicaCount }} # Pod副本数,从 values.yaml 文件取
  selector:
    matchLabels:
      app: myapp-test
  template:
    metadata:
      labels:
        app: myapp-test
    spec:
      containers:
        - name: myapp
          image: wangyanglinux/myapp:v1.0
          imagePullPolicy: {{ .Values.image.pullPolicy }} # 镜像拉取策略,从 values.yaml 文件取

5. values.yaml

$ vim values.yaml

# Pod副本数
replicaCount: 1

image:
  # 镜像拉取策略
  pullPolicy: IfNotPresent

service:
  # Service类型
  type: NodePort
  # service端口
  port: 80

6. Chart.yaml

$ vim Chart.yaml

apiVersion: v2
name: myapp
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"

7. 发布部署

$ helm install myapp myapp/
NAME: myapp
LAST DEPLOYED: Wed Jun 25 12:57:58 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None


# 查看部署的 Release
$ helm list
NAME 	NAMESPACE	REVISION	UPDATED                               	STATUS  	CHART      	APP VERSION
myapp	default  	1       	2025-06-25 12:57:58.07309733 +0800 CST	deployed	myapp-0.1.0	1.16.0

# 查看 Service
$ kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE     SELECTOR
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        57d     <none>
myapp-test   NodePort    10.108.147.243   <none>        80:30003/TCP   3m41s   app=myapp-test

# 查看 Deployment
$ kubectl get deploy -o wide
NAME           READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                     SELECTOR
myapp-deploy   1/1     1            1           4m58s   myapp        wangyanglinux/myapp:v1.0   app=myapp-test

# 查看 Pod
$ kubectl get pod -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP              NODE         NOMINATED NODE   READINESS GATES
myapp-deploy-7ff87cfb6c-nfff4   1/1     Running   0          5m29s   172.16.58.227   k8s-node02   <none>           <none>

浏览器访问 Service

http://192.168.6.139:30003/

访问自定Chart

8. 打包Chart,发布到私有仓库

# 1.将 myapp 目录打包成tgz文件,用于发布。
$ helm package myapp/
Successfully packaged chart and saved it to: /opt/k8s/10/myapp-0.1.0.tgz

# 2.将打包好的压缩包移动到创建的私有仓库目录中(本文第八段有说明)
$ mv myapp-0.1.0.tgz /opt/software/myrepo/

# 3. 在myrepo目录生成index.yaml索引文件,用于仓库查询。
$ $ helm repo index /opt/software/myrepo/ --url http://192.168.6.203:8899/charts

# 4. 将index和chart复制到Web服务器目录下,提供下载。
$ cd /opt/software/myrepo/
$ scp -r ./* root@192.168.6.203:/var/www/charts/

# 5. 在本地Helm中添加这个chart仓库源,名为newrepo。
$ helm repo add newrepo http://192.168.6.203:8899/charts

# 6. 列出已知的仓库列表,确保newrepo添加成功。
$ helm repo list

# 7. 更新本地缓存的仓库index文件。
$ helm repo update

# 8. 在newrepo仓库中搜索 nginx 是否可用。
$ helm search repo newrepo/myapp
NAME         	CHART VERSION	APP VERSION	DESCRIPTION                
newrepo/myapp	0.1.0        	1.16.0     	A Helm chart for Kubernetes

# 9. 从私有仓库拉取chart,并安装到服务器
$ helm install newrepo/myapp --generate-name
NAME: myapp-1750829238
LAST DEPLOYED: Wed Jun 25 13:27:18 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

# 10. 卸载 Chart
$ helm uninstall myapp-1750829238
release "myapp-1750829238" uninstalled

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 george_95@126.com