03.01 k8s實踐(九):Helm and Kubeapps UI

一、概述

1. Helm簡介

  Helm是一個Kubemetes包管理器(類似於OS包管理器,比如Linux中的yum、apt,或者MacOS中的 homebrew)。

  Helm包括兩個部分:helm客戶端和tiller服務端。

helm客戶端

helm客戶端是一個命令行工具,負責管理charts、repository和release。它通過gPRC API(使用kubectl port-forward將tiller的端口映射到本地,然後再通過映射後的端口跟tiller通信)向tiller發送請求,並由tiller來管理對應的Kubernetes資源。helm作用:

  • 本地Charts開發;
  • 管理Charts倉庫;
  • 與Tiller服務器交互:發送Charts以安裝、查詢Release的相關信息及升級或卸載已有的Release

tiller 服務端

tiller 接收來自helm客戶端的請求,並把相關資源的操作發送到Kubernetes,負責管理(安裝、查詢、升級或刪除等)和跟蹤 Kubernetes 資源。為了方便管理,tiller把release的相關信息保存在kubernetes的ConfigMap中。tiller作用:

  • 監聽來自helm客戶端的請求;
  • 合併Charts和配置以構建一個Release;
  • 向Kubernetes集群安裝Charts並對相應的Release進行跟蹤;
  • 升級和卸載Charts;
k8s實踐(九):Helm and Kubeapps UI

圖片.png

2. 為什麼需要Helm

  Kubernetes雖然提供了多種容器編排對象,例如Deployment、StatefulSet、DeamonSet、Job等,還有多種基礎資源封裝例如ConfigMap、Secret、Serivce等,但是一個應用往往有多個服務,有的可能還要依賴持久化存儲,當這些服務之間直接互相依賴,需要有一定的組合的情況下,使用YAML文件的方式配置應用往往十分繁瑣還容易出錯,這時候就需要服務編排工具。

  服務編排管理工具就是構建在kubernetes的基礎object之上,統籌各個服務之間的關係和依賴的。目前常用到的工具是Helm。

3. Helm核心術語

Chart:一個Helm包,其中包含了運行一個應用所需要的工具和資源定義,還可能包含Kubernetes集群中的服務定義,類似於Homebrew中的formula、APT中的dpkg或者Yum中的RPM文件: Release:在Kubernetes集群上運行的一個Chart實例。在同一個集群上,一個Chart可以安裝多次。例如有一個MySQLChart,如果想在服務器上運行兩個MySQL數據庫,就可以基於這個Chart安裝兩次,每次安裝都會生成新的Release,會有獨立的Release名稱; Repository:

用於存放和共享Chart的倉庫。

Helm將charts安裝到Kubernetes中,每個安裝創建一個新release。要找到新的chart,可以搜索Helm charts存儲庫repositories。

二、安裝Helm

1. 安裝Helm Client

Helm客戶端可以從源代碼安裝,也可以從預構建的二進制版本安裝或執行安裝腳本。

1.1 腳本安裝方式

Helm現在有一個安裝shell腳本,將自動獲取最新版本的Helm客戶端並在本地安裝。

<code>[root@master ~]# curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash/<code>

腳本方式安裝很簡單,執行一條命令就行。

1.2 二進制方式安裝

這種方式可以選擇helm客戶端安裝版本,下載二進制文件:https://github.com/helm/helm/releases/ ,例如下載2.14.2版本:

<code>[root@master ~]# curl -L https://get.helm.sh/helm-v2.14.2-linux-amd64.tar.gz -o helm-v2.14.2-linux-amd64.tar.gz[root@master ~]# tar -zxvf helm-v2.14.2-linux-amd64.tar.gz linux-amd64/linux-amd64/LICENSElinux-amd64/helmlinux-amd64/README.mdlinux-amd64/tiller[root@master ~]# cp linux-amd64/helm /usr/bin[root@master ~]# helm versionClient: &version.Version{SemVer:"v2.14.2", GitCommit:"a8b13cc5ab6a7dbef0a58f5061bcc7c0c61598e7", GitTreeState:"clean"}Error: could not find tiller/<code>

下載二進制文件、解壓、拷貝命令,執行helm version命令發現helm客戶端版本為v2.14.2,服務端tiller還未安裝,本文測試基於v2.14.3最新版。

1.3 命令補全

<code>[root@master ~]# echo   "source > .bash_profile[root@master ~]# source .bash_profile/<code>
k8s實踐(九):Helm and Kubeapps UI

圖片.png

2. 安裝Tiller server

2.1 設置環境變量

<code>[root@master ~]# mkdir helm[root@master ~]# echo 'export HELM_HOME=~/helm' >> .bash_profile [root@master ~]# source .bash_profile [root@master ~]# echo $HELM_HOME/root/helm/<code>

設置helm的home目錄為/root/helm,tiller將安裝於該目錄下

k8s實踐(九):Helm and Kubeapps UI

圖片.png

2.2 創建帶有cluster-admin角色權限的服務賬戶

<code>[root@master ~]# more rbac-config.yaml apiVersion: v1kind: ServiceAccountmetadata:  name: tiller  namespace: kube-system---apiVersion: rbac.authorization.k8s.io/v1beta1kind: ClusterRoleBindingmetadata:  name: tillerroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: cluster-adminsubjects:  - kind: ServiceAccount    name: tiller    namespace: kube-system[root@master ~]# kubectl create -f rbac-config.yamlserviceaccount/tiller createdclusterrolebinding.rbac.authorization.k8s.io/tiller created[root@master ~]# kubectl get -n kube-system secrets,sa,clusterrolebinding -o name|grep tillersecret/tiller-token-dz4ltserviceaccount/tillerclusterrolebinding.rbac.authorization.k8s.io/tiller/<code> 

否則helm install可能會報權限錯誤:

<code>Error: no available release name foundError: the server does not allow access to the requested resourc/<code>
k8s實踐(九):Helm and Kubeapps UI

圖片.png

2.3 下載tiller鏡像

<code>[root@master helm]# docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.3[root@master helm]# docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.3 gcr.io/kubernetes-helm/tiller:v2.14.3[root@master helm]# docker rmi -f registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.3/<code>

由於網絡原因官網鏡像無法下載,下載阿里源鏡像,打上tag並刪除原鏡像。注意,每個node節點都需執行以上操作。

k8s實踐(九):Helm and Kubeapps UI

圖片.png

2.4 安裝Tiller

<code>[root@master ~]# helm init --service-account tiller/<code>

安裝的tiller版本與helm客戶端版本一致

k8s實踐(九):Helm and Kubeapps UI

圖片.png

3. 卸載Helm

3.1 卸載tiller server

<code>[root@master ~]# helm reset --force[root@master ~]# kubectl get -n kube-system secrets,sa,clusterrolebinding -o name|grep tiller|xargs kubectl -n kube-system delete[root@master ~]# kubectl get all -n kube-system -l app=helm -o name|xargs kubectl delete -n kube-system[root@master ~]# rm -rf /root/helm/<code>

卸載tiller,刪除相關資源和文件

k8s實踐(九):Helm and Kubeapps UI

圖片.png

3.2 卸載helm客戶端

<code>[root@master ~]# rm -rf /usr/bin/helm[root@master ~]# rm -rf helm-v2.14.3-linux-amd64.tar.gz [root@master ~]# rm -rf linux-amd64//<code>

helm客戶端卸載只需移除相關文件即可

三、Helm UI

Kubeapps提供了一個開源的Helm UI界面,方便以圖形界面的形式管理Helm應用。Kubeapps特點:

部署應用。可從公共或私有倉庫中瀏覽chart並將其部署到集群中; 管理應用。升級、管理和刪除部署在kubernetes集群中的應用程序; 搜索功能。Kubeapps提供chart搜索頁面;

1. 新增倉庫bitnami

<code>[root@master ~]# helm repo add bitnami https://charts.bitnami.com/bitnami"bitnami" has been added to your repositories[root@master ~]# helm updateCommand "update" is deprecated, use 'helm repo update'Hang tight while we grab the latest from your chart repositories......Skip local chart repository...Successfully got an update from the "bitnami" chart repository...Successfully got an update from the "stable" chart repositoryUpdate Complete.[root@master ~]# helm repo listNAME    URL                                             stable  https://kubernetes-charts.storage.googleapis.comlocal   http://127.0.0.1:8879/charts                    bitnami https://charts.bitnami.com/bitnami/<code>
k8s實踐(九):Helm and Kubeapps UI

圖片.png

2. 安裝Kubeapps

<code>[root@master ~]# helm install --name kubeapps --namespace kubeapps bitnami/kubeapps/<code>

安裝的時候主要遇到的問題是網絡,即鏡像下載失敗,可通過手動方式下載鏡像到對應節點方式解決。

k8s實踐(九):Helm and Kubeapps UI

圖片.png

kubeappspod資源列表如下:

k8s實踐(九):Helm and Kubeapps UI

圖片.png

3. 創建API token

<code>[root@master ~]# kubectl create -n default serviceaccount exampleserviceaccount/example created[root@master ~]# kubectl get -n default secret $(kubectl get -n default serviceaccount example -o jsonpath='{.secrets[].name}') -o jsonpath='{.data.token}' | base64 --decode eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImV4YW1wbGUtdG9rZW4tdHBmdHoiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZXhhbXBsZSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImFhZTIxZmE0LWU5N2ItMTFlOS05Njk0LTAwMGMyOWQ5OWJhMyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmV4YW1wbGUifQ.Cto0Csh7n6Uk_cgGWGGGiMXVie8IBX-yu3fKWGFgX4rxhjT1pwS1PXI7Kq2M-c00DJhHEih2cHFZ7trwZdLrBpI3qJUz5Ymta3I3k5V2m0C_H3wXH9KODIRAhOxT45yFPk3gmdfl8-QBKLD8bB8WufHTTO0SeJ1hsAWDX5S9f3EyTmYhjI6UPEnlWiheq-WjiR1Ba7ZRzCCr4KU3_UIZ_GTF0D_1a5yghizwwngdOs7dPdLfuKOwbgjBhEBlWP4nINa2ixo03EE2EzjfAVtX6SQTuJu1lAmH-vZZi19pKc6PyMzSjfUKHmB-W5dfcbmPhv4OAlJxx4tZffq8fKP0cw[root@master ~]# /<code>

創建serviceaccount example並獲取secret,登錄時會用到。

k8s實踐(九):Helm and Kubeapps UI

圖片.png

4. 創建service

<code>[root@master ~]# more kubeapps-service.yaml apiVersion: v1kind: Servicemetadata:  name: kubeapps-svc  namespace: kubeapps spec:  type: NodePort  selector:    app: kubeapps  ports:  - protocol: TCP    nodePort: 30002    port: 8080    targetPort: 8080[root@master ~]# kubectl apply -f kubeapps-service.yamlservice/kubeapps-svc created[root@master ~]# kubectl get service -n kubeapps NAME                             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGEkubeapps                         ClusterIP   10.103.27.24    <none>        80/TCP           46mkubeapps-internal-chartsvc       ClusterIP   10.102.122.69   <none>        8080/TCP         46mkubeapps-internal-dashboard      ClusterIP   10.110.249.91   <none>        8080/TCP         46mkubeapps-internal-tiller-proxy   ClusterIP   10.105.104.45   <none>        8080/TCP         46mkubeapps-mongodb                 ClusterIP   10.96.175.241   <none>        27017/TCP        46mkubeapps-svc                     NodePort    10.98.2.173     <none>        8080:30002/TCP   6s/<none>/<none>/<none>/<none>/<none>/<none>/<code>

創建servicekubeapps-svc用於登陸訪問。

k8s實踐(九):Helm and Kubeapps UI

圖片.png

5. 登錄kubeapps

登錄kubeapps,地址為:http://NodeIp:30002,密碼為之前創建的secret

k8s實踐(九):Helm and Kubeapps UI

圖片.png

輸入secret後登陸成功

k8s實踐(九):Helm and Kubeapps UI

圖片.png

6.通過kubeapps創建mysql

<code>[root@master ~]# kubectl create clusterrolebinding example --clusterrole=cluster-admin --serviceaccount=default:exampleclusterrolebinding.rbac.authorization.k8s.io/example created/<code>

授予example用戶集群管理訪問權限

6.2 創建pv

部署mysql服務時需8G的pv

nfs和pv搭建詳見:k8s實踐(七):存儲卷和數據持久化(Volumes and Persistent Storage)

<code>[root@master ~]# more kubeapps-pv.yaml apiVersion: v1kind: PersistentVolumemetadata:  name: pv-mysqlspec:  capacity:    storage: 8Gi                             #指定PV容量為8G  volumeMode: Filesystem                     #卷模式,默認為Filesystem,也可設置為'Block'表示支持原始塊設備  accessModes:    - ReadWriteOnce                          #訪問模式,該卷可以被單個節點以讀/寫模式掛載  persistentVolumeReclaimPolicy: Retain      #回收策略,Retain(保留),表示手動回收  nfs:                                       #指定NFS共享目錄和IP信息    path: /backup/v1    server: 172.27.9.181[root@master ~]# kubectl apply -f kubeapps-pv.yaml persistentvolume/pv-mysql created[root@master ~]# kubectl get pvNAME       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGEpv-mysql   8Gi        RWO            Retain           Available                                   5s/<code>
k8s實踐(九):Helm and Kubeapps UI

圖片.png

6.3 創建mysql

k8s實踐(九):Helm and Kubeapps UI

圖片.png

倉庫選擇stable

k8s實踐(九):Helm and Kubeapps UI

圖片.png

選擇deploy

k8s實踐(九):Helm and Kubeapps UI

圖片.png

name為mysql-stable,submit

k8s實踐(九):Helm and Kubeapps UI

圖片.png

mysql部署成功

6.4 進入mysql

<code>[root@master ~]# kubectl get secret --namespace default mysql-stable -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echoL31oZF8AJ2[root@master ~]# kubectl exec -it mysql-stable-76674bc757-8crfk sh# mysql -uroot -pEnter password: Welcome to the MySQL monitor.  Commands end with ; or \\g.Your MySQL connection id is 25Server version: 5.7.14 MySQL Community Server (GPL)Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.mysql> /<code>
k8s實踐(九):Helm and Kubeapps UI

圖片.png

四、Helm的使用

1. helm search

<code>[root@master ~]# helm search mysql/<code>

使用search命令可搜索倉庫中的mysql應用

k8s實踐(九):Helm and Kubeapps UI

圖片.png

2. helm inspect

<code>[root@master ~]# helm inspect values stable/mysql/<code>

使用inspect查詢package詳細信息,之前kubeapps部署mysql時需要8G的pv就是通過該命令獲得的。

k8s實踐(九):Helm and Kubeapps UI

圖片.png

3. helm status

<code>[root@master ~]# helm lsNAME            REVISION        UPDATED                         STATUS          CHART           APP VERSION     NAMESPACEkubeapps        1               Tue Oct  8 10:41:57 2019        DEPLOYED        kubeapps-2.1.6  v1.5.1          kubeapps mysql-stable    1               Tue Oct  8 15:39:07 2019        DEPLOYED        mysql-1.4.0     5.7.27          default  [root@master ~]# helm status mysql-stable/<code>

通過status查詢之前部署的服務mysql-stable的狀態

k8s實踐(九):Helm and Kubeapps UI

圖片.png

4. helm delete

<code>[root@master ~]# helm delete --purge mysql-stablerelease "mysql-stable" deleted/<code>

通過delete可刪除之前部署的mysql-stable服務

k8s實踐(九):Helm and Kubeapps UI

圖片.png

5. helm install

<code>[root@master ~]# helm install --name my-database stable/mysql/<code>

通過install安裝部署package,服務名為my-database;由於pv回收策略為Retain,需手動回收,故刪除pv並重建。

k8s實踐(九):Helm and Kubeapps UI

圖片.png

6. helm upgrade

<code>[root@master ~]# helm upgrade --force --set imageTag=5.7.15 my-database stable/mysql/<code>

mysql鏡像由5.7.14升級到了5.7.15

k8s實踐(九):Helm and Kubeapps UI

圖片.png

7. helm rollback

<code>[root@master ~]# helm history my-databaseREVISION        UPDATED                         STATUS          CHART           DESCRIPTION     1               Wed Oct  9 17:28:51 2019        SUPERSEDED      mysql-1.4.0     Install complete2               Wed Oct  9 17:31:09 2019        DEPLOYED        mysql-1.4.0     Upgrade complete[root@master ~]# helm rollback my-database 1Rollback was a success.[root@master ~]# kubectl get deployments. -o wideNAME                READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS          IMAGES         SELECTORmy-database-mysql   1/1     1            1           16m   my-database-mysql   mysql:5.7.14   app=my-database-mysql,release=my-database/<code>

回滾至上一個版本,鏡像版本回退為5.7.14

k8s實踐(九):Helm and Kubeapps UI

圖片.png

8. helm fetch

<code>[root@master ~]# helm fetch stable/mysql[root@master ~]# ll|grep mysql-rw-r--r--  1 root root    10657 10月 10 11:20 mysql-1.4.0.tgz/<code>

可通過helm fetch命令下載chart

五、Chart目錄結構

<code>[root@master ~]# helm fetch stable/wordpress   [root@master ~]# tar -zxvf wordpress-7.3.9.tgz /<code>

以wordpress為例介紹Charts目錄結構

k8s實踐(九):Helm and Kubeapps UI

圖片.png

文件名

說明

charts

可選,包含該Chart所依賴的其他Chart,依賴管理推薦採用requirements.yaml文件來進行

Chart.yaml

用於描述Chart信息的YAML文件

requirements.yaml

指明Chart可能依賴其他的Chart,與charts區別是charts需要提供整個Chart的文件,requirements僅需要註明依賴Chart的倉庫信息

templates

可選,結合values.yaml,能夠生成Kubernetes的manifest文件

templates/NOTES

可選,文本文件,用法描述

values.yaml

提供了Chart定製化安裝是配置參數的默認值

六、搭建本地倉庫

在master節點上啟動httpd容器來搭建私有倉庫,容器的volume採用Bind mounts方式,掛載點使用NFS共享存儲,

Docker Bind mounts實踐詳見:Docker實踐(三):數據持久化及共享

1. 創建自定義chart並打包

<code>[root@master ~]# helm create mychartCreating mychart[root@master ~]# helm package mychart/Successfully packaged chart and saved it to: /root/mychart-0.1.0.tgz/<code>

Helm會自動創建目錄mychart,並生成了各類chart文件,默認包含一個 nginx 應用示例。

k8s實踐(九):Helm and Kubeapps UI

圖片.png

2. 掛載NFS共享目錄

<code>[root@master ~]# mkdir /repo[root@master ~]# showmount -e 172.27.9.181[root@master ~]# mount -t nfs 172.27.9.181:/helm-repo /repo/<code>

本地新建目錄repo,掛載nfs共享目錄/helm-repo

k8s實踐(九):Helm and Kubeapps UI

圖片.png

3. 新建容器web-repo

<code>[root@master ~]# docker run -d -p 81:80 -v /repo/:/usr/local/apache2/htdocs --name web-repo httpd/<code>

新建容器web-repo,端口映射為81

k8s實踐(九):Helm and Kubeapps UI

圖片.png

4. 生成倉庫的index文件

<code>[root@master ~]# mkdir /repo/charts[root@master ~]# mv mychart-0.1.0.tgz /repo/charts/[root@master ~]# helm repo index /repo/charts --url http://172.27.9.131:81/charts/<code>

新建目錄/repo/charts,Helm會掃描/repo/charts目錄中的所有tgz包並生成index.yaml。--url指定的是新倉庫的訪問路徑。新生成的 index.yaml記錄了當前倉庫中所有chart的信息

k8s實踐(九):Helm and Kubeapps UI

圖片.png

5. 將新倉庫添加到Helm

<code>[root@master charts]# helm repo add pri-repo http://172.27.9.131:81/charts"pri-repo" has been added to your repositories/<code>

新倉庫命名為pri-repo

k8s實踐(九):Helm and Kubeapps UI

圖片.png

6. 驗證新倉庫

<code>[root@master charts]# helm install pri-repo/mychart/<code>

從新的倉庫pri-repo中部署應用,訪問nginx服務正常;當然,私有鏡像也可以部署在其他節點或者專門的鏡像服務器上

k8s實踐(九):Helm and Kubeapps UI

圖片.png

7. 更新本地倉庫

<code>[root@master charts]# helm repo index /repo/charts --url http://172.27.9.131:81/charts[root@master charts]# helm repo update /<code>

當本地倉庫有chart增減時,可通過執行update更新。

k8s實踐(九):Helm and Kubeapps UI

圖片.png

本文所有腳本和配置文件已上傳:https://github.com/loong576/k8s-Helm-and-Kubeapps.git


分享到:


相關文章: