Kubernetes之(二十)Helm程序包管理器

释放双眼,带上耳机,听听看~!

目录

  • Kubernetes之(二十)Helm程序包管理器

  • 概念

    • 部署Helm
  • 下载helm
    * 部署Tiller

    • helm的使用
    • chart 目录结构
    • chart模板
    • 定制安装 MySQL chart
  • chart安装准备
    * 定制化安装 chart
    * 升级和回滚release

    • 自定义chart
  • 创建chart
    * 调试chart
    * 安装chart
    * 将chart添加到仓库

    • 总结

Kubernetes之(二十)Helm程序包管理器

概念

每个成功的软件平台都有一个优秀的打包系统,比如 Debian、Ubuntu 的 apt,Redhat、Centos 的 yum。而 Helm 则是 Kubernetes 上的包管理器。
Kubernetes 能够很好地组织和编排容器,但它缺少一个更高层次的应用打包工具,而 Helm 就是来干这件事的。
举个例子,我们需要部署一个MySQL服务,Kubernetes则需要部署以下对象:
① 为了能够让外界访问到MySQL,需要部署一个mysql的service;
②需要进行定义MySQL的密码,则需要部署一个Secret;
③Mysql的运行需要持久化的数据存储,此时还需要部署PVC;
④保证后端mysql的运行,还需要部署一个Deployment,以支持以上的对象。
针对以上对象,我们可以使用YAML文件进行定义并部署,但是仅仅对于单个的服务支持,如果应用需要由一个甚至几十个这样的服务组成,并且还需要考虑各种服务的依赖问题,可想而知,这样的组织管理应用的方式就显得繁琐。为此就诞生了一个工具Helm,就是为了解决Kubernetes这种应用部署繁重的现象。

Helm的核心术语:

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

Helm的程序架构:
Helm主要由Helm客户端、Tiller服务器和Charts仓库组成,如下图:

  • helm:客户端,GO语言编写,实现管理本地的Chart仓库,可管理Chart,与Tiller服务进行交互,用于发送Chart,实例安装、查询、卸载等操作。
  • Tiller:服务端,通常运行在K8S集群之上。用于接收helm发来的Charts和Conifg,合并生成release,完成部署。

简单的说:Helm 客户端负责管理 chart;Tiller 服务器负责管理 release。

部署Helm

下载helm

Helm的部署方式有两种:预编译的二进制程序和源码编译安装,这里使用二进制的方式进行安装


1
2
3
4
5
6
7
8
9
10
1[root@master manifests]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz
2[root@master manifests]# tar xf helm-v2.9.1-linux-amd64.tar.gz
3[root@master manifests]# cd linux-amd64
4[root@master linux-amd64]# ls
5helm  LICENSE  README.md
6[root@master linux-amd64]# cp helm /usr/bin/
7
8[root@master linux-amd64]# helm version
9Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
10

部署Tiller

helm第一次init时,需要链接api-server并进行认证,所以在运行helm时,会去读取kube-config文件,所以必须确认当前用户存在kube-config文件。

Tiller运行在K8s集群之上,也必须拥有集群的管理权限,也就是需要一个serviceaccount,进行一个clusterrolebinding到cluster-admin。
Tiller的RBAC配置示例链接:

https://github.com/helm/helm/blob/master/docs/rbac.md


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
1[root@master linux-amd64]# cd ..
2[root@master manifests]# mkdir helm
3[root@master manifests]# cd helm
4[root@master helm]# vim tiller-rbac.yaml
5apiVersion: v1
6kind: ServiceAccount
7metadata:
8  name: tiller
9  namespace: kube-system
10---
11apiVersion: rbac.authorization.k8s.io/v1
12kind: ClusterRoleBinding
13metadata:
14  name: tiller
15roleRef:
16  apiGroup: rbac.authorization.k8s.io
17  kind: ClusterRole
18  name: cluster-admin
19subjects:
20  - kind: ServiceAccount
21    name: tiller
22    namespace: kube-system
23    
24
25[root@master helm]# kubectl apply -f tiller-rbac.yaml
26serviceaccount/tiller created
27clusterrolebinding.rbac.authorization.k8s.io/tiller created
28[root@master helm]# kubectl get sa -n kube-system|grep tiller
29tiller                               1         14s
30
31[root@master helm]# helm init
32Creating /root/.helm
33Creating /root/.helm/repository
34Creating /root/.helm/repository/cache
35Creating /root/.helm/repository/local
36Creating /root/.helm/plugins
37Creating /root/.helm/starters
38Creating /root/.helm/cache/archive
39Creating /root/.helm/repository/repositories.yaml
40Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
41Adding local repo with URL: http://127.0.0.1:8879/charts
42$HELM_HOME has been configured at /root/.helm.
43
44Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
45
46Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
47For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
48Happy Helming!
49
50#helm init命令进行初始化时,会用到gcr.io/kubernetes-helm中的景象,需要提前下载,镜像标签和Helm同版本号
51[root@master helm]# docker pull xiaobai20201/tiller:v2.9.1
52
53[root@master pki]#  docker tag xiaobai20201/tiller:v2.9.1 gcr.io/kubernetes-helm/tiller:v2.9.1
54
55
56[root@master helm]# kubectl get pods -n kube-system
57NAME                                     READY   STATUS    RESTARTS   AGE
58canal-nbspn                              3/3     Running   0          30h
59canal-pj6rx                              3/3     Running   0          30h
60canal-rgsnp                              3/3     Running   0          30h
61coredns-78d4cf999f-6cb69                 1/1     Running   3          14d
62coredns-78d4cf999f-tflpn                 1/1     Running   2          14d
63etcd-master                              1/1     Running   0          14d
64kube-apiserver-master                    1/1     Running   0          14d
65kube-controller-manager-master           1/1     Running   0          14d
66kube-flannel-ds-amd64-5zrk7              1/1     Running   0          31h
67kube-flannel-ds-amd64-pql5n              1/1     Running   0          31h
68kube-flannel-ds-amd64-ssd29              1/1     Running   0          31h
69kube-proxy-ch4vp                         1/1     Running   0          14d
70kube-proxy-cz2rf                         1/1     Running   1          14d
71kube-proxy-kdp7d                         1/1     Running   0          14d
72kube-scheduler-master                    1/1     Running   0          14d
73kubernetes-dashboard-6f9998798-klf4t     1/1     Running   0          2d2h
74metrics-server-v0.3.1-65bd5d59b9-xvmns   2/2     Running   0          5h31m
75tiller-deploy-c4f47c598-gl6rp            1/1     Running   0          11m
76
77#安装完成后,执行helm version可以看到客户端和服务端的版本号,两个都显示表示正常安装。
78[root@master helm]# helm version
79Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
80Server: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
81

如果希望在安装时自定义一些参数,可以参考一下的一些参数:

  • –canary-image:安装canary分支,即项目的Master分支
  • –tiller-image:安装指定版本的镜像,默认和helm同版本
  • –kube-context:安装到指定的Kubernetes集群
  • –tiller-namespace:安装到指定的名称空间,默认为kube-system

Tiller将数据存储在ConfigMap资源当中,卸载或重装不会导致数据丢失,卸载Tiller的方法有以下两种:


1
2
3
1(1)kubectl delete deployment tiller-deploy -n kube-system
2(2)helm reset
3

helm的使用

官方可用的Chart列表:

https://hub.kubeapps.com


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
1[root@master helm]# helm -h
2The Kubernetes package manager
3
4To begin working with Helm, run the 'helm init' command:
5
6        $ helm init
7
8This will install Tiller to your running Kubernetes cluster.
9It will also set up any necessary local configuration.
10
11Common actions from this point include:
12
13- helm search:    search for charts  #搜索charts
14- helm fetch:     download a chart to your local directory to view #下载charts到本地
15- helm install:   upload the chart to Kubernetes #安装charts
16- helm list:      list releases of charts #列出charts的版本
17
18Environment:
19  $HELM_HOME          set an alternative location for Helm files. By default, these are stored in ~/.helm
20  $HELM_HOST          set an alternative Tiller host. The format is host:port
21  $HELM_NO_PLUGINS    disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
22  $TILLER_NAMESPACE   set an alternative Tiller namespace (default "kube-system")
23  $KUBECONFIG         set an alternative Kubernetes configuration file (default "~/.kube/config")
24
25Usage:
26  helm [command]
27
28Available Commands:
29  completion  Generate autocompletions script for the specified shell (bash or zsh) #为指定的shell生成自动补全脚本(bash或zsh)
30  create      create a new chart with the given name #创建一个新的charts
31  delete      given a release name, delete the release from Kubernetes #删除指定版本的release
32  dependency  manage a chart's dependencies # 管理charts的依赖
33  fetch       download a chart from a repository and (optionally) unpack it in local directory #  下载charts并解压到本地目录
34  get         download a named release# 下载一个release
35  history     fetch release history #release历史信息
36  home        displays the location of HELM_HOME #显示helm的家目录
37  init        initialize Helm on both client and server #在客户端和服务端初始化helm
38  inspect     inspect a chart #查看charts的详细信息
39  install     install a chart archive #安装charts
40  lint        examines a chart for possible issues #检测包的存在问题
41  list        list releases #列出release
42  package     package a chart directory into a chart archive # 将chart目录进行打包
43  plugin      add, list, or remove Helm plugins #add(增加), list(列出), or remove(移除) Helm 插件
44  repo        add, list, remove, update, and index chart repositories #add(增加), list(列出), remove(移除), update(更新), and index(索引) chart仓库
45  reset       uninstalls Tiller from a cluster #卸载tiller
46  rollback    roll back a release to a previous revision #release版本回滚
47  search      search for a keyword in charts#  关键字搜索chart
48  serve       start a local http web server # 启动一个本地的http server
49  status      displays the status of the named release #查看release状态信息
50  template    locally render templates #本地模板
51  test        test a release # release测试
52  upgrade     upgrade a release #release更新
53  verify      verify that a chart at the given path has been signed and is valid  #验证chart的签名和有效期
54  version     print the client/server version information #打印客户端和服务端的版本信息
55

Charts是Helm的程序包,它们都存在在Charts仓库当中。Kubernetes官方的仓库保存了一系列的Charts,仓库默认的名称为stable。安装Charts到集群时,Helm首先会到官方仓库获取相关的Charts,并创建release。可执行 helm search 查看当前可安装的 chart 。
Helm 可以像 yum 管理软件包一样管理 chart。 yum 的软件包存放在仓库中,同样的,Helm 也有仓库。
Helm 安装时已经默认配置好了两个仓库:stable 和 local。stable 是官方仓库,local 是用户存放自己开发的chart的本地仓库。可以通过helm repo list进行查看。由于网络原因,国内可能无法更新仓库源(网络不稳定偶尔出问题),这里可以更改为阿里云的仓库源,。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1[root@master helm]# helm repo remove stable
2"stable" has been removed from your repositories
3[root@master helm]#
4[root@master helm]# helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
5"stable" has been added to your repositories
6[root@master helm]#
7[root@master helm]# helm repo update
8Hang tight while we grab the latest from your chart repositories...
9...Skip local chart repository
10...Successfully got an update from the "stable" chart repository
11Update Complete. ⎈ Happy Helming!⎈
12[root@master helm]# helm repo list
13NAME    URL                                                  
14local   http://127.0.0.1:8879/charts                          
15stable  https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
16

与 yum 一样,helm 也支持关键字搜索:


1
2
3
4
5
1[root@master helm]# helm search stable/mysql
2NAME                    CHART VERSION   APP VERSION     DESCRIPTION                                      
3stable/mysql            0.15.0          5.7.14          Fast, reliable, scalable, and easy to use open-...
4stable/mysqldump        2.4.0           2.4.0           A Helm chart to help backup MySQL databases usi..
5

使用helm inspect也可以查看详细信息


1
2
1[root@master helm]# helm inspect stable/mysql
2

包括 DESCRIPTION 在内的所有信息,只要跟关键字匹配,都会显示在结果列表中。
安装 chart 也很简单,执行如下命令可以安装 MySQL。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
1[root@master helm]# helm install stable/mysql
2Error: no available release name found
3#出现此类报错主要是tiller权限的问题
4[root@master helm]# kubectl create serviceaccount --namespace kube-system tiller
5Error from server (AlreadyExists): serviceaccounts "tiller" already exists
6[root@master helm]# kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
7clusterrolebinding.rbac.authorization.k8s.io/tiller-cluster-rule created
8[root@master helm]# kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
9deployment.extensions/tiller-deploy patched (no change)
10
11#再次安装
12[root@master helm]# helm install stable/mysql
13NAME:   callous-zorse  #第一部分
14LAST DEPLOYED: Thu Apr 11 09:31:41 2019
15NAMESPACE: default
16STATUS: DEPLOYED
17
18RESOURCES:   #第二部分
19==> v1/Secret
20NAME                 TYPE    DATA  AGE
21callous-zorse-mysql  Opaque  2     0s
22
23==> v1/ConfigMap
24NAME                      DATA  AGE
25callous-zorse-mysql-test  1     0s
26
27==> v1/PersistentVolumeClaim
28NAME                 STATUS   VOLUME  CAPACITY  ACCESS MODES  STORAGECLASS  AGE
29callous-zorse-mysql  Pending  0s
30
31==> v1/Service
32NAME                 TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)   AGE
33callous-zorse-mysql  ClusterIP  10.109.125.202  <none>       3306/TCP  0s
34
35==> v1beta1/Deployment
36NAME                 DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
37callous-zorse-mysql  1        1        1           0          0s
38
39==> v1/Pod(related)
40NAME                                 READY  STATUS   RESTARTS  AGE
41callous-zorse-mysql-f5c97689b-ch5cf  0/1    Pending  0         0s
42
43
44NOTES:  #第三部分
45MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
46callous-zorse-mysql.default.svc.cluster.local
47
48To get your root password run:
49
50    MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default callous-zorse-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)
51
52To connect to your database:
53
541. Run an Ubuntu pod that you can use as a client:
55
56    kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il
57
582. Install the mysql client:
59
60    $ apt-get update && apt-get install mysql-client -y
61
623. Connect using the mysql cli, then provide your password:
63    $ mysql -h callous-zorse-mysql -p
64
65To connect to your database directly from outside the K8s cluster:
66    MYSQL_HOST=127.0.0.1
67    MYSQL_PORT=3306
68
69    # Execute the following command to route the connection:
70    kubectl port-forward svc/callous-zorse-mysql 3306
71
72    mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
73
74

输出分为三部分:

  1. chart 本次部署的描述信息:

NAME 是 release 的名字,因为我们没用 -n 参数指定,Helm 随机生成了一个,这里是 callous-zorse。
NAMESPACE 是 release 部署的 namespace,默认是 default,也可以通过 –namespace 指定。
STATUS 为 DEPLOYED,表示已经将 chart 部署到集群。

  1. 当前 release 包含的资源:Service、Deployment、Secret 和 PersistentVolumeClaim,其名字都是 callous-zorse-mysql,命名的格式为 ReleasName-ChartName。
  2. NOTES 部分显示的是 release 的使用方法。比如如何访问 Service,如何获取数据库密码,以及如何连接数据库等。

通过 kubectl get 可以查看组成 release 的各个对象:


1
2
3
4
5
6
7
8
9
10
11
12
13
1[root@master helm]# kubectl get deploy,svc,pvc,secret callous-zorse-mysql
2NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
3deployment.extensions/callous-zorse-mysql   0/1     1            0           10m
4
5NAME                          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
6service/callous-zorse-mysql   ClusterIP   10.109.125.202   <none>        3306/TCP   10m
7
8NAME                                        STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
9persistentvolumeclaim/callous-zorse-mysql   Pending                                                     10m
10
11NAME                         TYPE     DATA   AGE
12secret/callous-zorse-mysql   Opaque   2      10m
13

由于我们还没有准备 PersistentVolume,当前 release 还不可用。

helm list 显示已经部署的 release,helm delete 可以删除 release。


1
2
3
4
5
6
1[root@master helm]# helm list
2NAME            REVISION        UPDATED                         STATUS          CHART           NAMESPACE
3callous-zorse   1               Thu Apr 11 09:31:41 2019        DEPLOYED        mysql-0.15.0    default  
4[root@master helm]# helm delete callous-zorse
5release "callous-zorse" deleted
6

chart 目录结构

chart 是 Helm 的应用打包格式。chart 由一系列文件组成,这些文件描述了 Kubernetes 部署应用时所需要的资源,比如 Service、Deployment、PersistentVolumeClaim、Secret、ConfigMap 等。

单个的 chart 可以非常简单,只用于部署一个服务,比如 Memcached;chart 也可以很复杂,部署整个应用,比如包含 HTTP Servers、 Database、消息中间件、cache 等。

chart 将这些文件放置在预定义的目录结构中,通常整个 chart 被打成 tar 包,而且标注上版本信息,便于 Helm 部署。

以前面 MySQL chart为例。一旦安装了某个 chart,我们就可以在 ~/.helm/cache/archive 中找到 chart 的 tar 包。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
1[root@master ~]# cd .helm/cache/archive/  
2[root@master archive]# ls
3mysql-0.15.0.tgz
4
5[root@master archive]# tar xf mysql-0.15.0.tgz  
6tar: mysql/Chart.yaml:不可信的旧时间戳 1970-01-01 08:00:00
7tar: mysql/values.yaml:不可信的旧时间戳 1970-01-01 08:00:00
8tar: mysql/templates/NOTES.txt:不可信的旧时间戳 1970-01-01 08:00:00
9tar: mysql/templates/_helpers.tpl:不可信的旧时间戳 1970-01-01 08:00:00
10tar: mysql/templates/configurationFiles-configmap.yaml:不可信的旧时间戳 1970-01-01 08:00:00
11tar: mysql/templates/deployment.yaml:不可信的旧时间戳 1970-01-01 08:00:00
12tar: mysql/templates/initializationFiles-configmap.yaml:不可信的旧时间戳 1970-01-01 08:00:00
13tar: mysql/templates/pvc.yaml:不可信的旧时间戳 1970-01-01 08:00:00
14tar: mysql/templates/secrets.yaml:不可信的旧时间戳 1970-01-01 08:00:00
15tar: mysql/templates/svc.yaml:不可信的旧时间戳 1970-01-01 08:00:00
16tar: mysql/templates/tests/test-configmap.yaml:不可信的旧时间戳 1970-01-01 08:00:00
17tar: mysql/templates/tests/test.yaml:不可信的旧时间戳 1970-01-01 08:00:00
18tar: mysql/.helmignore:不可信的旧时间戳 1970-01-01 08:00:00
19tar: mysql/README.md:不可信的旧时间戳 1970-01-01 08:00:00
20
21[root@master archive]# tree
22.
23├── mysql
24│   ├── Chart.yaml
25│   ├── README.md
26│   ├── templates
27│   │   ├── configurationFiles-configmap.yaml
28│   │   ├── deployment.yaml
29│   │   ├── _helpers.tpl
30│   │   ├── initializationFiles-configmap.yaml
31│   │   ├── NOTES.txt
32│   │   ├── pvc.yaml
33│   │   ├── secrets.yaml
34│   │   ├── svc.yaml
35│   │   └── tests
36│   │       ├── test-configmap.yaml
37│   │       └── test.yaml
38│   └── values.yaml
39└── mysql-0.15.0.tgz
40
413 directories, 14 files
42
  • Chart.yaml:YAML 文件,描述 chart 的概要信息。
  • README.md:Markdown 格式的 README 文件,相当于 chart 的使用文档,此文件为可选。
  • LICENSE:文本文件,描述 chart 的许可信息,此文件为可选。
  • requirements.yaml :chart 可能依赖其他的 chart,这些依赖关系可通过 requirements.yaml 指定。
  • values.yaml:chart 支持在安装的时根据参数进行定制化配置,而 values.yaml 则提供了这些配置参数的默认值。
  • templates目录:各类 Kubernetes 资源的配置模板都放置在这里。Helm 会将 values.yaml 中的参数值注入到模板中生成标准的 YAML 配置文件。
  • templates/NOTES.txt:chart 的简易使用文档,chart 安装成功后会显示此文档内容。 与模板一样,可以在 NOTE.txt 中插入配置参数,Helm 会动态注入参数值。

chart模板

Helm 通过模板创建 Kubernetes 能够理解的 YAML 格式的资源配置文件,我们将通过例子来学习如何使用模板。
以 templates/secrets.yaml 为例:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
1{{- if not .Values.existingSecret }}
2apiVersion: v1
3kind: Secret
4metadata:
5  name: {{ template "mysql.fullname" . }}
6  labels:
7    app: {{ template "mysql.fullname" . }}
8    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
9    release: "{{ .Release.Name }}"
10    heritage: "{{ .Release.Service }}"
11type: Opaque
12data:
13  {{ if .Values.mysqlRootPassword }}
14  mysql-root-password:  {{ .Values.mysqlRootPassword | b64enc | quote }}
15  {{ else }}
16  mysql-root-password: {{ randAlphaNum 10 | b64enc | quote }}
17  {{ end }}
18  {{ if .Values.mysqlPassword }}
19  mysql-password:  {{ .Values.mysqlPassword | b64enc | quote }}
20  {{ else }}
21  mysql-password: {{ randAlphaNum 10 | b64enc | quote }}
22  {{ end }}
23{{- if .Values.ssl.enabled }}
24{{ if .Values.ssl.certificates }}
25{{- range .Values.ssl.certificates }}
26---
27apiVersion: v1
28kind: Secret
29metadata:
30  name: {{ .name }}
31  labels:
32    app: {{ template "mysql.fullname" $ }}
33    chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
34    release: "{{ $.Release.Name }}"
35    heritage: "{{ $.Release.Service }}"
36type: Opaque
37data:
38  ca.pem: {{ .ca | b64enc }}
39  server-cert.pem: {{ .cert | b64enc }}
40  server-key.pem: {{ .key | b64enc }}
41{{- end }}
42{{- end }}
43{{- end }}
44{{- end }}
45

从结构上看,文件的内容和我们在定义Secret的配置上大致相似,只是大部分的属性值变成了{{ xxx }}。这些{{ xx }}实际上是模板的语法。Helm采用了Go语言的模板来编写chart。

  • {{ template "mysql.fullname" . }} 定义 Secret 的 name

关键字 template 的作用是引用一个子模板 mysql.fullname。这个子模板是在 templates/_helpers.tpl 文件中定义的。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1[root@master templates]# vim _helpers.tpl
2......
3If release name contains chart name it will be used as a full name.
4*/}}
5{{- define "mysql.fullname" -}}
6{{- if .Values.fullnameOverride -}}
7{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
8{{- else -}}
9{{- $name := default .Chart.Name .Values.nameOverride -}}
10{{- if contains $name .Release.Name -}}
11{{- printf .Release.Name | trunc 63 | trimSuffix "-" -}}
12{{- else -}}
13{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
14{{- end -}}
15{{- end -}}
16{{- end -}}
17......
18

这个定义还是很复杂的,因为它用到了模板语言中的对象、函数、流控制等概念。现在看不懂没关系,这里我们学习的重点是:如果存在一些信息多个模板都会用到,则可在 templates/_helpers.tpl 中将其定义为子模板,然后通过 templates 函数引用。
这里 mysql.fullname 是由 release 与 chart 二者名字拼接组成。
根据 chart 的最佳实践,所有资源的名称都应该保持一致,对于我们这个 chart,无论 Secret 还是 Deployment、PersistentVolumeClaim、Service,它们的名字都是子模板 mysql.fullname 的值。

  • Chart 和 Release 是 Helm 预定义的对象,每个对象都有自己的属性,可以在模板中使用。如果使用下面命令安装 chart:


1
2
3
4
5
6
1[root@master templates]# helm search stable/mysql
2NAME                    CHART VERSION   APP VERSION     DESCRIPTION                                      
3stable/mysql            0.15.0          5.7.14          Fast, reliable, scalable, and easy to use open-...
4stable/mysqldump        2.4.0           2.4.0           A Helm chart to help backup MySQL databases usi...
5[root@master templates]# helm install stable/mysql -n my
6


{{ .Chart.Name }} 的值为 mysql。
{{ .Chart.Version }} 的值为 0.15.0。
{{ .Release.Name }}的值为 my。
{{ .Release.Service }} 始终取值为 Tiller.
{{ template "mysql.fullname" . }} 计算结果为 my-mysql。

  • 这里指定 mysql-root-password 的值,不过使用了 if-else 的流控制,其逻辑为:

如果 .Values.mysqlRootPassword有值,则对其进行 base64 编码;否则随机生成一个 10 位的字符串并编码。

Values 也是预定义的对象,代表的是values.yaml 文件。而 .Values.mysqlRootPassword 则是values.yaml中定义的 mysqlRootPassword参数:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1[root@master mysql]# vim values.yaml
2## mysql image version
3## ref: https://hub.docker.com/r/library/mysql/tags/
4##
5image: "mysql"
6imageTag: "5.7.14"
7
8busybox:
9  image: "busybox"
10  tag: "1.29.3"
11
12testFramework:
13  image: "dduportal/bats"
14  tag: "0.4.0"
15
16## Specify password for root user
17##
18## Default: random 10 character string
19# mysqlRootPassword: testing
20
21## Create a database user
22##
23# mysqlUser:
24## Default: random 10 character string
25# mysqlPassword:
26

因为 mysqlRootPassword 被注释掉了,没有赋值,所以逻辑判断会走 else,即随机生成密码。

randAlphaNum、b64enc、quote 都是 Go 模板语言支持的函数,函数之间可以通过管道 | 连接。
{{ randAlphaNum 10 | b64enc | quote }} 的作用是首先随机产生一个长度为 10 的字符串,然后将其 base64 编码,最后两边加上双引号。
templates/secrets.yaml 这个例子展示了chart 模板主要的功能,我们最大的收获应该是:模板将 chart参数化了,通过 values.yaml 可以灵活定制应用。

无论多复杂的应用,用户都可以用 Go 模板语言编写出 chart。无非是使用到更多的函数、对象和流控制

定制安装 MySQL chart

chart安装准备

作为准备工作,安装之前需要先清楚 chart 的使用方法。这些信息通常记录在 values.yaml 和 README.md 中。除了下载源文件查看,执行 helm inspect values 可能是更方便的方法。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
1[root@master helm]# helm inspect values stable/mysql      
2## mysql image version
3## ref: https://hub.docker.com/r/library/mysql/tags/
4##
5image: "mysql"
6imageTag: "5.7.14"
7
8busybox:
9  image: "busybox"
10  tag: "1.29.3"
11
12testFramework:
13  image: "dduportal/bats"
14  tag: "0.4.0"
15
16## Specify password for root user
17##
18## Default: random 10 character string
19# mysqlRootPassword: testing
20
21## Create a database user
22##
23# mysqlUser:
24## Default: random 10 character string
25# mysqlPassword:
26
27## Allow unauthenticated access, uncomment to enable
28##
29# mysqlAllowEmptyPassword: true
30
31## Create a database
32##
33# mysqlDatabase:
34
35## Specify an imagePullPolicy (Required)
36## It's recommended to change this to 'Always' if the image tag is 'latest'
37## ref: http://kubernetes.io/docs/user-guide/images/#updating-images
38##
39imagePullPolicy: IfNotPresent
40
41extraVolumes: |
42  # - name: extras
43  #   emptyDir: {}
44
45extraVolumeMounts: |
46  # - name: extras
47  #   mountPath: /usr/share/extras
48  #   readOnly: true
49
50extraInitContainers: |
51  # - name: do-something
52  #   image: busybox
53  #   command: ['do', 'something']
54
55# Optionally specify an array of imagePullSecrets.
56# Secrets must be manually created in the namespace.
57# ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
58# imagePullSecrets:
59  # - name: myRegistryKeySecretName
60
61## Node selector
62## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
63nodeSelector: {}
64
65## Tolerations for pod assignment
66## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
67##
68tolerations: []
69
70livenessProbe:
71  initialDelaySeconds: 30
72  periodSeconds: 10
73  timeoutSeconds: 5
74  successThreshold: 1
75  failureThreshold: 3
76
77readinessProbe:
78  initialDelaySeconds: 5
79  periodSeconds: 10
80  timeoutSeconds: 1
81  successThreshold: 1
82  failureThreshold: 3
83
84## Persist data to a persistent volume
85persistence:
86  enabled: true
87  ## database data Persistent Volume Storage Class
88  ## If defined, storageClassName: <storageClass>
89  ## If set to "-", storageClassName: "", which disables dynamic provisioning
90  ## If undefined (the default) or set to null, no storageClassName spec is
91  ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
92  ##   GKE, AWS & OpenStack)
93  ##
94  # storageClass: "-"
95  accessMode: ReadWriteOnce
96  size: 8Gi
97  annotations: {}
98
99## Configure resource requests and limits
100## ref: http://kubernetes.io/docs/user-guide/compute-resources/
101##
102resources:
103  requests:
104    memory: 256Mi
105    cpu: 100m
106
107# Custom mysql configuration files used to override default mysql settings
108configurationFiles: {}
109#  mysql.cnf: |-
110#    [mysqld]
111#    skip-name-resolve
112#    ssl-ca=/ssl/ca.pem
113#    ssl-cert=/ssl/server-cert.pem
114#    ssl-key=/ssl/server-key.pem
115
116# Custom mysql init SQL files used to initialize the database
117initializationFiles: {}
118#  first-db.sql: |-
119#    CREATE DATABASE IF NOT EXISTS first DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
120#  second-db.sql: |-
121#    CREATE DATABASE IF NOT EXISTS second DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
122
123metrics:
124  enabled: false
125  image: prom/mysqld-exporter
126  imageTag: v0.10.0
127  imagePullPolicy: IfNotPresent
128  resources: {}
129  annotations: {}
130    # prometheus.io/scrape: "true"
131    # prometheus.io/port: "9104"
132  livenessProbe:
133    initialDelaySeconds: 15
134    timeoutSeconds: 5
135  readinessProbe:
136    initialDelaySeconds: 5
137    timeoutSeconds: 1
138
139## Configure the service
140## ref: http://kubernetes.io/docs/user-guide/services/
141service:
142  annotations: {}
143  ## Specify a service type
144  ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types
145  type: ClusterIP
146  port: 3306
147  # nodePort: 32000
148
149ssl:
150  enabled: false
151  secret: mysql-ssl-certs
152  certificates:
153#  - name: mysql-ssl-certs
154#    ca: |-
155#      -----BEGIN CERTIFICATE-----
156#      ...
157#      -----END CERTIFICATE-----
158#    cert: |-
159#      -----BEGIN CERTIFICATE-----
160#      ...
161#      -----END CERTIFICATE-----
162#    key: |-
163#      -----BEGIN RSA PRIVATE KEY-----
164#      ...
165#      -----END RSA PRIVATE KEY-----
166
167## Populates the 'TZ' system timezone environment variable
168## ref: https://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html
169##
170## Default: nil (mysql will use image's default timezone, normally UTC)
171## Example: 'Australia/Sydney'
172# timezone:
173
174# To be added to the database server pod(s)
175podAnnotations: {}
176
177podLabels: {}
178
179## Set pod priorityClassName
180# priorityClassName: {}
181

输出的实际上是 values.yaml 的内容。阅读注释就可以知道 MySQL chart 支持哪些参数,安装之前需要做哪些准备。其中有一部分是关于存储的:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1## Persist data to a persistent volume
2persistence:
3  enabled: true
4  ## database data Persistent Volume Storage Class
5  ## If defined, storageClassName: <storageClass>
6  ## If set to "-", storageClassName: "", which disables dynamic provisioning
7  ## If undefined (the default) or set to null, no storageClassName spec is
8  ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
9  ##   GKE, AWS & OpenStack)
10  ##
11  # storageClass: "-"
12  accessMode: ReadWriteOnce
13  size: 8Gi
14  annotations: {}
15

chart 定义了一个 PersistentVolumeClaim,申请 8G 的 PersistentVolume。由于我们的实验环境不支持动态供给,所以得预先创建好相应的 PV,其配置文件 mysql-pv.yml 内容为:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1
2[root@master helm]# cd ../volume/
3[root@master volume]# vim mysql-pv.yaml
4
5apiVersion: v1
6kind: PersistentVolume
7metadata:
8  name: mysql-pv2
9spec:
10  accessModes:
11    - ReadWriteOnce
12  capacity:
13    storage: 8Gi
14  persistentVolumeReclaimPolicy: Retain
15  nfs:
16    path: /data/volume/db
17    server: nfs
18    
19[root@master volume]# kubectl apply -f mysql-pv.yaml
20persistentvolume/mysql-pv2 created
21[root@master volume]# kubectl get pv  
22NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                       STORAGECLASS   REASON   AGE
23mysql-pv2   8Gi        RWO            Retain           Bound       default/my-mysql                                    30s
24

定制化安装 chart

除了接受 values.yaml 的默认值,我们还可以定制化 chart,比如设置 mysqlRootPassword
Helm有两种方式传递配置参数:

  • 指定自己的values文件,通常是先通过helm inspect values mysql > myvalues.yaml生成values,然后设置mysqlRootPassword之后执行 helm install –values=myvalues.yaml mysql

  • 通过 –set 直接传入参数值,比如:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1[root@master helm]# helm install stable/mysql --set mysqlRootPassword=abc123 -n my-2
2NAME:   my-2
3LAST DEPLOYED: Thu Apr 11 11:26:33 2019
4NAMESPACE: default
5STATUS: DEPLOYED
6RESOURCES:
7==> v1/Service
8NAME        TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)   AGE
9my-2-mysql  ClusterIP  10.97.198.107  <none>       3306/TCP  1s
10
11==> v1beta1/Deployment
12NAME        DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
13my-2-mysql  1        1        1           0          1s
14
15==> v1/Pod(related)
16NAME                         READY  STATUS   RESTARTS  AGE
17my-2-mysql-5dc69d7d66-rmt2z  0/1    Pending  0         1s
18
19==> v1/Secret
20NAME        TYPE    DATA  AGE
21my-2-mysql  Opaque  2     1s
22
23==> v1/ConfigMap
24NAME             DATA  AGE
25my-2-mysql-test  1     1s
26
27==> v1/PersistentVolumeClaim
28NAME        STATUS   VOLUME  CAPACITY  ACCESS MODES  STORAGECLASS  AGE
29my-2-mysql  Pending  1s
30......
31

mysqlRootPassword设置为 abc123。另外,-n设置elease 为 my-2,各类资源的名称即为my-2-mysql。

通过 helm list 和helm status 可以查看 chart 的最新状态。

升级和回滚release

release 发布后可以执行 helm upgrade 对其升级,通过 –values 或 –set应用新的配置。比如将当前的 MySQL 版本升级到 5.7.15:


1
2
1[root@master helm]# helm upgrade --set imageTag=5.7.15 my stable/mysql
2

helm history 可以查看 release 所有的版本。通过 helm rollback 可以回滚到任何版本。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
1[root@master helm]# helm history my-2
2REVISION        UPDATED                         STATUS          CHART           DESCRIPTION    
31               Thu Apr 11 11:26:33 2019        SUPERSEDED      mysql-0.15.0    Install complete
42               Thu Apr 11 11:29:41 2019        DEPLOYED        mysql-0.15.0    Upgrade complete
5
6[root@master helm]# helm rollback my-2 1
7Rollback was a success! Happy Helming!
8
9[root@master helm]# helm history my-2
10REVISION        UPDATED                         STATUS          CHART           DESCRIPTION    
111               Thu Apr 11 11:26:33 2019        SUPERSEDED      mysql-0.15.0    Install complete
122               Thu Apr 11 11:29:41 2019        SUPERSEDED      mysql-0.15.0    Upgrade complete
133               Thu Apr 11 11:30:21 2019        DEPLOYED        mysql-0.15.0    Rollback to 1
14

自定义chart

Kubernetes 给我们提供了大量官方 chart,不过要部署微服务应用,还是需要开发自己的 chart。

创建chart

执行 helm create mychart 的命令创建 chart mychart:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1[root@master helm]# cd mychart/
2[root@master mychart]# tree
3.
4├── charts
5├── Chart.yaml
6├── templates
7│   ├── deployment.yaml
8│   ├── _helpers.tpl
9│   ├── ingress.yaml
10│   ├── NOTES.txt
11│   └── service.yaml
12└── values.yaml
13
142 directories, 7 files
15

Helm 会帮我们创建目录 mychart,并生成了各类 chart 文件。这样我们就可以在此基础上开发自己的 chart 了。

调试chart

elm 提供了 debug 的工具:helm lint 和 helm install –dry-run –debug。
helm lint会检测 chart 的语法,报告错误以及给出建议。 故意修改mychart中的value.yaml,进行检测:
helm lint mychart会指出这个语法错误。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1[root@master helm]# helm lint mychart
2==> Linting mychart
3[INFO] Chart.yaml: icon is recommended
4[ERROR] values.yaml: unable to parse YAML
5        error converting YAML to JSON: yaml: line 12: could not find expected ':'
6
7Error: 1 chart(s) linted, 1 chart(s) failed
8
91 chart(s) linted, no failures
10[root@master helm]# helm lint mychart
11==> Linting mychart
12[INFO] Chart.yaml: icon is recommended
13
141 chart(s) linted, no failures
15

helm install –dry-run –debug 会模拟安装 chart,并输出每个模板生成的 YAML 内容。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
1[root@master helm]# helm install --dry-run mychart --debug
2[debug] Created tunnel using local port: '28515'
3
4[debug] SERVER: "127.0.0.1:28515"
5
6[debug] Original chart version: ""
7[debug] CHART PATH: /root/manifests/helm/mychart
8
9NAME:   early-marsupial
10REVISION: 1
11RELEASED: Thu Apr 11 11:40:39 2019
12CHART: mychart-0.1.0
13USER-SUPPLIED VALUES:
14{}
15
16COMPUTED VALUES:
17affinity: {}
18image:
19  pullPolicy: IfNotPresent
20  repository: nginx
21  tag: stable
22ingress:
23  annotations: {}
24  enabled: false
25  hosts:
26  - chart-example.local
27  path: /
28  tls: []
29nodeSelector: {}
30replicaCount: 1
31resources: {}
32service:
33  port: 80
34  type: ClusterIP
35tolerations: []
36
37HOOKS:
38MANIFEST:
39
40---
41# Source: mychart/templates/service.yaml
42apiVersion: v1
43kind: Service
44metadata:
45  name: early-marsupial-mychart
46  labels:
47    app: mychart
48    chart: mychart-0.1.0
49    release: early-marsupial
50    heritage: Tiller
51spec:
52  type: ClusterIP
53  ports:
54    - port: 80
55      targetPort: http
56      protocol: TCP
57      name: http
58  selector:
59    app: mychart
60    release: early-marsupial
61---
62# Source: mychart/templates/deployment.yaml
63apiVersion: apps/v1beta2
64kind: Deployment
65metadata:
66  name: early-marsupial-mychart
67  labels:
68    app: mychart
69    chart: mychart-0.1.0
70    release: early-marsupial
71    heritage: Tiller
72spec:
73  replicas: 1
74  selector:
75    matchLabels:
76      app: mychart
77      release: early-marsupial
78  template:
79    metadata:
80      labels:
81        app: mychart
82        release: early-marsupial
83    spec:
84      containers:
85        - name: mychart
86          image: "nginx:stable"
87          imagePullPolicy: IfNotPresent
88          ports:
89            - name: http
90              containerPort: 80
91              protocol: TCP
92          livenessProbe:
93            httpGet:
94              path: /
95              port: http
96          readinessProbe:
97            httpGet:
98              path: /
99              port: http
100          resources:
101            {}
102

我们可以检视这些输出,判断是否与预期相符。

安装chart

Helm自持四种方法安装chart:

  • 安装仓库中的 chart,例如:helm install stable/nginx
  • 通过 tar 包安装,例如:helm install ./nginx-1.2.3.tgz
  • 通过 chart 本地目录安装,例如:helm install ./nginx
  • 通过 URL 安装,例如:helm install https://example.com/charts/nginx-1.2.3.tgz

本次使用本地目录安装


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1[root@master helm]# helm install ./mychart/
2NAME:   soft-worm
3LAST DEPLOYED: Thu Apr 11 13:43:18 2019
4NAMESPACE: default
5STATUS: DEPLOYED
6
7RESOURCES:
8==> v1beta2/Deployment
9NAME               DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
10soft-worm-mychart  1        1        1           0          0s
11
12==> v1/Pod(related)
13NAME                               READY  STATUS   RESTARTS  AGE
14soft-worm-mychart-78ccf58c6-t6jp5  0/1    Pending  0         0s
15
16==> v1/Service
17NAME               TYPE       CLUSTER-IP    EXTERNAL-IP  PORT(S)  AGE
18soft-worm-mychart  ClusterIP  10.103.92.36  <none>       80/TCP   0s
19
20
21NOTES:
221. Get the application URL by running these commands:
23  export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=soft-worm" -o jsonpath="{.items[0].metadata.name}")
24  echo "Visit http://127.0.0.1:8080 to use your application"
25  kubectl port-forward $POD_NAME 8080:80
26

当 chart 部署到 Kubernetes 集群,便可以对其进行更为全面的测试。

将chart添加到仓库

chart 通过测试后可以将其添加到仓库,团队其他成员就能够使用。任何 HTTP Server 都可以用作 chart 仓库,下面演示在 nfs 10.0.0.14 上搭建仓库。

在nfs上启动nginx(容器也可以)并创建一个server标签(由于实验用nfs已经有nginx服务,新建个server标签监听8080端口)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
1......
2    server {
3        listen       8080;
4        location / {
5        root         /data/;
6        }
7        # Load configuration files for the default server block.
8        include /etc/nginx/default.d/*.conf;
9
10        }
11.....
12[root@nfs ~]# mkdir /data/charts/ -p
13[root@nfs ~]#  nginx -s reload
14

通过 helm package 将 mychart 打包。


1
2
3
4
5
6
7
8
9
10
11
1[root@master helm]# helm package ./mychart/
2Successfully packaged chart and saved it to: /root/manifests/helm/mychart-0.1.0.tgz
3#执行 helm repo index 生成仓库的 index 文件
4[root@master helm]# helm package ./mychart/
5Successfully packaged chart and saved it to: /root/manifests/helm/mychart-0.1.0.tgz
6[root@master helm]# mkdir myrepo
7[root@master helm]# mv /root/manifests/helm/mychart-0.1.0.tgz ./myrepo/
8[root@master helm]# helm repo index ./myrepo/ --url http://10.0.0.14:8080/charts
9[root@master helm]# ls myrepo/
10index.yaml  mychart-0.1.0.tgz
11

Helm 会扫描 myrepo 目录中的所有 tgz 包并生成 index.yaml。–url指定的是新仓库的访问路径。新生成的 index.yaml 记录了当前仓库中所有 chart 的信息:
当前只有 mychart 这一个 chart。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1[root@master helm]# cat myrepo/index.yaml
2apiVersion: v1
3entries:
4  mychart:
5  - apiVersion: v1
6    appVersion: "1.0"
7    created: 2019-04-11T14:18:48.494631141+08:00
8    description: A Helm chart for Kubernetes
9    digest: 08abeb3542e8a9ab90df776d3a646199da8be0ebfc5198ef032190938d49e30a
10    name: mychart
11    urls:
12    - http://10.0.0.14:8080/charts/mychart-0.1.0.tgz
13    version: 0.1.0
14generated: 2019-04-11T14:18:48.494210001+08:00
15

将 mychart-0.1.0.tgz 和 index.yaml 上传到 k8s-node1 的 /var/www/charts 目录。


1
2
3
4
1[root@master helm]# scp ./myrepo/* nfs:/data/charts/
2index.yaml                                                              100%  394   407.6KB/s   00:00    
3mychart-0.1.0.tgz                                                       100% 2556     2.8MB/s   00:00  
4

通过 helm repo add 将新仓库添加到 Helm。


1
2
3
4
5
6
7
8
1[root@master helm]# helm repo add nfs_repo http://10.0.0.14:8080/charts
2"nfs_repo" has been added to your repositories
3[root@master helm]# helm repo list
4NAME            URL                                            
5stable          https://kubernetes-charts.storage.googleapis.com
6local           http://127.0.0.1:8879/charts                    
7nfs_repo        http://10.0.0.14:8080/charts  
8

现在已经可以 repo search 到 mychart 了。
[root@master helm]# helm search mychart NAME CHART VERSION APP VERSION DESCRIPTION local/mychart 0.1.0 1.0 A Helm chart for Kubernetes nfs_repo/mychart 0.1.0 1.0 A Helm chart for Kubernetes
除了 newrepo/mychart,这里还有一个 local/mychart。这是因为在执行打包操作的同时,mychart 也被同步到了 local 的仓库。

已经可以直接从新仓库安装 mychart 了。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1[root@master helm]# helm install --name my-3 nfs_repo/mychart
2NAME:   my-3
3LAST DEPLOYED: Thu Apr 11 14:26:53 2019
4NAMESPACE: default
5STATUS: DEPLOYED
6
7RESOURCES:
8==> v1/Pod(related)
9NAME                           READY  STATUS             RESTARTS  AGE
10my-3-mychart-69cdddc4fb-cljmt  0/1    ContainerCreating  0         0s
11
12==> v1/Service
13NAME          TYPE       CLUSTER-IP    EXTERNAL-IP  PORT(S)  AGE
14my-3-mychart  ClusterIP  10.97.149.58  <none>       80/TCP   0s
15
16==> v1beta2/Deployment
17NAME          DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
18my-3-mychart  1        1        1           0          0s
19
20
21NOTES:
221. Get the application URL by running these commands:
23  export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=my-3" -o jsonpath="{.items[0].metadata.name}")
24  echo "Visit http://127.0.0.1:8080 to use your application"
25  kubectl port-forward $POD_NAME 8080:80
26
27

如果以后仓库添加了新的 chart,需要用 helm repo update 更新本地的 index。类似于yum update /apt-get update


1
2
3
4
5
6
7
8
1[root@master helm]# helm repo update
2Hang tight while we grab the latest from your chart repositories...
3...Skip local chart repository
4...Successfully got an update from the "nfs_repo" chart repository
5...Unable to get an update from the "stable" chart repository (https://kubernetes-charts.storage.googleapis.com):
6        Get https://kubernetes-charts.storage.googleapis.com/index.yaml: dial tcp 172.217.161.176:443: connect: connection timed out
7Update Complete. ⎈ Happy Helming!⎈
8

总结

  • Helm是Kubernetes的包管理器,Helm 让我们能够像 yum 管理 rpm 包那样安装、部署、升级和删除容器化应用。
  • Helm 由客户端和 Tiller 服务器组成。客户端负责管理 chart,服务器负责管理 release。
  • chart 是 Helm 的应用打包格式,它由一组文件和目录构成。其中最重要的是模板,模板中定义了 Kubernetes 各类资源的配置信息,Helm 在部署时通过 values.yaml 实例化模板。
  • Helm 允许用户开发自己的 chart,并为用户提供了调试工具。用户可以搭建自己的 chart 仓库,在团队中共享 chart。

给TA打赏
共{{data.count}}人
人已打赏
安全运维

故障复盘的简洁框架-黄金三问

2021-9-30 19:18:23

安全运维

OpenSSH-8.7p1离线升级修复安全漏洞

2021-10-23 10:13:25

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索