目前咱們的一個產品共有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文件,比較原始。nginx
最近須要新起另外的一套測試環境這裏稱它爲test2吧,須要在第一個Kubernetes集羣上建立新的namespace,要維護的yaml文件立刻也要增長到70個,有點噩夢的感受了。 所以咱們須要一個模板工具來管理這些yaml文件。早就知道helm這個東西,但爲了保持簡單,一直遵循着最少引入新東西的原則,那麼如今是時候使用Helm了吧?git
Helm是Kubernetes的一個包管理工具,用來簡化Kubernetes應用的部署和管理。能夠把Helm比做CentOS的yum工具。 Helm有以下幾個基本概念:github
使用Helm能夠完成如下事情:golang
Helm由兩部分組成,客戶端helm和服務端tiller。docker
如下是摘自Helm – Application deployment management for Kubernetes的一張Helm的架構圖,一圖勝千言了。json
咱們將在Kubernetes 1.8上安裝Helm。api
首先從這裏下載Helm的二進制文件. 這裏下載的是helm 2.7.2,解壓縮後將可執行文件helm拷貝到/usr/local/bin下。這樣客戶端helm就在這臺機器上安裝完成了。網絡
此時運行helm version能夠打印出客戶端helm的版本,同時會提示沒法鏈接到服務端Tiller。架構
helm version Client: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"} Error: cannot connect to Tiller
爲了安裝服務端tiller,還須要在這臺機器上配置好kubectl工具和kubeconfig文件,確保kubectl工具能夠在這臺機器上訪問apiserver且正常使用。app
kubectl get cs NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-4 Healthy {"health": "true"} etcd-0 Healthy {"health": "true"} etcd-2 Healthy {"health": "true"} etcd-3 Healthy {"health": "true"} etcd-1 Healthy {"health": "true"}
使用helm在k8s上部署tiller:
helm init --service-account tiller --skip-refresh 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.
注意因爲某些緣由須要網絡能夠訪問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下。
kubectl get pod -n kube-system -l app=helm NAME READY STATUS RESTARTS AGE tiller-deploy-587df449fb-c6tzp 1/1 Running 0 9m
再次helm version能夠打印客戶端和服務端的版本:
helm version Client: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
由於咱們將tiller部署在Kubernetes 1.8上,Kubernetes APIServer開啓了RBAC訪問控制,因此咱們須要建立tiller使用的service account: tiller並分配合適的角色給它。 詳細內容能夠查看helm文檔中的Role-based Access Control。 這裏簡單起見直接分配cluster-admin這個集羣內置的ClusterRole給它。
建立rbac-config.yaml文件:
apiVersion: v1 kind: ServiceAccount metadata: name: tiller namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: tiller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: tiller namespace: kube-system
kubectl create -f rbac-config.yaml serviceaccount "tiller" created clusterrolebinding "tiller" created
已經安裝helm的客戶端helm和服務端tiller,下面要熟悉如何使用helm管理Kubernetes集羣的安裝包。
更新chart repo:
helm repo update
實際上若是helm所在的機器訪問不了google的話,會報錯,由於訪問不了 「stable」 chart repository (https://kubernetes-charts.storage.googleapis.com)
下面咱們開始嘗試建立一個chart,這個chart用來部署一個簡單的服務。
helm create hello-svc Creating hello-svc tree hello-svc/ hello-svc/ ├── charts ├── Chart.yaml ├── templates │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── ingress.yaml │ ├── NOTES.txt │ └── service.yaml └── values.yaml 2 directories, 7 files
先熟悉一下hello-svc這個chart中目錄和文件內容:
cat Chart.yaml apiVersion: v1 description: A Helm chart for Kubernetes name: hello-svc version: 0.1.0
經過查看deployment.yaml和value.yaml,大概知道這個chart默認安裝就是在Kubernetes部署一個nginx服務。
更多Chart的內容能夠查看Chart官方文檔
使用helm在Kubernetes上安裝chart時,其實是將chart的模板生成Kubernetes使用的manifest yaml文件。 在編寫chart的過程當中能夠chart目錄下使用helm install –dry-run –debug ./來驗證模板和配置。
helm install --dry-run --debug ./ [debug] Created tunnel using local port: '22635' [debug] SERVER: "127.0.0.1:22635" [debug] Original chart version: "" [debug] CHART PATH: /root/helm/hello-svc NAME: foolish-zebra REVISION: 1 ......輸出基於配置值和模板生成的yaml文件
在hello-svc這個chart目錄下執行:
helm install ./ NAME: wishful-squid LAST DEPLOYED: Thu Dec 21 22:04:19 2017 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE wishful-squid-hello-svc ClusterIP 10.111.223.243 <none> 80/TCP 0s ==> v1beta1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE wishful-squid-hello-svc 1 0 0 0 0s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE wishful-squid-hello-svc-6bbb59dfb6-smvz5 0/1 Pending 0 0s NOTES: 1. Get the application URL by running these commands: export POD_NAME=$(kubectl get pods --namespace default -l "app=hello-svc,release=wishful-squid" -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:
helm list NAME REVISION UPDATED STATUS CHART NAMESPACE wishful-squid 1 Thu Dec 21 22:04:19 2017 DEPLOYED hello-svc-0.1.0 default
刪除release:
helm delete wishful-squid release "wishful-squid" deleted
打包:
helm package ./ tree . ├── charts ├── Chart.yaml ├── hello-svc-0.1.0.tgz ├── templates │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── ingress.yaml │ ├── NOTES.txt │ └── service.yaml └── values.yaml