目录node
每一个成功的软件平台都有一个优秀的打包系统,好比 Debian、Ubuntu 的 apt,Redhat、Centos 的 yum。而 Helm 则是 Kubernetes 上的包管理器。mysql
思考??Helm 到底解决了什么问题?为何 Kubernetes 须要 Helm?linux
Kubernetes 可以很好地组织和编排容器,但它缺乏一个更高层次的应用打包工具,而 Helm 就是来干这件事的。nginx
举个例子,咱们须要部署一个MySQL服务,Kubernetes则须要部署如下对象:git
① 为了可以让外界访问到MySQL,须要部署一个mysql的service;github
②须要进行定义MySQL的密码,则须要部署一个Secret;redis
③Mysql的运行须要持久化的数据存储,此时还须要部署PVC;sql
④保证后端mysql的运行,还须要部署一个Deployment,以支持以上的对象。docker
针对以上对象,咱们可使用YAML文件进行定义并部署,可是仅仅对于单个的服务支持,若是应用须要由一个甚至几十个这样的服务组成,而且还须要考虑各类服务的依赖问题,可想而知,这样的组织管理应用的方式就显得繁琐。为此就诞生了一个工具Helm,就是为了解决Kubernetes这种应用部署繁重的现象。shell
Helm的核心术语:
Helm的程序架构:
Helm主要由Helm客户端、Tiller服务器和Charts仓库组成,以下图:
简单的说:Helm 客户端负责管理 chart;Tiller 服务器负责管理 release。
Helm的部署方式有两种:预编译的二进制程序和源码编译安装,这里使用二进制的方式进行安装
[root@k8s-master ~]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz --no-check-certificate [root@k8s-master ~]# tar -xf helm-v2.9.1-linux-amd64.tar.gz [root@k8s-master ~]# cd linux-amd64/ [root@k8s-master linux-amd64]# ls helm LICENSE README.md [root@k8s-master linux-amd64]# mv helm /usr/bin [root@k8s-master linux-amd64]# helm version Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
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
#建立tiller的rbac清单 [root@k8s-master ~]# cd mainfests/ [root@k8s-master mainfests]# mkdir helm [root@k8s-master mainfests]# cd helm/ [root@k8s-master helm]# vim tiller-rbac.yaml apiVersion: v1 kind: ServiceAccount metadata: name: tiller namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tiller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: tiller namespace: kube-system [root@k8s-master helm]# kubectl apply -f tiller-rbac.yaml serviceaccount/tiller created clusterrolebinding.rbac.authorization.k8s.io/tiller created [root@k8s-master helm]# kubectl get sa -n kube-system |grep tiller tiller 1 18s #helm init命令进行初始化时,会用到gcr.io/kubernetes-helm中的景象,须要提早下载,镜像标签和Helm同版本号 [root@k8s-node01 ~]# docker pull jmgao1983/tiller:v2.9.1 v2.9.1: Pulling from jmgao1983/tiller 53969ec691ff: Pull complete ea45de95cb26: Pull complete 495df31ed85a: Pull complete Digest: sha256:417aae19a0709075df9cc87e2fcac599b39d8f73ac95e668d9627fec9d341af2 Status: Downloaded newer image for jmgao1983/tiller:v2.9.1 [root@k8s-node01 ~]# docker tag jmgao1983/tiller:v2.9.1 gcr.io/kubernetes-helm/tiller:v2.9.1 [root@k8s-master ~]# helm init Creating /root/.helm Creating /root/.helm/repository Creating /root/.helm/repository/cache Creating /root/.helm/repository/local Creating /root/.helm/plugins Creating /root/.helm/starters Creating /root/.helm/cache/archive Creating /root/.helm/repository/repositories.yaml Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com Adding local repo with URL: http://127.0.0.1:8879/charts $HELM_HOME has been configured at /root/.helm. Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster. Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy. For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation Happy Helming! [root@k8s-master ~]# kubectl get pods -n kube-system |grep tiller tiller-deploy-759cb9df9-ls47p 1/1 Running 0 16m #安装完成后,执行helm version能够看到客户端和服务端的版本号,两个都显示表示正常安装。 [root@k8s-master ~]# helm version Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
若是但愿在安装时自定义一些参数,能够参考一下的一些参数:
Tiller将数据存储在ConfigMap资源当中,卸载或重装不会致使数据丢失,卸载Tiller的方法有如下两种:
(1)kubectl delete deployment tiller-deploy --n kube-system (2)heml reset
官方可用的Chart列表:
https://hub.kubeapps.com
helm经常使用命令: - helm search: 搜索charts - helm fetch: 下载charts到本地目录 - helm install: 安装charts - helm list: 列出charts的全部版本 用法: helm [command] 命令可用选项: completion 为指定的shell生成自动补全脚本(bash或zsh) create 建立一个新的charts delete 删除指定版本的release dependency 管理charts的依赖 fetch 下载charts并解压到本地目录 get 下载一个release history release历史信息 home 显示helm的家目录 init 在客户端和服务端初始化helm inspect 查看charts的详细信息 install 安装charts lint 检测包的存在问题 list 列出release package 将chart目录进行打包 plugin add(增长), list(列出), or remove(移除) Helm 插件 repo add(增长), list(列出), remove(移除), update(更新), and index(索引) chart仓库 reset 卸载tiller rollback release版本回滚 search 关键字搜索chart serve 启动一个本地的http server status 查看release状态信息 template 本地模板 test release测试 upgrade release更新 verify 验证chart的签名和有效期 version 打印客户端和服务端的版本信息
Charts是Helm的程序包,它们都存在在Charts仓库当中。Kubernetes官方的仓库保存了一系列的Charts,仓库默认的名称为stable
。安装Charts到集群时,Helm首先会到官方仓库获取相关的Charts,并建立release。可执行 helm search
查看当前可安装的 chart 。
[root@k8s-master ~]# helm search NAME CHART VERSION APP VERSION DESCRIPTION stable/acs-engine-autoscaler 2.1.3 2.1.1 Scales worker nodes within agent pools stable/aerospike 0.1.7 v3.14.1.2 A Helm chart for Aerospike in Kubernetes stable/anchore-engine 0.1.3 0.1.6 Anchore container analysis and policy evaluatio... ......
这些 chart 都是从哪里来的?
前面说过,Helm 能够像 yum 管理软件包同样管理 chart。 yum 的软件包存放在仓库中,一样的,Helm 也有仓库。
[root@k8s-master ~]# helm repo list NAME URL local http://127.0.0.1:8879/charts stable https://kubernetes-charts.storage.googleapis.com
Helm 安装时已经默认配置好了两个仓库:stable
和 local
。stable
是官方仓库,local
是用户存放本身开发的chart
的本地仓库。能够经过helm repo list
进行查看。因为网络缘由,国内没法更新仓库源,这里更改成阿里云的仓库源。
[root@k8s-master helm]# helm repo update #仓库更新有时会提示没法链接 Hang tight while we grab the latest from your chart repositories... ...Skip local chart repository ...Unable to get an update from the "stable" chart repository (https://kubernetes-charts.storage.googleapis.com): Get https://kubernetes-charts.storage.googleapis.com/index.yaml: dial tcp 216.58.220.208:443: connect: connection refused Update Complete. ⎈ Happy Helming!⎈ [root@k8s-master helm]# helm repo list NAME URL stable https://kubernetes-charts.storage.googleapis.com local http://127.0.0.1:8879/charts [root@k8s-master helm]# helm repo remove stable #移除stable repo "stable" has been removed from your repositories [root@k8s-master helm]# helm repo list NAME URL local http://127.0.0.1:8879/charts #增长阿里云的charts仓库 [root@k8s-master helm]# helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts "stable" has been added to your repositories [root@k8s-master helm]# helm repo list NAME URL local http://127.0.0.1:8879/charts stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts [root@k8s-master helm]# helm repo update #再次更新repo Hang tight while we grab the latest from your chart repositories... ...Skip local chart repository ...Successfully got an update from the "stable" chart repository Update Complete. ⎈ Happy Helming!⎈
与 yum 同样,helm 也支持关键字搜索:
[root@k8s-master ~]# helm search mysql NAME CHART VERSION APP VERSION DESCRIPTION stable/mysql 0.3.5 Fast, reliable, scalable, and easy to use open-... stable/percona 0.3.0 free, fully compatible, enhanced, open source d... stable/percona-xtradb-cluster 0.0.2 5.7.19 free, fully compatible, enhanced, open source d... 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-...
包括 DESCRIPTION 在内的全部信息,只要跟关键字匹配,都会显示在结果列表中。
安装 chart 也很简单,执行以下命令能够安装 MySQL。
[root@k8s-master ~]# helm install stable/mysql Error: no available release name found #若是看到上面的报错,一般是由于 Tiller 服务器的权限不足。执行如下命令添加权限: 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"}}}}' #helm安装mysql [root@k8s-master helm]# helm install stable/mysql NAME: reeling-bronco ① LAST DEPLOYED: Wed Mar 27 03:10:31 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ② ==> v1/Secret NAME TYPE DATA AGE reeling-bronco-mysql Opaque 2 0s ==> v1/PersistentVolumeClaim NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE reeling-bronco-mysql Pending 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE reeling-bronco-mysql ClusterIP 10.99.245.169 <none> 3306/TCP 0s ==> v1beta1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE reeling-bronco-mysql 1 1 1 0 0s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE reeling-bronco-mysql-84b897b676-59qhh 0/1 Pending 0 0s NOTES: ③ MySQL can be accessed via port 3306 on the following DNS name from within your cluster: reeling-bronco-mysql.default.svc.cluster.local To get your root password run: MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default reeling-bronco-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo) To connect to your database: 1. Run an Ubuntu pod that you can use as a client: kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il 2. Install the mysql client: $ apt-get update && apt-get install mysql-client -y 3. Connect using the mysql cli, then provide your password: $ mysql -h reeling-bronco-mysql -p To connect to your database directly from outside the K8s cluster: MYSQL_HOST=127.0.0.1 MYSQL_PORT=3306 # Execute the following commands to route the connection: export POD_NAME=$(kubectl get pods --namespace default -l "app=reeling-bronco-mysql" -o jsonpath="{.items[0].metadata.name}") kubectl port-forward $POD_NAME 3306:3306 mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
输出分为三部分:
NAME
是 release 的名字,由于咱们没用 -n
参数指定,Helm 随机生成了一个,这里是 reeling-bronco
。
NAMESPACE
是 release 部署的 namespace,默认是 default
,也能够经过 --namespace
指定。
STATUS
为 DEPLOYED
,表示已经将 chart 部署到集群。
reeling-bronco-mysql
,命名的格式为 ReleasName
-ChartName
。NOTES
部分显示的是 release 的使用方法。好比如何访问 Service,如何获取数据库密码,以及如何链接数据库等。经过 kubectl get
能够查看组成 release 的各个对象:
[root@k8s-master helm]# kubectl get service reeling-bronco-mysql NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE reeling-bronco-mysql ClusterIP 10.99.245.169 <none> 3306/TCP 3m [root@k8s-master helm]# kubectl get deployment reeling-bronco-mysql NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE reeling-bronco-mysql 1 1 1 0 3m [root@k8s-master helm]# kubectl get pvc reeling-bronco-mysql NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE reeling-bronco-mysql Pending 4m [root@k8s-master helm]# kubectl get secret reeling-bronco-mysql NAME TYPE DATA AGE reeling-bronco-mysql Opaque 2 4m
因为咱们尚未准备 PersistentVolume,当前 release 还不可用。
helm list
显示已经部署的 release,helm delete
能够删除 release。
[root@k8s-master helm]# helm list NAME REVISION UPDATED STATUS CHART NAMESPACE reeling-bronco 1 Wed Mar 27 03:10:31 2019 DEPLOYED mysql-0.3.5 default [root@k8s-master helm]# helm delete reeling-bronco release "reeling-bronco" deleted
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 包。
[root@k8s-master ~]# cd .helm/cache/archive/ [root@k8s-master archive]# ll -rw-r--r-- 1 root root 5536 Oct 29 22:04 mysql-0.3.5.tgz -rw-r--r-- 1 root root 6189 Oct 29 05:03 redis-1.1.15.tgz [root@k8s-master archive]# tar -xf mysql-0.3.5.tgz [root@k8s-master archive]# tree mysql mysql ├── Chart.yaml ├── README.md ├── templates │ ├── configmap.yaml │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── NOTES.txt │ ├── pvc.yaml │ ├── secrets.yaml │ └── svc.yaml └── values.yaml
Helm 经过模板建立 Kubernetes 可以理解的 YAML 格式的资源配置文件,咱们将经过例子来学习如何使用模板。
以 templates/secrets.yaml
为例:
从结构上看,文件的内容和咱们在定义Secret的配置上大体类似,只是大部分的属性值变成了{{ xxx }}。这些{{ xx }}其实是模板的语法。Helm采用了Go语言的模板来编写chart。
{{ template "mysql.fullname" . }}
定义 Secret 的 name
。关键字 template
的做用是引用一个子模板 mysql.fullname
。这个子模板是在 templates/_helpers.tpl
文件中定义的。
这个定义仍是很复杂的,由于它用到了模板语言中的对象、函数、流控制等概念。如今看不懂不要紧,这里咱们学习的重点是:若是存在一些信息多个模板都会用到,则可在 templates/_helpers.tpl
中将其定义为子模板,而后经过 templates
函数引用。
这里 mysql.fullname
是由 release 与 chart 两者名字拼接组成。
根据 chart 的最佳实践,全部资源的名称都应该保持一致,对于咱们这个 chart,不管 Secret 仍是 Deployment、PersistentVolumeClaim、Service,它们的名字都是子模板 mysql.fullname
的值。
Chart
和 Release
是 Helm 预约义的对象,每一个对象都有本身的属性,能够在模板中使用。若是使用下面命令安装 chart:[root@k8s-master templates]# helm search stable/mysql NAME CHART VERSION APP VERSION DESCRIPTION stable/mysql 0.3.5 Fast, reliable, scalable, and easy to use open-... [root@k8s-master templates]# helm install stable/mysql -n my
那么:
{{ .Chart.Name }}
的值为 mysql
。
{{ .Chart.Version }}
的值为 0.3.5。
{{ .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
参数:
由于 mysqlRootPassword
被注释掉了,没有赋值,因此逻辑判断会走 else
,即随机生成密码。
randAlphaNum
、b64enc
、quote
都是 Go 模板语言支持的函数,函数之间能够经过管道 |
链接。{{ randAlphaNum 10 | b64enc | quote }}
的做用是首先随机产生一个长度为 10 的字符串,而后将其 base64 编码,最后两边加上双引号。
templates/secrets.yaml
这个例子展现了 chart 模板主要的功能,咱们最大的收获应该是:模板将 chart 参数化了,经过 values.yaml
能够灵活定制应用。
不管多复杂的应用,用户均可以用 Go 模板语言编写出 chart。无非是使用到更多的函数、对象和流控制
做为准备工做,安装以前须要先清楚 chart 的使用方法。这些信息一般记录在 values.yaml 和 README.md 中。除了下载源文件查看,执行 helm inspect values
多是更方便的方法。
[root@k8s-master ~]# helm inspect values stable/mysql ## mysql image version ## ref: https://hub.docker.com/r/library/mysql/tags/ ## image: "mysql" imageTag: "5.7.14" ## Specify password for root user ## ## Default: random 10 character string # mysqlRootPassword: testing ## Create a database user ## # mysqlUser: # mysqlPassword: ## Allow unauthenticated access, uncomment to enable ## # mysqlAllowEmptyPassword: true ......
输出的其实是 values.yaml 的内容。阅读注释就能够知道 MySQL chart 支持哪些参数,安装以前须要作哪些准备。其中有一部分是关于存储的:
## Persist data to a persistent volume persistence: enabled: true ## database data Persistent Volume Storage Class ## If defined, storageClassName: <storageClass> ## If set to "-", storageClassName: "", which disables dynamic provisioning ## If undefined (the default) or set to null, no storageClassName spec is ## set, choosing the default provisioner. (gp2 on AWS, standard on ## GKE, AWS & OpenStack) ## # storageClass: "-" accessMode: ReadWriteOnce size: 8Gi
chart 定义了一个 PersistentVolumeClaim,申请 8G 的 PersistentVolume。因为咱们的实验环境不支持动态供给,因此得预先建立好相应的 PV,其配置文件 mysql-pv.yml
内容为:
[root@k8s-master volumes]# pwd /root/mainfests/volumes [root@k8s-master volumes]# cat mysql-pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv2 spec: accessModes: - ReadWriteOnce capacity: storage: 8Gi persistentVolumeReclaimPolicy: Retain nfs: path: /data/volume/db server: stor01 [root@k8s-master volumes]# kubectl apply -f mysql-pv.yaml persistentvolume/mysql-pv2 created [root@k8s-master volumes]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mysql-pv2 8Gi RWO Retain Available 5s
除了接受 values.yaml 的默认值,咱们还能够定制化 chart,好比设置 mysqlRootPassword
。
Helm 有两种方式传递配置参数:
helm inspect values mysql > myvalues.yaml
生成 values 文件,而后设置 mysqlRootPassword
,以后执行 helm install --values=myvalues.yaml mysql
。--set
直接传入参数值,好比:[root@k8s-master ~]# helm install stable/mysql --set mysqlRootPassword=abc123 -n my NAME: my LAST DEPLOYED: Tue Oct 30 22:55:22 2018 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Secret NAME TYPE DATA AGE my-mysql Opaque 2 1s ==> v1/PersistentVolumeClaim NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE my-mysql Bound mysql-pv2 8Gi RWO 1s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-mysql ClusterIP 10.103.41.193 <none> 3306/TCP 1s ==> v1beta1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE my-mysql 1 1 1 0 1s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE my-mysql-79b5d4fdcd-bj4mt 0/1 Pending 0 0s ......
mysqlRootPassword
设置为 abc123
。另外,-n
设置 release 为 my
,各种资源的名称即为my-mysql
。
经过 helm list
和 helm status
能够查看 chart 的最新状态。
release 发布后能够执行 helm upgrade
对其升级,经过 --values
或 --set
应用新的配置。好比将当前的 MySQL 版本升级到 5.7.15:
[root@k8s-master ~]# helm upgrade --set imageTag=5.7.15 my stable/mysql Release "my" has been upgraded. Happy Helming! LAST DEPLOYED: Tue Oct 30 23:42:36 2018 ...... [root@k8s-master ~]# kubectl get deployment my-mysql -o wide NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR my-mysql 1 1 1 0 11m my-mysql mysql:5.7.15 app=my-mysql
helm history
能够查看 release 全部的版本。经过 helm rollback
能够回滚到任何版本。
[root@k8s-master ~]# helm history my REVISION UPDATED STATUS CHART DESCRIPTION 1 Tue Oct 30 23:31:42 2018 SUPERSEDED mysql-0.3.5 Install complete 2 Tue Oct 30 23:42:36 2018 DEPLOYED mysql-0.3.5 Upgrade complete [root@k8s-master ~]# helm rollback my 1 Rollback was a success! Happy Helming! 回滚成功,MySQL 恢复到 5.7.14。 [root@k8s-master ~]# helm history my REVISION UPDATED STATUS CHART DESCRIPTION 1 Tue Oct 30 23:31:42 2018 SUPERSEDED mysql-0.3.5 Install complete 2 Tue Oct 30 23:42:36 2018 SUPERSEDED mysql-0.3.5 Upgrade complete 3 Tue Oct 30 23:44:28 2018 DEPLOYED mysql-0.3.5 Rollback to 1 [root@k8s-master ~]# kubectl get deployment my-mysql -o wide NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR my-mysql 1 1 1 1 13m my-mysql mysql:5.7.14 app=my-mysql
Kubernetes 给咱们提供了大量官方 chart,不过要部署微服务应用,仍是须要开发本身的 chart,下面就来实践这个主题。
执行 helm create mychart
的命令建立 chart mychart
:
[root@k8s-master ~]# helm create -h [root@k8s-master ~]# helm create mychart Creating mychart [root@k8s-master ~]# tree mychart/ mychart/ ├── charts ├── Chart.yaml ├── templates │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── ingress.yaml │ ├── NOTES.txt │ └── service.yaml └── values.yaml
Helm 会帮咱们建立目录 mychart
,并生成了各种 chart 文件。这样咱们就能够在此基础上开发本身的 chart 了。
只要是程序就会有 bug,chart 也不例外。Helm 提供了 debug 的工具:helm lint
和 helm install --dry-run --debug
。
helm lint
会检测 chart 的语法,报告错误以及给出建议。 故意修改mychart中的value.yaml,进行检测:
helm lint mychart
会指出这个语法错误。
[root@k8s-master ~]# helm lint mychart ==> Linting mychart [INFO] Chart.yaml: icon is recommended [ERROR] values.yaml: unable to parse YAML error converting YAML to JSON: yaml: line 11: could not find expected ':' Error: 1 chart(s) linted, 1 chart(s) failed mychart 目录被做为参数传递给 helm lint。错误修复后则能经过检测。 [root@k8s-master ~]# helm lint mychart ==> Linting mychart [INFO] Chart.yaml: icon is recommended 1 chart(s) linted, no failures
helm install --dry-run --debug
会模拟安装 chart,并输出每一个模板生成的 YAML 内容。
[root@k8s-master ~]# helm install --dry-run mychart --debug [debug] Created tunnel using local port: '46807' [debug] SERVER: "127.0.0.1:46807" [debug] Original chart version: "" [debug] CHART PATH: /root/mychart NAME: sad-orangutan REVISION: 1 RELEASED: Wed Oct 31 01:55:03 2018 CHART: mychart-0.1.0 USER-SUPPLIED VALUES: {} COMPUTED VALUES: affinity: {} image: pullPolicy: IfNotPresent repository: nginx tag: stable ingress: annotations: {} enabled: false hosts: - chart-example.local path: / tls: [] nodeSelector: {} replicaCount: 1 resources: {} service: port: 80 type: ClusterIP tolerations: [] HOOKS: MANIFEST: --- # Source: mychart/templates/service.yaml apiVersion: v1 kind: Service metadata: name: sad-orangutan-mychart labels: app: mychart chart: mychart-0.1.0 release: sad-orangutan heritage: Tiller spec: type: ClusterIP ports: - port: 80 targetPort: http protocol: TCP name: http selector: app: mychart release: sad-orangutan --- # Source: mychart/templates/deployment.yaml apiVersion: apps/v1beta2 kind: Deployment metadata: name: sad-orangutan-mychart labels: app: mychart chart: mychart-0.1.0 release: sad-orangutan heritage: Tiller spec: replicas: 1 selector: matchLabels: app: mychart release: sad-orangutan template: metadata: labels: app: mychart release: sad-orangutan spec: containers: - name: mychart image: "nginx:stable" imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 protocol: TCP livenessProbe: httpGet: path: / port: http readinessProbe: httpGet: path: / port: http resources: {}
咱们能够检视这些输出,判断是否与预期相符。
安装 chart,Helm 支持四种安装方法:
helm install stable/nginx
helm install ./nginx-1.2.3.tgz
helm install ./nginx
helm install https://example.com/charts/nginx-1.2.3.tgz
这里经过使用本地目录进行安装:
[root@k8s-master ~]# helm install mychart NAME: anxious-wasp LAST DEPLOYED: Wed Oct 31 01:57:15 2018 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE anxious-wasp-mychart-94fcbf7d-dg5qn 0/1 ContainerCreating 0 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE anxious-wasp-mychart ClusterIP 10.111.51.71 <none> 80/TCP 0s ==> v1beta2/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE anxious-wasp-mychart 1 1 1 0 0s NOTES: 1. Get the application URL by running these commands: export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=anxious-wasp" -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
当 chart 部署到 Kubernetes 集群,即可以对其进行更为全面的测试。
chart 经过测试后能够将其添加到仓库,团队其余成员就可以使用。任何 HTTP Server 均可以用做 chart 仓库,下面演示在 k8s-node1
192.168.56.12 上搭建仓库。
(1)在 k8s-node1 上启动一个 httpd 容器。 [root@k8s-node01 ~]# mkdir /var/www [root@k8s-node01 ~]# docker run -d -p 8080:80 -v /var/www/:/usr/local/apache2/htdocs/ httpd (2)经过 helm package 将 mychart 打包。 [root@k8s-master ~]# helm package mychart Successfully packaged chart and saved it to: /root/mychart-0.1.0.tgz (3)执行 helm repo index 生成仓库的 index 文件 [root@k8s-master ~]# mkdir myrepo [root@k8s-master ~]# mv mychart-0.1.0.tgz myrepo/ [root@k8s-master ~]# [root@k8s-master ~]# helm repo index myrepo/ --url http://192.168.56.12:8080/charts [root@k8s-master ~]# ls myrepo/ index.yaml mychart-0.1.0.tgz Helm 会扫描 myrepo 目录中的全部 tgz 包并生成 index.yaml。--url指定的是新仓库的访问路径。新生成的 index.yaml 记录了当前仓库中全部 chart 的信息: 当前只有 mychart 这一个 chart。 [root@k8s-master ~]# cat myrepo/index.yaml apiVersion: v1 entries: mychart: - apiVersion: v1 appVersion: "1.0" created: 2018-10-31T02:02:45.599264611-04:00 description: A Helm chart for Kubernetes digest: 08abeb3542e8a9ab90df776d3a646199da8be0ebfc5198ef032190938d49e30a name: mychart urls: - http://192.168.56.12:8080/charts/mychart-0.1.0.tgz version: 0.1.0 generated: 2018-10-31T02:02:45.598450525-04:00 (4)将 mychart-0.1.0.tgz 和 index.yaml 上传到 k8s-node1 的 /var/www/charts 目录。 [root@k8s-master myrepo]# scp ./* root@k8s-node01:/var/www/charts/ [root@k8s-node01 ~]# ls /var/www/charts/ index.yaml mychart-0.1.0.tgz (5)经过 helm repo add 将新仓库添加到 Helm。 [root@k8s-master ~]# helm repo add newrepo http://192.168.56.12:8080/charts "newrepo" has been added to your repositories [root@k8s-master ~]# helm repo list NAME URL local http://127.0.0.1:8879/charts stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts newrepo http://192.168.56.12:8080/charts (6)如今已经能够 repo search 到 mychart 了。 [root@k8s-master ~]# helm search mychart NAME CHART VERSION APP VERSION DESCRIPTION local/mychart 0.1.0 1.0 A Helm chart for Kubernetes newrepo/mychart 0.1.0 1.0 A Helm chart for Kubernetes 除了 newrepo/mychart,这里还有一个 local/mychart。这是由于在执行第 2 步打包操做的同时,mychart 也被同步到了 local 的仓库。 (7)已经能够直接重新仓库安装 mychart 了。 [root@k8s-master ~]# helm install newrepo/mychart (8)若是之后仓库添加了新的 chart,须要用 helm repo update 更新本地的 index。 [root@k8s-master ~]# helm repo update Hang tight while we grab the latest from your chart repositories... ...Skip local chart repository ...Successfully got an update from the "newrepo" chart repository ...Successfully got an update from the "stable" chart repository Update Complete. ⎈ Happy Helming!⎈ 这个操做至关于 Centos 的 yum update。
Helm是Kubernetes的包管理器,Helm 让咱们可以像 yum 管理 rpm 包那样安装、部署、升级和删除容器化应用。
Helm 由客户端和 Tiller 服务器组成。客户端负责管理 chart,服务器负责管理 release。
chart 是 Helm 的应用打包格式,它由一组文件和目录构成。其中最重要的是模板,模板中定义了 Kubernetes 各种资源的配置信息,Helm 在部署时经过 values.yaml 实例化模板。
Helm 容许用户开发本身的 chart,并为用户提供了调试工具。用户能够搭建本身的 chart 仓库,在团队中共享 chart。