每个成功的软件平台都有一个优秀的打包系统,比如 Debian、Ubuntu 的 apt,Redhat、Centos 的 yum。而 Helm 则是 Kubernetes 上的包管理器,可以很方便的将之前打包好的yaml文件部署到kubernetes上。
本章我们将讨论为什么需要 Helm,它的架构和组件,以及如何使用 Helm。
Helm有两个重要概念:
此外Helm还经常与CI\CD配置使用,在这个过程中用于维护应用程序的安装、升级、回滚等操作。
Helm 到底解决了什么问题?为什么 Kubernetes 需要 Helm? 答案是:Kubernetes 能够很好地组织和编排容器,但它缺少一个更高层次的应用打包工具,而 Helm 就是来干这件事的。
K8S上的应用对象,都是由特定的资源描述组成,包括deployment、service等。都保存各自文件中或者集中写到一个配置文件。然后kubectl apply –f 部署。

如果应用只由一个或几个这样的服务组成,上面部署方式足够了。
而对于一个复杂的应用,会有很多类似上面的资源描述文件,例如微服务架构应用,组成应用的服务可能多达十个,几十个。如果有更新或回滚应用的需求,可能要修改和维护所涉及的大量资源文件,而这种组织和管理应用的方式就显得力不从心了。
且由于缺少对发布过的应用版本管理和控制,使Kubernetes上的应用维护和更新等面临诸多的挑战,主要面临以下问题:
2019年11月13日, Helm团队发布 Helm v3的第一个稳定版本。
该版本主要变化如下:
架构变化
最明显的变化是 Tiller的删除

Release名称可以在不同命名空间重用
支持将 Chart 推送至 Docker 镜像仓库中
使用JSONSchema验证chart values
其他
5.1. 为了更好地协调其他包管理者的措辞 Helm CLI个别更名
helm delete 更名为 helm uninstall
helm inspect 更名为 helm show
helm fetch 更名为 helm pull但以上旧的命令当前仍能使用。
5.2. 移除了用于本地临时搭建 Chart Repository的 helm serve 命令。
5.3. 自动创建名称空间,在不存在的命名空间中创建发行版时,Helm 2创建了命名空间。Helm 3遵循其他Kubernetes对象的行为,如果命名空间不存在则返回错误。
5.4. 不再需要requirements.yaml, 依赖关系是直接在chart.yaml中定义。
Helm客户端下载地址:https://github.com/helm/helm/releases
解压移动到/usr/bin/目录即可。
wget https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz
tar zxvf helm-v3.8.2-linux-amd64.tar.gz
mv linux-amd64/helm /usr/bin/命令 | 描述 |
|---|---|
create | 创建一个chart并指定名字 |
dependency | 管理chart依赖 |
get | 下载一个release。可用子命令:all、hooks、manifest、notes、values |
history | 获取release历史 |
install | 安装一个chart |
list | 列出release |
package | 将chart目录打包到chart存档文件中 |
pull | 从远程仓库中下载chart并解压到本地 # helm pull stable/mysql —untar |
repo | 添加,列出,移除,更新和索引chart仓库。可用子命令:add、index、list、remove、update |
rollback | 从之前版本回滚 |
search | 根据关键字搜索chart。可用子命令:hub、repo |
show | 查看chart详细信息。可用子命令:all、chart、readme、values |
status | 显示已命名版本的状态 |
template | 本地呈现模板 |
uninstall | 卸载一个release |
upgrade | 更新一个release |
version | 查看helm客户端版本 |
添加存储库:
helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo update查看配置的存储库:
helm repo list
helm search repo stable一直在stable存储库中安装charts,你可以配置其他存储库。
删除存储库:
helm repo remove aliyun主要介绍三个命令:
# helm search repo xxxxx
# helm search repo mysql# 查看chart信息:
helm show chart stable/mysql
# helm部署到k8s上MySQL服务
helm install db stable/mysql
# 查看发布提示信息:
helm status db
# 查看pods会发现处于Pending。这时需要创建pv。
cat > pv-config.yml <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 8Gi
nfs:
path: /data/nfs-volume/mysql
server: 10.1.1.150
EOF
# 应用pv资源
kubectl apply -f pv-config.yml这是因为并不是所有的chart都能按照默认配置运行成功,可能会需要一些环境依赖,例如PV。
所以我们需要自定义chart配置选项,安装过程中有两种方法可以传递配置数据:
cat > rbac.yml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get","create","list", "watch","update"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io
EOFcat >dp.yml <<EOF
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccount: nfs-provisioner
containers:
- name: nfs-client-provisioner
image: wangxiansen/nfs-client-provisioner:v3.1.0
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME # 供应者的名字
value: data-storage # 名字虽然可以随便起,以后引用要一致
- name: NFS_SERVER
value: 10.1.1.150
- name: NFS_PATH
value: /data/nfs-volume/mysql
volumes:
- name: nfs-client-root
nfs:
server: 10.1.1.150
path: /data/nfs-volume/mysql
EOFcat storage.yml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: mysql-nfs-storage
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: data-storage
reclaimPolicy: Delete
allowVolumeExpansion: True
EOF以下是将创建具有名称的默认MySQL用户k8s,默认root密码为wangxiansen,并授予此用户访问新创建的k8s数据库的权限,但将接受该图表的所有其余默认值。
# helm show values stable/mysql
cat > values.yaml <<EOF
mysqlRootPassword: "wangxiansen"
persistence:
enabled: true
storageClass: "mysql-nfs-storage"
accessMode: ReadWriteOnce
size: 1Gi
mysqlUser: "k8s"
mysqlPassword: "123456"
mysqlDatabase: "k8s"
EOF
# helm创建db2
helm install db2 -f values.yaml stable/mysql
# 查看pods
kubectl get pods
NAME READY STATUS RESTARTS AGE
db2-mysql-f7fbfdd68-7f7q8 1/1 Running 0 2d21h命令行替代变量:
# helm install db3 --set persistence.storageClass="mysql-nfs-storage" --set mysqlRootPassword="testing" stable/mysql也可以把chart包下载下来查看详情:
# helm pull stable/mysql --untarvalues yaml与set使用:

该helm install命令可以从多个来源安装: