什么是helm?
Helm 是 Kubernetes 的包管理器。Helm 是查找、分享和使用软件构建 Kubernetes 的最优方式。
在红帽系的Linux中我们使用yum来管理RPM包,类似的,在K8s中我们可以使用helm来管理资源对象(Deployment、Service、Ingress...)实现K8s中应用的快速发布、升级、维护和分享。helm 官方文档[1]
helm中的几个关键概念
- Chart 是Helm 中的包。包含一组用于部署应用程序的 K8s 资源对象定义(即资源清单的集合)。
- Repository 即chart图表的仓库。我们可以从网络仓库中搜索、下载和安装chart。
- Release 即chart部署后的实例。通过
helm install
命令,在 Kubernetes 集群上安装该chart的新版本。
helm实现哪些功能?
Helm (v3版本)为 K8s 提供的功能包括:
- 通过单个 CLI 命令部署 Kubernetes 应用(chart)。实现本地chart的创建、管理和发布。
- Helm 将chart中资源对象配置文件模板化,实现在多个集群环境中重用一个 Helm chart,同时可打包进行网络共享。
- Helm 通过自动维护发布的所有版本来简化 Kubernetes 应用程序的回滚,防止部署问题。
- 通过helm轻松实现 Kubernetes 中工作负载的 CI/CD 管道。
helm 基本使用
Helm可以用源码或构建的二进制版本安装。参考:安装 Helm[2]
Artifact Hub[3] 是一个开源项目,我们通过它来查找、安装或发布k8s应用。
除了通过web搜索,也可以通过helm命令行方式:
代码语言:javascript复制#helm search hub redis
URL CHART VERSION APP VERSION DESCRIPTION
https://hub.helm.sh/charts/bitnami/redis 16.4.0 6.2.6 Redis(TM) is an opensource, advanced key-value...
https://hub.helm.sh/charts/wenerme/redis 16.4.0 6.2.6 Redis(TM) is an opensource, advanced key-value...
...
找到redis版本为6.2.6,chart版本16.4.0的包,访问 url https://hub.helm.sh/charts/bitnami/redis
新版本已被重定向到 artifacthub.io
由图上信息可以知redis是一个来自Bitnami仓库(由VMware主导的开源软件仓库),通过验证的版本,仓库地址 https://charts.bitnami.com/bitnami
要安装这个应用我们应先将Bitnami仓库添加到本地配置中。
代码语言:javascript复制#helm repo add bitnami https://charts.bitnami.com/bitnami
安装redis,release名称为 redis-dev
# helm install redis-dev bitnami/redis
NAME: redis-dev
LAST DEPLOYED: Sun Feb 13 20:09:30 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: redis
CHART VERSION: 16.4.0
APP VERSION: 6.2.6
这样我们可以轻松发布一个一主三从的redis集群到k8s中
代码语言:javascript复制# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
redis-dev default 1 2022-02-13 20:09:30.755534484 0800 CST deployed redis-16.4.0
Helm 通过向资源对象中添加标签来跟踪安装在 Kubernetes 集群上的chart。这些标签看起来像 app.kubernetes.io/managed-by=Helm
和 app.kubernetes.io/instance:myapp
。
# kubectl get all -l app.kubernetes.io/instance=redis-dev
NAME READY STATUS RESTARTS AGE
pod/redis-dev-master-0 1/1 Running 0 27m
pod/redis-dev-replicas-0 1/1 Running 0 27m
pod/redis-dev-replicas-1 1/1 Running 0 24m
pod/redis-dev-replicas-2 1/1 Running 0 23m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/redis-dev-headless ClusterIP None <none> 6379/TCP 27m
service/redis-dev-master ClusterIP 10.96.52.104 <none> 6379/TCP 27m
service/redis-dev-replicas ClusterIP 10.96.230.162 <none> 6379/TCP 27m
NAME READY AGE
statefulset.apps/redis-dev-master 1/1 27m
statefulset.apps/redis-dev-replicas 3/3 27m
删除 redis-dev
的发布,将会移除标签跟踪的所有资源对象。
# helm uninstall redis-dev
release "redis-dev" uninstalled
创建自己的helm chart
显然大多数时候我们更想发布自己的应用到K8s中或者需要对将要发布的开源软件做一些配置上的修改,所以我们可以通过helm自己构建一个chart或者使用 helm pull
下载一个chart做修改后再上传的内部或外部仓库中。
下面来创建一个简易的nginx chart
代码语言:javascript复制# helm create chart-nginx
Creating chart-nginx
chart的目录结构,你可以删除模板中的所有文件自建或使用默认模板
代码语言:javascript复制# tree chart-nginx/
chart-nginx/
├── charts #依赖的chart目录
├── Chart.yaml #chart版本信息
├── templates #资源对象模板目录
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── NOTES.txt #提示信息
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml #模板值
3 directories, 10 files
Chart.yaml声明了版本信息,我们可以进行自定义
代码语言:javascript复制# Chart.yaml
apiVersion: v2
name: chart-nginx
description: A Helm chart for Kubernetes
type: application
version: 0.1.0 #chart版本
appVersion: 1.0.0 #app版本
helm默认创建的模板文件deployment.yaml如下:
helm 采用go模板,官方文档Chart 模板[4]
通过deployment模板中可以看到 image
的值会引用value文件中定义的image.repository和tag,如果tag值为空则返回默认引用Chart.appVersion的值。
接着根据需要更新value.yaml文件中 image
和 service
等相关信息,同时关闭serviceAccount、ingress、hpa的创建。
模板文件service.yaml定义好了type和pod的引用。
一个基本的nginx chart创建好了。通过 helmtemplate
命令渲染模板查看一下
# helm template chart-nginx
---
# Source: chart-nginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: RELEASE-NAME-chart-nginx
labels:
helm.sh/chart: chart-nginx-0.1.0
app.kubernetes.io/name: chart-nginx
app.kubernetes.io/instance: RELEASE-NAME
app.kubernetes.io/version: "1.0.0"
app.kubernetes.io/managed-by: Helm
spec:
type: NodePort
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: chart-nginx
app.kubernetes.io/instance: RELEASE-NAME
---
# Source: chart-nginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: RELEASE-NAME-chart-nginx
labels:
helm.sh/chart: chart-nginx-0.1.0
app.kubernetes.io/name: chart-nginx
...
再通过 helm lint
检查语法
==> Linting chart-nginx
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
ok,通过 helm install
发布到k8s,参照NOTES说明可进行访问。
# helm install chart-nginx --generate-name
NAME: chart-nginx-1644771770
LAST DEPLOYED: Mon Feb 14 01:02:50 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services chart-nginx-1644771770)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
查看资源正常。
代码语言:javascript复制# kubectl get all -l app.kubernetes.io/name=chart-nginx
NAME READY STATUS RESTARTS AGE
pod/chart-nginx-1644771770-69bbb4fdf8-gqdk7 1/1 Running 0 3m59s
pod/chart-nginx-1644771770-69bbb4fdf8-wwxw2 1/1 Running 0 3m59s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/chart-nginx-1644771770 NodePort 10.96.231.61 <none> 80:32631/TCP 3m59s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/chart-nginx-1644771770 2/2 2 2 3m59s
NAME DESIRED CURRENT READY AGE
replicaset.apps/chart-nginx-1644771770-69bbb4fdf8 2 2 2 3m59s
通过仓库分发应用
首先通过 helm packge
将chart-nginx打包
# helm package chart-nginx
Successfully packaged chart and saved it to: .../../chart-nginx-0.1.0.tgz
建立chart私有仓库,可参考开源项目chartmuseum,如有必要你也可将仓库提交至 artifacthub
发布到互联网。
将 chart-nginx-0.1.0.tgz
上传至仓库后,通过curl列出chart信息如下:
# curl http://192.168.1.123:8088/api/charts |python -m json.tool
{
"chart-nginx": [
{
"apiVersion": "v2",
"appVersion": "1.0.0",
"created": "2022-02-13T17:37:43.653117345Z",
"description": "A Helm chart for Kubernetes",
"digest": "58a687be62a2a2a2b1dd177675bbc5aa49ac754df2219149bb4798636662b57c",
"name": "chart-nginx",
"type": "application",
"urls": [
"charts/chart-nginx-0.1.0.tgz"
],
"version": "0.1.0"
}
]
}
将仓库添加到你的其他k8s集群helm中,实现应用共享和发布。
代码语言:javascript复制# helm repo add chartmuseum http://192.168.1.123:8088
"chartmuseum" has been added to your repositories
搜索 chart-nginx
# helm search repo chart-nginx
NAME CHART VERSION APP VERSION DESCRIPTION
chartmuseum/chart-nginx 0.1.0 1.0.0 A Helm chart for Kubernetes
通过仓库发布 chart-nginx
# helm install my-chart-nginx chartmuseum/chart-nginx
NAME: my-chart-nginx
LAST DEPLOYED: Mon Feb 14 01:54:34 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
...
以上我们对helm进行了基本介绍以及如何创建一个自己的 helm chart
,如何结合私有仓库 chartmuseum
在K8s中发布应用。