目錄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。