444 views
Package Manager - Helm === ###### tags: `K8s` `Advanced Packaging Tools` ## 什麼是 Helm? * offical address: * Helm is a tool for managing Kubernetes charts. Charts are packages of pre-configured Kubernetes resources. * Helm 就有點像是 Ubuntu 中的 APT 系統,也類似 Ansible 中的 Galaxy;簡單來說就是可以將一個 or 多個應用包裝成一個服務,並透過 chart 的形式發佈,讓大家可以方便在 k8s 上安裝特定的服務。 * Helm 有三個觀念需要我們去了解,分別為 Chart、Release 與 Repository,其細節如下: * Chart:主要定義要被執行的應用程式中,所需要的工具、資源、服務等資訊,有點類似 Homebrew 的 Formula 或是 APT 的 dpkg 檔案。 * Release:一個被執行於 Kubernetes 的 Chart 實例。Chart 能夠在一個叢集中擁有多個 Release,例如 MySQL Chart,可以在叢集建立基於該 Chart 的兩個資料庫實例,其中每個 Release 都會有獨立的名稱。 * Repository:主要用來存放 Chart 的倉庫,如 KubeApps。 * 可以理解 Helm 主要目標就是從 Chart Repository 中,查找部署者需要的應用程式 Chart,然後以 Release 形式來部署到 Kubernetes 中進行管理。 ![](https://minio.mcl.math.ncu.edu.tw:443/hackmd/uploads/upload_7edfa6e2d102015c696f813cf829e642.png) ## Helm 系統元件 ### Helm 主要分為兩種元件,Helm Client 與 Tiller Server,兩者功能如下: * Helm Client:一個安裝 Helm CLI 的機器,該機器透過 gRPC 連接 Tiller Server 來對 Repository、Chart 與 Release 等進行管理與操作,如建立、刪除與升級等操作,細節可以查看 Helm Documentation。 * Tiller Server:主要負責接收來至 Client 的指令,並透過 kube-apiserver 與 Kubernetes 叢集做溝通,根據 Chart 定義的內容,來產生與管理各種對應 API 物件的 Kubernetes 部署檔案(又稱為 Release)。 ![](https://minio.mcl.math.ncu.edu.tw:443/hackmd/uploads/upload_f57b2ec934be3d41a5132c666d8c6184.png) ### Helm 要解決什麼問題? #### 一個工具被開發出來,總是被賦予要解決問題的任務,而 Helm 到底可以協助我們解決什麼樣的問題呢? * 先來討論目前的趨勢: * 線上的服務開始往 micro service 的方向走 * k8s 似乎也變成整個 container 大一統的平台 * 因此使用 k8s 作為承載 micro service 的平台的確也是很正常的事情,但 k8s 為了解決各式各樣的問題,提供了大量的 resource object(pod, deployment, service … etc),因此如何利用這些 resource object 來組成一個完整的系統,整個過程是很複雜的,其中包含了很多不同面向的問題需要處理,例如: * 如何管理、編輯 & 更新大量的 k8s resource object 設定檔? * 如何快速佈署一個含有很多設定檔的 k8s application? * 如何分享 & 重複利用 k8s resource object 設定檔? * 如何透過 parameter & template 的方式,使用相同的設定檔來支援不同環境上的佈署? * 如何管理 application 的 deployment, rollback, diff & history? * Application 發佈後如何進行驗證? * 在 micro service 的過程中,林林總總的問題也跑了出來,而 Helm 就是為了解決上述問題而被開發出來的工具,它使用了以下幾個方式來解決上述的問題: * 將 k8s resource object 打包到一個 chart 中 (chart 是多個 k8s resource object configuration 的集合) * 將 chart 保存在 chart repository 中,透過 repository 的方式來儲存 & 分享 chart * Helm 則利用 chart 來進行 deployment, upgrade, rollback, version control …. 等工作 ## 安裝 ### 事前準備 * 安裝前需要確認環境滿足以下幾膽: * 已部署 Kubernetes 叢集。 * 操作端安裝 kubectl 工具。 * 操作端可以透過 kubectl 工具管理到 Kubernetes(可用的 kubectl config)。 ### 安裝Helm * Helm 有許多種安裝方式,用 binary 檔案來進行安裝: ```shell= $ wget -qO- https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-linux-amd64.tar.gz | tar -zx $ sudo mv linux-amd64/helm /usr/local/bin/ $ helm version ``` ### 初始化 Helm * 在開始使用 Helm 之前,我們需要建置 Tiller Server 來對 Kubernetes 的管理,而 Helm CLI 內建也提供了快速初始化指令,如下: ```shell= $ kubectl -n kube-system create sa tiller $ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller $ helm init --service-account tiller --upgrade ``` ![](https://minio.mcl.math.ncu.edu.tw:443/hackmd/uploads/upload_49928968a416b99ef3216734ce1ecb7f.png) * 完成後,就可以透過 kubectl 來查看 Tiller Server 是否被建立: ```shell= $ kubectl get po,svc -n kube-system -l app=helm NAME READY STATUS RESTARTS AGE po/tiller-deploy-1651596238-5lsdw 1/1 Running 0 3m NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc/tiller-deploy 192.162.204.144 <none> 44134/TCP 3m ``` * 接著透過 helm ctl 來查看資訊: ```shell= $ export KUBECONFIG=/etc/kubernetes/admin.conf $ export HELM_HOST=$(kubectl describe svc/tiller-deploy -n kube-system | awk '/Endpoints/{print $2}') # wait for a few minutes $ helm version Client: &version.Version{SemVer:"v2.8.1", GitCommit:"6af75a8fd72e2aa18a2b278cfe5c7a1c5feca7f2", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.8.1", GitCommit:"6af75a8fd72e2aa18a2b278cfe5c7a1c5feca7f2", GitTreeState:"clean"} ``` ### 部署 Chart Release 實例 * 當完成初始化後,就可以透過 helm ctl 來管理與部署 Chart Release,我們可以到 KubeApps 查找想要部署的 Chart,如以下快速部屬 Jenkins 範例,首先先透過搜尋來查看目前應用程式版本: ```shell= $ helm search jenkins NAME VERSION DESCRIPTION stable/jenkins 0.6.3 Open source continuous integration server. It s... ``` * 接著透過inspect指令查看該 Chart 的參數資訊: ```shell= $ helm inspect stable/jenkins ... Persistence: Enabled: true ``` * 這邊需要建立一個PVC給Jenkins Chart來做儲存使用,手動建立Jenkins-pv-pvc.yaml ```shell= apiVersion: v1 kind: PersistentVolume metadata: name: jenkins-pv labels: app: jenkins spec: capacity: storage: 10Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle nfs: path: /var/nfs/jenkins server: 172.20.3.91 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: jenkins-pvc labels: app: jenkins spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi ``` * 接著透過 kubectl 來建立: ```shell= $ kubectl create -f jenkins-pv-pvc.yml persistentvolumeclaim "jenkins-pvc" created persistentvolume "jenkins-pv" created $ kubectl get pv,pvc NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE pv/jenkins-pv 10Gi RWO Recycle Bound default/jenkins-pvc 20s NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE pvc/jenkins-pvc Bound jenkins-pv 10Gi RWO 20s ``` * 當 PVC 建立完成後,就可以開始透過 Helm 來建立 Jenkins Release: ```shell= $ export PVC_NAME=$(kubectl get pvc -l app=jenkins --output=template --template="{{with index .items 0}}{{.metadata.name}}{{end}}") $ helm install --name demo --set Persistence.ExistingClaim=${PVC_NAME} stable/jenkins NAME: demo LAST DEPLOYED: Thu May 25 17:53:50 2017 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1beta1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE demo-jenkins 1 1 1 0 1s ==> v1/Secrets:wq NAME TYPE DATA AGE demo-jenkins Opaque 2 1s ==> v1/ConfigMap NAME DATA AGE demo-jenkins-tests 1 1s demo-jenkins 3 1s ==> v1/Service NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE d;1 mo-jenkins 192.169.143.140 <pending> 8080:30152/TCP,50000:3180goo6 ``` ### 更新 ```shell= helm upgrade -f myvalues.yaml -f override.yaml redis ./redis ``` ```shell= ip route del default via 10.1.1.254 dev ens4 ip route add default via 10.100.37.92 dev ens4 helm repo add common https://kubernetes-charts-incubator.storage.googleapis.com/ ```