helm简介
Helm 是 Kubernetes 上的包管理器,用来管理Kubernetes应用程序,Helm Charts可帮助您定义,安装和升级复杂的Kubernetes应用程序。Helm把Kubernetes资源(比如deployments、services或 ingress等) 打包到一个chart中,而chart被保存到chart仓库。通过chart仓库可用来存储和分享chart。
Helm使发布可配置,支持发布应用配置的版本管理,简化了Kubernetes部署应用的版本控制、打包、发布、删除、更新等操作。Helm之于Kubernetes好比yum之于RHEL,或者apt-get之于Ubuntu。Helm使用Chart帮助我们管理应用,Chart就好像RPM一样,里面描述了应用及其依赖关系。
helm v3版本了移除 Tiller、让 Helm 成为一个纯客户端工具。
Helm安装
github地址:https://github.com/helm/helm
官方文档:https://helm.sh/docs/intro/install/
二进制安装helm3
version=v3.6.0
curl -LO https://repo.huaweicloud.com/helm/${version}/helm-${version}-linux-amd64.tar.gz
tar -zxvf helm-${version}-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/helm && rm -rf linux-amd64
官方下载方式
curl -LO https://get.helm.sh/helm-${version}-linux-amd64.tar.gz
脚本安装helm
curl -L https://git.io/get_helm.sh | bash -s -- -v v3.1.2
查看helm版本
helm version --short
Helm组件
Helm 中的重要概念:
- Helm 命令行工具主要用于 Kubernetes 应用程序 Chart 的创建、打包、发布以及创建和管理本地和远程的 Chart 仓库。
- chart 是Helm 的软件包,是创建一个应用的信息集合,采用 TAR 格式,其包含了一组定义 Kubernetes 资源相关的YAML 文件,包括各种 Kubernetes 对象的配置模板、参数定义、依赖关系、文档说明等。
- release 可以理解为 Helm使用 Chart 包部署的一个应用实例,代表了一个正在运行的应用。当 chart 被安装到 Kubernetes 集群,就生成一个release。chart 能够多次安装到同一个集群,每次安装都是一个 release。
- Repoistory是Helm的软件仓库,Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。
Helm使用
国内阿里云chart仓库:
https://github.com/cloudnativeapp/charts
bitnami helm仓库
https://github.com/bitnami/charts
kube-charts-mirror
https://github.com/BurdenBear/kube-charts-mirror
添加chart repository,国内目前好像只有前两个可以添加成功:
#阿里云
helm repo add apphub https://apphub.aliyuncs.com
#bitnami
helm repo add https://charts.bitnami.com/bitnami
#kube-charts-mirror
helm repo add stable https://burdenbear.github.io/kube-charts-mirror
也可以添加官方chart repository,注意,官方chart仓库官方仓库国内无法访问。
helm repo add stable https://kubernetes-charts.storage.googleapis.com/
查看添加的chart仓库
# helm repo list
NAME URL
apphub https://apphub.aliyuncs.com
更新chart仓库
helm repo update
移除chart仓库
helm repo remove apphub
查看可安装的charts
helm search repo
helm search repo nginx
helm search repo mysql
部署nginx应用,直接覆盖参数部署为nodePort类型
helm show all apphub/nginx
helm install my-nginx-app --set service.type=NodePort apphub/nginx
helm ls
helm uninstall my-nginx-app
浏览器访问
http://<node-ip>:ndoeport
从0手动创建charts
创建chart目录结构
mkdir my-nginx
cd my-nginx
创建Chart.yaml
cat > Chart.yaml <<EOF
apiVersion: v2
appVersion: v1.0
description: A Helm chart for Kubernetes
name: nginx-app
version: 0.1.0
EOF
创建templates目录
[root@master01 my-nginx]# mkdir templates
创建deployment.yaml
[root@master01 my-nginx]# kubectl create deploy my-nginx --image nginx --dry-run=client -o yaml > templates/deployment.yaml
[root@master01 my-nginx]# tree
.
├── Chart.yaml
└── templates
└── deployment.yaml
以上完成后就可以使用helm部署,部署名为my-nginx的应用
[root@master01 my-nginx]# helm install my-nginx .
NAME: my-nginx
LAST DEPLOYED: Wed Apr 22 22:20:28 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
查看创建的应用
[root@master01 my-nginx]# helm ls
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-nginx default 1 2020-04-22 22:20:28.899879555 +0800 CST deployed nginx-app-0.1.0 v1.0
查看创建的实际资源
[root@master01 my-nginx]# kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-9b596c8c4-8w55p 1/1 Running 0 3m2s
继续创建service.yaml
[root@master01 my-nginx]# kubectl expose deploy my-nginx --port 80 --dry-run=client -o yaml > templates/service.yaml
创建values.yaml
cat > values.yaml <<EOF
replicaCount: 2
service:
type: NodePort
NodePort: 30080
EOF
修改deployment.yaml,注入变量,改为模板形式:
[root@master01 my-nginx]# cat templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: my-nginx
name: my-nginx
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: my-nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: my-nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
修改service.yaml,注入变量,改为模板形式:
[root@master01 my-nginx]# cat templates/service.yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: my-nginx
name: my-nginx
spec:
type: {{ .Values.service.type }}
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: {{ .Values.service.nodePort }}
selector:
app: my-nginx
status:
loadBalancer: {}
此时的目录结构
[root@master01 my-nginx]# tree
.
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ └── service.yaml
└── values.yaml
修改后可升级helm版本,也可以删除原helm重新部署:
[root@master01 my-nginx]# helm upgrade my-nginx .
Release "my-nginx" has been upgraded. Happy Helming!
NAME: my-nginx
LAST DEPLOYED: Wed Apr 22 22:37:11 2020
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
查看升级后的信息,REVISION版本变为2
[root@master01 my-nginx]# helm ls
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-nginx default 2 2020-04-22 22:37:11.159433211 +0800 CST deployed nginx-app-0.1.0 v1.0
查看创建的资源,副本扩容为2,新创建了NodePort类型的service:
[root@master01 my-nginx]# kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-9b596c8c4-8w55p 1/1 Running 0 20m
my-nginx-9b596c8c4-h7b6f 1/1 Running 0 3m38s
[root@master01 my-nginx]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d10h
my-nginx NodePort 10.98.112.77 <none> 80:30080/TCP 3m42s
浏览器访问应用
基于模板创建charts
以官方示例为参考:https://helm.sh/docs/chart_template_guide/getting_started/
创建一个名为mychart的简单chart,然后会生成mychart目录,并自动生成一些模板文件以供参考:
helm create mychart
创建完成后Helm chart的目录结构如下:
# tree mychart/
mychart/
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
说明:
- charts/目录可能包含其他chart(我们称为subcharts)。charts 目录存放依赖的chart。
- Chart.yaml文件包含对chart的描述。包括chart版本,名称等。可以从模板中访问它。
- templates/目录下存放应用一系列 k8s 资源的 yaml 模板,helm通过模板渲染引擎将templates/目录下的yaml模板进行渲染,然后发送到Kubernetes。
- values.yaml文件对模板也很重要。包含了必要的值定义(默认值), 用于存储 templates 目录中模板文件中用到变量的值。
- NOTES.txt:介绍chart 部署后的帮助信息,如何使用chart等,这将在用户运行helm install 时显示给他们。
- deployment.yaml:创建Kubernetes deployment的基本清单
- service.yaml:为deployment创建service endpoint的基本清单
- _helpers.tpl:此文件中定义一些可重用的模板片断,此文件中的定义在任何资源定义模板中可用
现在删除templates目录下所有文件,演示手动创建相关模板
$ rm -rf mychart/templates/*
以创建configmap模板为例,创建一个名为mychart/templates/configmap.yaml的文件:
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"
模板创建完成后就可以安装该chart:
$ helm install full-coral ./mychart
NAME: full-coral
LAST DEPLOYED: Tue Nov 1 17:36:01 2016
NAMESPACE: default
STATUS: DEPLOYED
REVISION: 1
TEST SUITE: None
检索发布并查看已加载的实际模板。
# helm get manifest full-coral
---
# Source: mycharts/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"
该helm get manifest命令指定release名称(full-coral),并打印出上载到服务器的所有Kubernetes资源。每个文件都—以指示YAML文档的开头开始,然后是自动生成的注释行,该注释行告诉我们是哪个模板文件生成了该YAML文档。可以看到YAML数据正是我们放入configmap.yaml文件中的数据。
卸载release:
helm uninstall full-coral。
添加一个简单的模板调用
硬编码name字段到资源通常被认为是不好的做法。名称对于release应该是唯一的。因此,我们可能希望通过插入release名称来生成name字段。
对configmap.yaml进行相应的更改。模板指令包含在{{ }}中。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
模板指令 {{.Release.Name}} 将 release 名称注入模板。传递给模板的值可以认为是 namespace 对象,其中 dot(.)分隔每个 namespace 元素。
Release 前面的前一个小圆点表示我们从这个范围的最上面的 namespace 开始。所以我们可以这样理解 .Release.Name:“从顶层命名空间开始,找到 Release 对象,然后在里面查找名为 Name 的对象”。
该 Release 对象是 Helm 的内置对象之一。
现在,当我们安装资源时,会立即看到使用这个模板指令的结果:
$ helm install clunky-serval ./mychart
NAME: clunky-serval
LAST DEPLOYED: Tue Nov 1 17:45:37 2016
NAMESPACE: default
STATUS: DEPLOYED
REVISION: 1
TEST SUITE: None
查看整个生成的yaml
# helm get manifest clunky-serval
---
# Source: mycharts/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: clunky-serval-configmap
data:
myvalue: "Hello World"
现在,我们看过了基础的模板:YAML 文件嵌入了模板指令{{ }},另外有一个快速技巧可以使构建模板更快:当您想测试模板渲染,但实际上不安装任何东西时,可以使用helm install --debug --dry-run ./mychart。这会将 chart 发送到 Tiller 服务器,它将渲染模板。但不是安装 chart,它会将渲染模板返回,以便可以看到输出:
$ helm install --debug --dry-run ./mychart
SERVER: "localhost:44134"
CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart
NAME: goodly-guppy
TARGET NAMESPACE: default
CHART: mychart 0.1.0
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
myvalue: "Hello World"
使用–dry-run可以更容易地测试代码,但不能确保 Kubernetes 本身会接受生成的模板。最好不要假定你的 chart 只要–dry-run成功而被安装。