是时候使用Helm了:Helm, Kubernetes的包管理工具
2017-12-21
目前我们的一个产品共有4套环境:dev环境、test环境、staging环境、production环境。
其中dev, test, staging环境在一个Kubernetes集群上以不同namespace部署,production环境部署在另一个Kubernetes集群上。这个产品总共有14个微服务组成,对应gitlab中14个代码库,Kubernetes的deployment yaml文件也保存在代码库,为每个服务的每套环境以环境名创建了一个目录,里面是yaml文件,yaml文件的内容使用sed
实现了简单的模板功能。14个服务*4套环境总共56个yaml文件,比较原始。
最近需要新起另外的一套测试环境这里称它为test2吧,需要在第一个Kubernetes集群上创建新的namespace,要维护的yaml文件马上也要增加到70个,有点噩梦的感觉了。 因此我们需要一个模板工具来管理这些yaml文件。早就知道helm这个东西,但为了保持简单,一直遵循着最少引入新东西的原则,那么现在是时候使用Helm了吧?
1.Helm的基本概念 #
Helm是Kubernetes的一个包管理工具,用来简化Kubernetes应用的部署和管理。可以把Helm比作CentOS的yum工具。 Helm有如下几个基本概念:
- Chart: 是Helm管理的安装包,里面包含需要部署的安装包资源。可以把Chart比作CentOS yum使用的rpm文件。每个Chart包含下面两部分:
- 包的基本描述文件
Chart.yaml
- 放在templates目录中的一个或多个Kubernetes manifest文件模板
- Release:是chart的部署实例,一个chart在一个Kubernetes集群上可以有多个release,即这个chart可以被安装多次
- Repository:chart的仓库,用于发布和存储chart
使用Helm可以完成以下事情:
- 管理Kubernetes manifest files
- 管理Helm安装包charts
- 基于chart的Kubernetes应用分发
2.Helm的组成 #
Helm由两部分组成,客户端helm和服务端tiller。
- tiller运行在Kubernetes集群上,管理chart安装的release
- helm是一个命令行工具,可在本地运行,一般运行在CI/CD Server上。
以下是摘自Helm - Application deployment management for Kubernetes的一张Helm的架构图,一图胜千言了。
3.Helm的安装 #
我们将在Kubernetes 1.8上安装Helm。
3.1 客户端helm和服务端tiller #
首先从这里下载Helm的二进制文件. 这里下载的是helm 2.7.2,解压缩后将可执行文件helm拷贝到/usr/local/bin下。这样客户端helm就在这台机器上安装完成了。
此时运行helm version
可以打印出客户端helm的版本,同时会提示无法连接到服务端Tiller。
1helm version
2Client: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
3Error: cannot connect to Tiller
为了安装服务端tiller,还需要在这台机器上配置好kubectl工具和kubeconfig文件,确保kubectl工具可以在这台机器上访问apiserver且正常使用。
1kubectl get cs
2NAME STATUS MESSAGE ERROR
3scheduler Healthy ok
4controller-manager Healthy ok
5etcd-4 Healthy {"health": "true"}
6etcd-0 Healthy {"health": "true"}
7etcd-2 Healthy {"health": "true"}
8etcd-3 Healthy {"health": "true"}
9etcd-1 Healthy {"health": "true"}
使用helm在k8s上部署tiller:
1helm init --service-account tiller --skip-refresh
2Creating /root/.helm
3Creating /root/.helm/repository
4Creating /root/.helm/repository/cache
5Creating /root/.helm/repository/local
6Creating /root/.helm/plugins
7Creating /root/.helm/starters
8Creating /root/.helm/cache/archive
9Creating /root/.helm/repository/repositories.yaml
10Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
11Adding local repo with URL: http://127.0.0.1:8879/charts
12$HELM_HOME has been configured at /root/.helm.
注意由于某些原因需要网络可以访问gcr.io和kubernetes-charts.storage.googleapis.com,如果无法访问可以通过
helm init --service-account tiller --tiller-image <your-docker-registry>/tiller:2.7.2 --skip-refresh
使用私有镜像仓库中的tiller镜像
tiller默认被部署在k8s集群中的kube-system这个namespace下。
1kubectl get pod -n kube-system -l app=helm
2NAME READY STATUS RESTARTS AGE
3tiller-deploy-587df449fb-c6tzp 1/1 Running 0 9m
再次helm version
可以打印客户端和服务端的版本:
1helm version
2Client: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
3Server: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
3.2 Kubernetes RBAC配置 #
因为我们将tiller部署在Kubernetes 1.8上,Kubernetes APIServer开启了RBAC访问控制,所以我们需要创建tiller使用的service account: tiller并分配合适的角色给它。
详细内容可以查看helm文档中的Role-based Access Control。
这里简单起见直接分配cluster-admin
这个集群内置的ClusterRole给它。
创建rbac-config.yaml
文件:
1apiVersion: v1
2kind: ServiceAccount
3metadata:
4 name: tiller
5 namespace: kube-system
6---
7apiVersion: rbac.authorization.k8s.io/v1beta1
8kind: ClusterRoleBinding
9metadata:
10 name: tiller
11roleRef:
12 apiGroup: rbac.authorization.k8s.io
13 kind: ClusterRole
14 name: cluster-admin
15subjects:
16 - kind: ServiceAccount
17 name: tiller
18 namespace: kube-system
1kubectl create -f rbac-config.yaml
2serviceaccount "tiller" created
3clusterrolebinding "tiller" created
4.Helm的基本使用 #
已经安装helm的客户端helm和服务端tiller,下面要熟悉如何使用helm管理Kubernetes集群的安装包。
更新chart repo:
1helm repo update
实际上如果helm所在的机器访问不了google的话,会报错,因为访问不了
"stable" chart repository (https://kubernetes-charts.storage.googleapis.com)
4.1 创建一个chart #
下面我们开始尝试创建一个chart,这个chart用来部署一个简单的服务。
1helm create hello-svc
2Creating hello-svc
3
4tree hello-svc/
5hello-svc/
6├── charts
7├── Chart.yaml
8├── templates
9│ ├── deployment.yaml
10│ ├── _helpers.tpl
11│ ├── ingress.yaml
12│ ├── NOTES.txt
13│ └── service.yaml
14└── values.yaml
15
162 directories, 7 files
先熟悉一下hello-svc这个chart中目录和文件内容:
- charts目录中是本chart依赖的chart,当前是空的
- Chart.yaml这个yaml文件用于描述Chart的基本信息,如名称版本等
1cat Chart.yaml 2apiVersion: v1 3description: A Helm chart for Kubernetes 4name: hello-svc 5version: 0.1.0
- templates是Kubernetes manifest文件模板目录,模板使用chart配置的值生成Kubernetes manifest文件。模板文件使用的Go语言模板语法
- templates/NOTES.txt 纯文本文件,可在其中填写chart的使用说明
- value.yaml 是chart配置的默认值
通过查看deployment.yaml和value.yaml,大概知道这个chart默认安装就是在Kubernetes部署一个nginx服务。
更多Chart的内容可以查看Chart官方文档
4.2 对chart的模板和配置进行测试 #
使用helm在Kubernetes上安装chart时,实际上是将chart的模板生成Kubernetes使用的manifest yaml文件。
在编写chart的过程中可以chart目录下使用helm install --dry-run --debug ./
来验证模板和配置。
1helm install --dry-run --debug ./
2[debug] Created tunnel using local port: '22635'
3
4[debug] SERVER: "127.0.0.1:22635"
5
6[debug] Original chart version: ""
7[debug] CHART PATH: /root/helm/hello-svc
8
9NAME: foolish-zebra
10REVISION: 1
11......输出基于配置值和模板生成的yaml文件
4.3 在Kubernetes上安装chart #
在hello-svc这个chart目录下执行:
1helm install ./
2
3NAME: wishful-squid
4LAST DEPLOYED: Thu Dec 21 22:04:19 2017
5NAMESPACE: default
6STATUS: DEPLOYED
7
8RESOURCES:
9==> v1/Service
10NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
11wishful-squid-hello-svc ClusterIP 10.111.223.243 <none> 80/TCP 0s
12
13==> v1beta1/Deployment
14NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
15wishful-squid-hello-svc 1 0 0 0 0s
16
17==> v1/Pod(related)
18NAME READY STATUS RESTARTS AGE
19wishful-squid-hello-svc-6bbb59dfb6-smvz5 0/1 Pending 0 0s
20
21
22NOTES:
231. Get the application URL by running these commands:
24 export POD_NAME=$(kubectl get pods --namespace default -l "app=hello-svc,release=wishful-squid" -o jsonpath="{.items[0].metadata.name}")
25 echo "Visit http://127.0.0.1:8080 to use your application"
26 kubectl port-forward $POD_NAME 8080:80
查看release:
1helm list
2NAME REVISION UPDATED STATUS CHART NAMESPACE
3wishful-squid 1 Thu Dec 21 22:04:19 2017 DEPLOYED hello-svc-0.1.0 default
删除release:
1helm delete wishful-squid
2release "wishful-squid" deleted
4.4 chart的分发 #
打包:
1helm package ./
2
3tree
4.
5├── charts
6├── Chart.yaml
7├── hello-svc-0.1.0.tgz
8├── templates
9│ ├── deployment.yaml
10│ ├── _helpers.tpl
11│ ├── ingress.yaml
12│ ├── NOTES.txt
13│ └── service.yaml
14└── values.yaml