Kubernetes-helm详细说明

olei 2,063 views 0

Helm基本介绍

  • 微服务和容器化给复杂应用部署与管理带来了极大的挑战。Helm是目前Kubernetes服务编排领域的唯一开源子项目,做为Kubernetes应用的一个包管理工具,可理解为Kubernetesapt-get / yum,由Deis公司发起,该公司已经被微软收购。Helm通过软件打包的形式,支持发布的版本管理和控制,很大程度上简化了Kubernetes应用部署和管理的复杂性。
  • 随着业务容器化与向微服务架构转变,通过分解巨大的单体应用为多个服务的方式,分解了单体应用的复杂性,使每个微服务都可以独立部署和扩展,实现了敏捷开发和快速迭代和部署。但任何事情都有两面性,虽然微服务给我们带来了很多便利,但由于应用被拆分成多个组件,导致服务数量大幅增加,对于Kubernetest编排来说,每个组件有自己的资源文件,并且可以独立的部署与伸缩,这给采用Kubernetes做应用编排带来了诸多挑战:
    • 管理、编辑与更新大量的K8s配置文件
    • 部署一个含有大量配置文件的复杂K8s应用
    • 分享和复用K8s配置和应用;
    • 参数化配置模板支持多个环境;
    • 管理应用的发布、回滚、diff和查看发布历史;
    • 控制一个部署周期中的某一些环节发布后的验证。
  • HelmKubernetes资源(比如deploymentsservicesingress)等打包到一个chart中,而chart被保存到chart仓库。通过chart仓库可用来存储和分享chartHelm使发布可配置,支持发布应用配置的版本管理,简化了Kubernetes部署应用的版本控制、打包、发布、删除、更新等操作。
  • 项目地址:https://github.com/helm/helm

Helm术语

  • Chart: 一个helm程序包,是创建一个应用的信息集合,包含各种Kubernetes对象的配置模板、参数定义、依赖关系、文档说明等。可以将Chart比喻为yum中的软件安装包
  • Repository: Charts仓库,用于集中存储和分发Charts
  • config: 包含了应用发布配置信息
  • Release: 特定的Chart部署于目标集群上的一个实例,代表这一个正在运行的应用。当chart被安装到Kubernetes集群,就会生成一个releasechart可以多次安装到同一个集群,每次安装都是一个新的release

Helm系统架构

helm采用客户端/服务端架构,有如下组件组成:

  • Helm客户端:用户命令行工具,负责本地chart开发、仓库管理、与Tiller server交互、发送预安装的chart、查询release信息和要求升级或卸载已存在的release
  • Tiller Server:部署在Kubernetes集群内部的server,其与Helm clientKubernetes API Server进行交互。负责监听来自Helm client的请求、通过chart及其配置构建一次发布、安装chartKubernetes集群并跟踪随后的发布、通过与Kubernetes交互升级或卸载chart
  • RepositoryChart仓库,Helm客户端通过HTTP协议来访问仓库中Chart的索引文件和压缩包
    Kubernetes-helm详细说明

Helm工作原理

  • Helm包括两部分,Helm客户端和Tiller服务端。
  • Helm客户端是一个命令行工具,采用go语言编写,负责管理chartsrepositoryrelease。它通过gPRC APITiller server发送请求。
  • Tiller服务端同样采用go语言编写,提供了gPRC server接受来自Helm客户端的请求,利用Kubernetes client库把相关资源的操作发送到Kubernetes,负责管理(安装、查询、升级或删除)和跟踪Kubernetes资源。为了方便管理,Tiller服务端把release的相关信息保存在KubernetesConfigMap中。

Helm安装

  • 准备一套Kubernetes集群并在每个节点都安装依赖包socat
$ yum -y install socat
  • Helm项目地址下载v2.15.1版本,将压缩包解压后的二进制文件复制到可执行文件目录/usr/local/bin
$ tar xvf helm-v2.15.1-linux-amd64.tar.gz
$ cp /root/helm/linux-amd64/helm /usr/local/bin/helm
  • Helm TillerHelmserver端,以Pod形式部署到Kubernetes集群中。通过命令helm init初始化Helm服务,该命令会检查Helm本地环境设置是否正确,helm init会连接kubelet默认连接的Kubernetes集群,一旦连接集群成功,Tiller服务会被安装到Kubernetes集群中的kube-system命名空间中
$ helm init --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.15.1 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
  • 查看Tiller服务相关的Pod是否正常启动
$ kubectl get pods -n kube-system -o wide |grep tiller 
  • 创建serviceAccount来授权Tiller服务可能访问Kubernetes集群中的资源
$ kubectl create serviceaccount --namespace kube-system tiller
$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
$ kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}' 
  • 验证Tiller服务是否正常,如果Helm客户端可以正常连接Tiller服务则输出信息如下。
$ helm version
Client: &version.Version{SemVer:"v2.15.1", GitCommit:"cf1de4f8ba70eded310918a8af3a96bfe8e7683b", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.15.1", GitCommit:"cf1de4f8ba70eded310918a8af3a96bfe8e7683b", GitTreeState:"clean"}

Chart私有仓库

chart仓库用来存储和分享打包的chart,官方chart仓库由Kubernetes Charts维护, Helm允许我们创建私有chart仓库。chart仓库是一个可用来存储index.yml与打包的chart文件的HTTP server,当要分享chart时,需要上传chart文件到chart仓库。任何一个能能够提供YAMLtar文件的HTTP server都可以当做chart仓库,比如Google Cloud Storage (GCS) bucket、Amazon S3 bucket、Github Pages或创建你自己的web服务器

Chart仓库结构

  • 一个chart仓库由多个chart包与index.yaml文件组成,index.yaml记录了chart仓库中全部chart的索引

创建并添加Chart私有仓库到本地仓库列表中

  • 创建Chart私有仓库存储目录并启动一个私有仓库绑定该目录
$ mkdir -p /root/helm-dir/charts/
$ helm serve --address 0.0.0.0:8879 --repo-path /root/helm-dir/charts/
  • 当私有仓库服务启动后会在/root/helm-dir/charts目录中自动创建一个index.yaml文件,内容如下
apiVersion: v1
entries: {}
generated: "2020-03-27T14:50:43.3791484+08:00"
  • 创建一个chart包并打包、移动压缩包到Chart私有仓库存储目录中
$ helm create test01
$ helm package test01
$ mv test01-0.1.0.tgz /root/helm-dir/charts/
  • 通过helm repo index命令重新生成index.yaml文件,命令会根据现有的chart压缩包来生成索引。新的索引文件index.yaml中会包含添加的chart压缩包信息
$ helm repo index /root/helm-dir/charts/ --url http://192.168.31.221:8879/charts
$ ls -l /root/helm-dir/charts/
total 8
-rw-r--r-- 1 root root  386 Mar 10 14:51 index.yaml
-rw-r--r-- 1 root root 3248 Mar 10 14:03 test01-0.1.0.tgz

$ cat /root/helm-dir/charts/index.yaml
apiVersion: v1
entries:
  test01:
  - apiVersion: v1
    appVersion: "1.0"
    created: "2020-03-10T14:51:27.781754825+08:00"
    description: A Helm chart for Kubernetes
    digest: cec95ca0e38174d080cc9e3d81380a0f077cd28a30b28571e76b035bc051a9b6
    name: test01
    urls:
    - http:// 192.168.31.221:8879/test01-0.1.0.tgz
    version: 0.1.0
generated: "2020-03-10T14:51:27.781091459+08:00"
  • 添加Chart私有仓库到本地仓库列表中,并更新本地仓库列表资源缓存
$ helm repo add localRegistry http://192.168.31.221:8879/charts
"localRegistry" has been added to your repositories

$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "localRegistry" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete.
  • 查看本地仓库列表并搜索刚上传的test01chart
$ helm repo list
NAME            URL                                                   
stable          https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
localRegistry   http://192.168.31.221:8879/charts                     
[root@node1 helm-dir]# helm search test01
NAME                    CHART VERSION   APP VERSION DESCRIPTION                
localregistry/test01    0.1.0           1.0         A Helm chart for Kubernetes

管理本地仓库列表

通过helm客户端可以对本地仓库列表进行管理,和Tiller服务没有任何关系,所有添加的本地仓库列表信息都存储在/root/.helm/repository目录中

  • 查看本地仓库列表
$ helm repo list 
NAME            URL                                                   
stable          https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
localRegistry   http://192.168.31.221:8879/charts
  • 添加一个Chart仓库名称为binami到本地仓库列表中并查看
$ helm repo add binami https://charts.bitnami.com/bitnami
"binami" has been added to your repositories

$ helm repo list 
NAME            URL                                                   
stable          https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
localRegistry   http://192.168.31.221:8879/charts                     
binami          https://charts.bitnami.com/bitnami
  • 更新本地仓库列表资源缓存并查找一个chart
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "localRegistry" chart repository
...Successfully got an update from the "stable" chart repository
...Successfully got an update from the "binami" chart repository
Update Complete.

$ helm search mysql
NAME                            CHART VERSION   APP VERSION DESCRIPTION                                                 
binami/mysql                    6.9.2           8.0.19      Chart to create a Highly available MySQL cluster            
stable/mysql                    0.3.5                       Fast, reliable, scalable, and easy to use open-source rel...
binami/phpmyadmin               4.3.3           5.0.1       phpMyAdmin is an mysql administration frontend              
stable/percona                  0.3.0                       free, fully compatible, enhanced, open source drop-in rep...
stable/percona-xtradb-cluster   0.0.2           5.7.19      free, fully compatible, enhanced, open source drop-in rep...
binami/mariadb                  7.3.12          10.3.22     Fast, reliable, scalable, and easy to use open-source rel...
binami/mariadb-cluster          1.0.1           10.2.14     Chart to create a Highly available MariaDB cluster          
binami/mariadb-galera           0.8.2           10.4.12     MariaDB Galera is a multi-master database cluster solutio...
stable/gcloud-sqlproxy          0.2.3                       Google Cloud SQL Proxy                                      
stable/mariadb                  2.1.6           10.1.31     Fast, reliable, scalable, and easy to use open-source rel...
  • 从本地仓库列表中删除一个Chart仓库名称为binami
$ helm repo remove binami
"binami" has been removed from your repositories

$ helm repo list
NAME            URL                                                   
stable          https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
localRegistry   http://192.168.31.221:8879/charts 

Chart

通过命令helm create test01可以创建一个test01Chart目录,目录中包含了多个配置文件,如下所示

$ tree test01
test01
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   └── service.yaml
└── values.yaml
  • 生成Chart目录中有Chart.yamlvalues.yamlNOTES.txt等文件,下面分别对chart中几个重要文件解释:

    • Chart.yaml:包含了chartmetadata,描述了Chart名称、描述信息和版本号
    • values.yaml:存储了模版文件的变量
    • templates:记录全部模板文件
    • charts:依赖chart存储路径
    • NOTES.txt:给出了部署后的信息,例如如何使用char、列出默认的设置等等
  • chart安装有以下几种方式

    • 指定charthelm install stable/mariadb
    • 指定打包的charthelm install ./nginx-1.2.3.tgz
    • 指定打包目录helm install ./nginx
    • 指定chartURLhelm install https://example.com/charts/nginx-1.2.3.tgz

Helm应用部署

创建并部署Chart

  • 通过helm create命令可以创建一个Chart包,其中包含了Chart包的基本文件并且可以用来作为测试用途部署到Kubernetes集群环境中
$ helm create nginx
Creating nginx
  • 创建完成后,可以使用命令helm lint检查chart包是否存在问题
$ helm lint nginx
==> Linting nginx
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, no failures
  • 检查过后,可以使用命令helm install来完成Chart包的部署,可以通过-n参数来指定部署的release名称,如果不指定会随机生成一个。部署过程中会打印出Chart包的描述信息、资源信息及提示信息
$ helm install -n nginx nginx
NAME:   nginx
LAST DEPLOYED: Fri Mar 27 16:06:20 2020
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Pod(related)
NAME                    READY  STATUS   RESTARTS  AGE
nginx-5bb789b86d-zf7b9  0/1    Pending  0         0s

==> v1/Service

NAME   AGE
nginx  0s

==> v1beta2/Deployment
nginx  0s

NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=nginx,app.kubernetes.io/instance=nginx" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80
  • 查看部署的release信息及Kubernetes集群中创建的PodServiceserviceAccount信息。
$ helm list
NAME    REVISION    UPDATED                     STATUS      CHART       APP VERSION NAMESPACE
nginx   1           Tue Mar 10 16:14:59 2020    DEPLOYED    nginx-0.1.0 1.0         default  

$ kubectl get pods 
NAME                     READY     STATUS    RESTARTS   AGE
nginx-594bb9f979-5rtkz   1/1       Running   0          3m

$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   6d
nginx        ClusterIP   10.102.126.72   <none>        80/TCP    3m

$ kubectl get sa
NAME      SECRETS   AGE
default   1         6d
nginx     1         3m

升级、回滚部署的Release

  • 在部署Chart包后,如果需要对已部署的Release进行修改,可以通过命令helm upgrade来进行升级操作。修改Chart包内values.yaml文件内的镜像配置参数后进行升级操作
$ helm upgrade -f nginx/values.yaml --description "set image tag 1.8.0" nginx nginx/
Release "nginx" has been upgraded. Happy Helming!
LAST DEPLOYED: Fri Mar 27 16:14:43 2020
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME   AGE
nginx  8m

==> v1beta2/Deployment
nginx  8m

==> v1/Pod(related)

NAME                    READY  STATUS             RESTARTS  AGE
nginx-5bb789b86d-zf7b9  1/1    Running            0         8m
nginx-8486957c66-2xnk5  0/1    ContainerCreating  0         0s

NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=nginx,app.kubernetes.io/instance=nginx" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80
  • 升级中需要指定配置文件并可以添加升级描述信息、部署的release名称和Chart包目录,升级后查看该Chart包当前版本号已经滚动并且UPDATED时间会刷新
$ helm list 
NAME    REVISION    UPDATED                     STATUS      CHART       APP VERSION NAMESPACE
nginx   6           Tue Mar 10 16:33:52 2020    DEPLOYED    nginx-0.1.1 2.0         default
  • 查看该Release的历史记录,可以看到当前版本信息及版本的描述信息
$ helm history nginx
REVISION        UPDATED                         STATUS          CHART           DESCRIPTION
1               Fri Mar 27 16:06:20 2020        SUPERSEDED      nginx-0.1.0     Install complete
2               Fri Mar 27 16:14:43 2020        DEPLOYED        nginx-0.1.0     set image tag 1.8.0
  • 如果在升级后发现当前版本有问题,需要马上回滚到上一个版本,此时可以通过命令helm rollback来回滚到指定的版本
$  helm rollback nginx 1
Rollback was a success! Happy Helming!
  • 此时再次查看Release的历史记录,可以看到当前版本是回退到版本1的位置
$ helm history nginx
REVISION        UPDATED                         STATUS          CHART           DESCRIPTION
1               Fri Mar 27 16:06:20 2020        SUPERSEDED      nginx-0.1.0     Install complete
2               Fri Mar 27 16:14:43 2020        SUPERSEDED      nginx-0.1.0     set image tag 1.8.0
3               Fri Mar 27 16:18:11 2020        DEPLOYED        nginx-0.1.0     Rollback to 1

删除、恢复部署的Release

  • 当不再需要部署的Release时,可以通过helm delete命令来删除部署的Release。当Release被删除后,Kubernetes集群中部署的Pod也会被清空
$ helm delete nginx 
release "nginx" deleted
  • 虽然此时已经在Kubernetes集群中看不到部署的Pod,但是Helm中并没有真正删除该Release。可以通过命令helm list -a查看已经被删除的Release
$ helm list -a
NAME                REVISION    UPDATED                     STATUS  CHART           APP VERSION NAMESPACE
nginx               8           Tue Mar 10 16:41:09 2020    DELETED nginx-0.1.1     2.0         default  
  • 即使删除了Release,其发布的历史信息还是会继续被保存
$ helm history nginx
REVISION        UPDATED                         STATUS          CHART           DESCRIPTION
1               Fri Mar 27 16:06:20 2020        SUPERSEDED      nginx-0.1.0     Install complete
2               Fri Mar 27 16:14:43 2020        SUPERSEDED      nginx-0.1.0     set image tag 1.8.0
3               Fri Mar 27 16:18:11 2020        DELETED         nginx-0.1.0     Deletion complete
  • 如果此时想恢复一个被删除的Release,可以通过helm rollback命令来恢复
$ helm rollback nginx 2
Rollback was a success.
  • 此时通过命令helm list查看部署的Release时,发现被删除的Release已经恢复并且正常显示
helm list 
NAME    REVISION    UPDATED                     STATUS      CHART       APP VERSION NAMESPACE
nginx   2       Tue Mar 10 17:06:00 2020    DEPLOYED    nginx-0.1.0 1.0         default 
  • 如果想彻底删除一个release,可以添加参数--purge来执行
$ helm delete nginx --purge
release "nginx" deleted

依赖关系

Helm中,一个chart可能依赖于任何数量的其他chart。这些依赖关系可以通过requirements.yaml文件动态链接或引入charts/目录并手动管理

requirements.yaml来管理依赖关系

  • requirements.yaml文件是列出chart的依赖关系的简单文件
dependencies:
  - name: mysql
    version: 0.3.5 
    repository: https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
  • name字段是chart的名称
  • version字段是chart的版本
  • repository字段是chart repo的完整URL。请注意,还必须使用helm repo add添加该repo到本地才能使用
  • 有了依赖关系文件,你可以通过运行helm dependency update ,它会使用你的依赖关系文件将所有指定的chart下载到你的charts/目录中
$ helm dependency update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "aliyun" chart repository
...Successfully got an update from the "binami" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete.
Saving 1 charts
Downloading mysql from repo https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
Deleting outdated charts
  • helm dependency update检索chart时,它会将它们作为chart存档存储在charts/目录中。因此,对于上面的示例,可以在chart目录中看到以下文件
$ ls charts/
mysql-0.3.5.tgz

通过requirements.yaml管理chart是一种轻松更新chart的好方法,还可以在整个团队中共享requirements信息。

除上述其他字段外,每个需求条目可能包含可选字段tagscondition。所有charts都会默认加载,如果存在tagscondition字段,将对它们进行评估并用于控制应用的chart的加载。

  • tagsconditions功能介绍
  • Conditions (设置 values) 会覆盖tags配置。第一个存在的condition路径生效,后续该chartcondition路径将被忽略
  • 如果chart的某tag的任一tag的值为true,那么该tag的值为true,并启用这个chart
  • Tagsconditions值必须在顶级父级的值中进行设置
  • tags:值中的关键字必须是顶级关键字。目前不支持全局和嵌套tags:表格
  • Condition:字段包含一个或多个YAML路径(用逗号分隔)。如果此路径存在于顶级父级的值中并且解析为布尔值,则将根据该布尔值启用或禁用chart。只有在列表中找到的第一个有效路径才被评估,如果没有路径存在,那么该条件不起作用.
  • Tags:标签字段是与此chart关联的YAML标签列表。在顶级父级的值中,可以通过指定标签和布尔值来启用或禁用所有带有标签的chart
# parentchart/requirements.yaml
dependencies:
      - name: subchart1
        repository: http://localhost:10191
        version: 0.1.0
        condition: subchart1.enabled, global.subchart1.enabled
        tags:
          - front-end
          - subchart1

      - name: subchart2
        repository: http://localhost:10191
        version: 0.1.0
        condition: subchart2.enabled,global.subchart2.enabled
        tags:
          - back-end
          - subchart2
# parentchart/values.yaml
subchart1:
  enabled: true
tags:
  front-end: false
  back-end: true

在上面的示例中,所有带有标签的front-endcharts都将被禁用,但由于 subchart1.enabled的值在父项值中为“真”,因此条件将覆盖该 front-end标签,subchart1会启用。由于subchart2被标记back-end和标签的计算结果为true,subchart2将被启用。还要注意的是,虽然subchart2有一个在requirements.yaml中指定的条件,但父项的值中没有对应的路径和值,因此条件无效

使用命令行时带有tagconditions--set参数可使用来更改tagconditions

$ helm install --set tags.front-end=true --set subchart2.enabled=false

通过charts目录手动管理依赖性

  • 如果需要更多的控制依赖关系,可以通过将依赖的charts复制到charts目录中来明确表达这些依赖关系 。依赖关系可以是chart归档(.tgz)或解压缩的chart目录。但它的名字不能从_.开始,这些文件被chart加载器忽略
  • 如果WordPress chart依赖于Apache chartMySQL chart,则在WordPress chartcharts目录中提供Apache chartMySQL chart,即表示相互的依赖关系。

发表评论 取消回复
表情 图片 链接 代码

分享