k8s之Helm详细讲解
1 Helm包管理工具
1.1 Helm的简介
在没使用 helm 之前,向 kubernetes 部署应用,我们要依次部署 deployment、svc 等,步骤较繁琐。 况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂,helm 通过打包的方式,支持发布的版本管理和控制, 很大程度上简化了 Kubernetes 应用的部署和管理。
==Helm 本质就是让 K8s 的应用管理(Deployment、Service 等)可配置,可以通过类似于传递环境变量的方式能动态生成。==通过动态生成 K8s 资源清单文件(deployment.yaml、service.yaml)。然后调用 Kubectl 自动执行 K8s 资源部署。
Helm 是官方提供的类似于 YUM 的包管理器,是部署环境的流程封装。
1.2 Helm 中三个重要的概念
- **Chart:**Helm 的软件包,采用 tar 格式。类似于 APT 的 DEB 包或者 YUM 的 RPM 包,其包含了一组定义 Kubernetes 资源相关的 YAML 文件。
- **Repository(仓库):**Helm 的软件仓库,Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。
- **Release:**使用
helm install
命令在 Kubernetes 集群中部署的 Chart 称为 Release。可以理解为 Helm 使用 Chart 包部署的一个应用实例。一个 chart 通常可以在同一个集群中安装多次。每一次安装都会创建一个新的 release
以 MySQL chart 为例,如果你想在你的集群中运行两个数据库,你可以安装该 chart 两次。每一个数据库都会拥有它自己的 release 和 release name。可以将 release 想象成应用程序发布的版本号。
1.3 Helm3 与 Helm2 的区别
Helmv2是C/S 架构,主要分为客户端helm 和服务器端tiller。而由于 RBAC 等权限控制体系的逐渐完善,多租户和安全的需求日益兴起,tiller变得越来越不安全,社区在权限控制领域遇到了极大的阻碍。所以在Helm3 版本中,直接将tiller 这一核心组件移除,helm 直接和kubernetes API 进行通信。直接带来的好处如下:
- Helm的架构变的更为简单和灵活
- 不再需要创建ServiceAccount,直接使用当前环境中的kubeconfig配置
- 可以直接和kubernetesAPl交互,更为安全
- 不再需要使用helminit来进行初始化
1.4 Helm常用命令
功能分类 | 命令示例 | 使用场景 | 核心参数 |
基础操作 | helm install [RELEASE] [CHART] | 部署应用到 K8s 集群(如 helm install myapp bitnami/nginx ) | -f values.yaml :自定义配置文件 --set key=value :临时覆盖值 --dry-run :模拟安装不执行 |
helm upgrade [RELEASE] [CHART] | 升级应用版本或配置(如 helm upgrade myapp bitnami/nginx --version 15.3.1 ) | --version x.y.z :指定 Chart 版本 --reset-values :重置非默认配置值 | |
helm uninstall [RELEASE] | 卸载应用(如 helm uninstall myapp -n prod ) | --keep-history :保留历史记录 -n NAMESPACE :指定命名空间 | |
Release 管理 | helm list | 查看已部署的应用列表(如 helm ls -a -n dev ) | -a/--all :显示所有状态的 Release -n NAMESPACE :指定命名空间 |
helm status [RELEASE] | 查看应用详细状态(如 helm status myapp -o yaml ) | -o json/yaml :输出 JSON/YAML 格式 | |
helm history [RELEASE] | 查看应用升级 / 回滚历史(如 helm history myapp --max=5 ) | --max=10 :显示最近 10 次历史 | |
helm rollback [RELEASE] [REVISION] | 回滚到指定版本(如 helm rollback myapp 2 ) | ||
Chart 操作 | helm repo add [NAME] [URL] | 添加 Chart 仓库(如 helm repo add bitnami https://charts.bitnami.com/bitnami ) | --username/--password :认证信息 --force-update :强制更新索引 |
helm repo update | 更新本地仓库索引(获取最新 Charts 列表) | ||
helm search repo [KEYWORD] | 搜索仓库中的 Charts(如 helm search repo nginx --versions ) | --version x.y.z :指定版本过滤 -l/--versions :显示所有版本 | |
helm pull [CHART] | 下载 Chart 到本地(如 helm pull bitnami/nginx --untar ) | --untar :解压到当前目录 --destination /path :指定下载路径 | |
配置与调试 | helm show values [CHART] | 查看 Chart 默认配置(如 helm show values bitnami/nginx ) | |
helm template [RELEASE] [CHART] | 本地渲染模板(不部署),用于调试 YAML(如 helm template myapp bitnami/nginx ) | -f values.yaml :自定义配置 --show-only templates/deployment.yaml :仅显示特定模板 | |
helm lint [CHART_DIR] | 检查 Chart 语法和结构(如 helm lint ./mychart ) | ||
插件扩展 | helm plugin install [URL] | 安装插件(如 helm plugin install https://github.com/databus23/helm-diff ) | |
helm plugin list | 列出已安装插件 |
1.5 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
添加chart仓库
当您已经安装好了Helm之后,您可以添加一个chart 仓库。
- 官方仓库:https://charts.bitnami.com/bitnami
- 阿里云:https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
- 微软:http://mirror.azure.cn/kubernetes/charts
# 添加chart仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
# 当添加完成,您将可以看到可以被您安装的 charts 列表
helm search repo bitnami
# 更新charts列表
helm repo update# 查看repo仓库
helm repo ls
# 移除仓库
helm repo remove <仓库名称>
安装chart示例
# 安装一个apache的chart包
helm search repo apache # Helm 搜索使用模糊字符串匹配算法
helm install web bitnami/apache # release名为web
helm install bitnami/apache --generate-name # 随机名# 查看已部署的应用,也就是查看release
helm list
helm show chart bitnami/apache # 查看chart的基本信息
卸载chart示例
helm v2 版本中,当一个 release 被删除,会保留一条删除记录。而在 Helm 3 中,删除也会移除 release 的记录。 如果你想保留删除记录,使用 helm uninstall --keep-history
。使用 helm list --uninstalled
只会展示使用了 --keep-history
删除的 release
helm list --all
会展示 Helm 保留的所有 release 记录,包括失败或删除的条目(指定了 --keep-history
)
# 卸载已部署的名为web的release
helm uninstall web # 该命令会从Kubernetes卸载web它将删除和该版本相关的所有相关资源(service、deployment、 pod等)甚至版本历史--keep-history # 该选项, Helm 将会保存版本历史helm status web # 查看该版本的信息
安装前自定义chart
安装过程中有两种方式传递配置数据
--values
(或-f
):使用 YAML 文件覆盖配置。可以指定多次,优先使用最右边的文件--set
:通过命令行的方式对指定项进行覆盖
如果同时使用两种方式,则--set
中的值会被合并到 --values
中,但是 --set
中的值优先级更高。在 --set
中覆盖的内容会被被保存在 ConfigMap 中。可以通过 helm get values <release-name>
来查看指定 release 中 --set
设置的值。也可以通过运行 helm upgrade
并指定 --reset-values
字段来清除 --set
中设置的值
# 查看 chart 中的可配置选项
helm show values bitnami/apache # 使用 YAML 格式的文件覆盖上述任意配置项,并在安装过程中使用该文件
vim values.yaml
service:type: NodePorthelm install web -f values.yaml bitnami/apache
# 查看svc,service的类型就是NOdePort类型了
kubectl get svc
下载chart包到本地
# 下载apache的chart包
[root@master 7.2]# helm pull bitnami/apache
[root@master 7.2]# ls
apache-11.3.18.tgz
[root@master 7.2]# tar xf apache-11.3.18.tgz
[root@master 7.2]# ls
apache apache-11.3.18.tgz# 目录里的templates存放K8s部署资源模板,Chart.yaml:包含chart的基本信息(版本、名称等)
[root@master 7.2]# ls apache
Chart.lock Chart.yaml README.md values.schema.json
charts files templates values.yaml[root@master 7.2]# vim 1.values.yaml
image:registry: harbor:443repository: library/apachetag: 2.4.63
global:security:allowInsecureImages: true # 显式允许非标准镜像
service:type: ClusterIP
[root@master 7.2]# helm install test -f 1.values.yaml apache/.
helm upgrade升级
当你想升级到 chart 的新版本,或是修改 release 的配置,你可以使用 helm upgrade
命令。Helm 会尝试执行最小侵入式升级。即它只会更新自上次发布以来发生了更改的内容
# 创建配置项,然后在安装chart的时候,指定该yaml配置项
[root@master 7.2]# vim 1.values.yaml
image:registry: harbor:443repository: library/apachetag: 2.4.63
global:security:allowInsecureImages: true # 显式允许非标准镜像
service:type: ClusterIP# 安装chart包,并使用-f选项修改配置项
[root@master 7.2]# helm install web -f 1.values.yaml bitnami/apache
# 部署完后,查看svc类型是不是被修改成了ClusterIP
[root@master 7.2]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 63d
web-apache ClusterIP 10.245.134.139 <none> 80/TCP,443/TCP 50s# 再次创建配置项,来修改svc的类型
[root@master 7.2]# vim 2.values.yaml
service: type: NodePort
# 使用upgrade子命令来升级web这个release的svc类型
[root@master 7.2]# helm upgrade -f 2.values.yaml web bitnami/apache
# 升级后,查看svc的类型就变成了NodePort
[root@master 7.2]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 63d
web-apache NodePort 10.245.134.139 <none> 80:31221/TCP,443:32027/TCP 2m# 看看配置值是否真的生效了
[root@master 7.2]# helm get values web
USER-SUPPLIED VALUES:
service:type: NodePort
helm rollback回滚
现在,假如在一次发布过程中,发生了不符合预期的事情,也很容易通过 helm rollback [RELEASE] [REVISION]
命令回滚到之前的发布版本
release 版本其实是一个增量修订(revision)。 每当发生了一次安装、升级或回滚操作,revision 的值就会加1。第一次 revision 的值永远是1。我们可以使用 helm history [RELEASE]
命令来查看一个特定 release 的修订版本号
# 查看历史版本
[root@master 7.2]# helm history web
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Wed Jul 2 16:05:50 2025 superseded apache-11.3.182.4.63 Install complete
2 Wed Jul 2 16:07:39 2025 deployed apache-11.3.182.4.63 Upgrade complete# 回滚到1版本
[root@master 7.2]# helm rollback web 1
Rollback was a success! Happy Helming!
# 回滚后,查看svc的类型就变成了1版本的ClusterIP类型
[root@master 7.2]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 63d
web-apache ClusterIP 10.245.134.139 <none> 80/TCP,443/TCP 93m
# 再次查看历史版本
[root@master 7.2]# helm history web
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Wed Jul 2 16:05:50 2025 superseded apache-11.3.18 2.4.63 Install complete
2 Wed Jul 2 16:07:39 2025 superseded apache-11.3.18 2.4.63 Upgrade complete
3 Wed Jul 2 17:39:17 2025 deployed apache-11.3.18 2.4.63 Rollback to 1
创建一个自己的chart
# 创建一个模板
[root@master 7.2]# helm create mychart
Creating mychart
[root@master 7.2]# ls
1.values.yaml 2.values.yaml apache apache-11.3.18.tgz mychart
[root@master 7.2]# tree mychart/
mychart/
├── charts # 子 Chart(依赖的其他 Charts)
├── Chart.yaml # Chart 元数据(名称、版本、依赖等)
├── templates # Kubernetes 资源模板(YAML 文件)
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── NOTES.txt # 安装后的提示信息
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml # 默认配置(可被用户覆盖)3 directories, 10 files[root@master 7.2]# cd mychart/
# 删除模板中的文件,我们自己创建
[root@master mychart]# rm -fr values.yaml templates/*
=======================================================
[root@master mychart]# vim templates/NOTES.txt
1、这是一个测试的 myapp chart
2、myapp release 名字:myapp-test-{{ now | date "20060102030405" }}-deploy
3、service 名字:myapp-test-{{ now | date "20060102030405" }}-svc
=======================================================
[root@master mychart]# vim templates/svc.yaml
apiVersion: v1
kind: Service
metadata:labels:app: mychartname: mychart-test-{{ now | date "20060102030405" }}-svc
spec:ports:- name: 80-80port: 80protocol: TCPtargetPort: 80{{- if eq .Values.service.type "NodePort" }}nodePort: {{ .Values.service.nodeport }}{{- end }}selector:app: mycharttype: {{ .Values.service.type | quote }}
=======================================================
[root@master mychart]# vim templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: mychartname: mychart-test-{{ now | date "20060102030405" }}-deploy
spec:replicas: {{.Values.replicaCount}}selector:matchLabels:app: my-deptemplate:metadata:labels:app: my-depspec:containers:- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}name: mychart
=======================================================
[root@master mychart]# vim values.yaml
# Default values for myapp.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 5
image:repository: library/myostag: httpd
service:type: NodePortnodeport: 31111
========================================================
# 创建自己的chart,并指定参数配置项
[root@master mychart]# helm install mychart -f values.yaml ../mychart/
NAME: mychart
LAST DEPLOYED: Wed Jul 2 21:58:59 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1、这是一个测试的 myapp chart
2、myapp release 名字:myapp-test-20250702095859-deploy
3、service 名字:myapp-test-20250702095859-svc# 查看release
[root@master mychart]# helm ls
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
mychart default 1 2025-07-02 21:58:59.099379134 +0800 CSdeployed mychart-0.1.0 1.16.0
test default 1 2025-07-02 18:16:54.973706955 +0800 CSdeployed apache-11.3.18 2.4.63
web default 3 2025-07-02 17:39:17.204102761 +0800 CSdeployed apache-11.3.18 2.4.63 # 查看svc类型是不是我们上面指定NodePort类型的31111端口
[root@master mychart]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 63d
mychart-test-20250702095859-svc NodePort 10.245.144.95 <none> 80:31111/TCP 20s
test-apache ClusterIP 10.245.228.226 <none> 80/TCP,443/TCP 3h42m
web-apache ClusterIP 10.245.134.139 <none> 80/TCP,443/TCP 5h53m
# 查看deployment是不是5副本的
[root@master mychart]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
mychart-test-20250702095859-deploy 5/5 5 5 33s
test-apache 1/1 1 1 3h42m
web-apache 1/1 1 1 5h53m
# 查看pod的状态是不是running运行的状态
[root@master mychart]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mychart-test-20250702095859-deploy-7f4bf7d6bf-4wz8h 1/1 Running 0 38s
mychart-test-20250702095859-deploy-7f4bf7d6bf-fh4wz 1/1 Running 0 38s
mychart-test-20250702095859-deploy-7f4bf7d6bf-j7thf 1/1 Running 0 38s
mychart-test-20250702095859-deploy-7f4bf7d6bf-ktzp9 1/1 Running 0 38s
mychart-test-20250702095859-deploy-7f4bf7d6bf-qw8z7 1/1 Running 0 38s
test-apache-5646477d78-r8szb 1/1 Running 1 (77m ago) 3h42m
web-apache-7d8c6d8cbb-dllfl 1/1 Running 1 (77m ago) 5h53m