目錄html
每一個成功的軟件平臺都有一個優秀的打包系統,好比 Debian、Ubuntu 的 apt,Redhat、Centos 的 yum。而 Helm 則是 Kubernetes 上的包管理器。
Kubernetes 可以很好地組織和編排容器,但它缺乏一個更高層次的應用打包工具,而 Helm 就是來幹這件事的。
舉個例子,咱們須要部署一個MySQL服務,Kubernetes則須要部署如下對象:
① 爲了可以讓外界訪問到MySQL,須要部署一個mysql的service;
②須要進行定義MySQL的密碼,則須要部署一個Secret;
③Mysql的運行須要持久化的數據存儲,此時還須要部署PVC;
④保證後端mysql的運行,還須要部署一個Deployment,以支持以上的對象。
針對以上對象,咱們可使用YAML文件進行定義並部署,可是僅僅對於單個的服務支持,若是應用須要由一個甚至幾十個這樣的服務組成,而且還須要考慮各類服務的依賴問題,可想而知,這樣的組織管理應用的方式就顯得繁瑣。爲此就誕生了一個工具Helm,就是爲了解決Kubernetes這種應用部署繁重的現象。node
Helm的核心術語:mysql
Helm的程序架構:
Helm主要由Helm客戶端、Tiller服務器和Charts倉庫組成,以下圖:linux
簡單的說:Helm 客戶端負責管理 chart;Tiller 服務器負責管理 release。nginx
Helm的部署方式有兩種:預編譯的二進制程序和源碼編譯安裝,這裏使用二進制的方式進行安裝git
[root@master manifests]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz [root@master manifests]# tar xf helm-v2.9.1-linux-amd64.tar.gz [root@master manifests]# cd linux-amd64 [root@master linux-amd64]# ls helm LICENSE README.md [root@master linux-amd64]# cp helm /usr/bin/ [root@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文件。github
Tiller運行在K8s集羣之上,也必須擁有集羣的管理權限,也就是須要一個serviceaccount,進行一個clusterrolebinding到cluster-admin。
Tiller的RBAC配置示例連接:web
https://github.com/helm/helm/blob/master/docs/rbac.mdsql
[root@master linux-amd64]# cd .. [root@master manifests]# mkdir helm [root@master manifests]# cd helm [root@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@master helm]# kubectl apply -f tiller-rbac.yaml serviceaccount/tiller created clusterrolebinding.rbac.authorization.k8s.io/tiller created [root@master helm]# kubectl get sa -n kube-system|grep tiller tiller 1 14s [root@master helm]# 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! #helm init命令進行初始化時,會用到gcr.io/kubernetes-helm中的景象,須要提早下載,鏡像標籤和Helm同版本號 [root@master helm]# docker pull xiaobai20201/tiller:v2.9.1 [root@master pki]# docker tag xiaobai20201/tiller:v2.9.1 gcr.io/kubernetes-helm/tiller:v2.9.1 [root@master helm]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE canal-nbspn 3/3 Running 0 30h canal-pj6rx 3/3 Running 0 30h canal-rgsnp 3/3 Running 0 30h coredns-78d4cf999f-6cb69 1/1 Running 3 14d coredns-78d4cf999f-tflpn 1/1 Running 2 14d etcd-master 1/1 Running 0 14d kube-apiserver-master 1/1 Running 0 14d kube-controller-manager-master 1/1 Running 0 14d kube-flannel-ds-amd64-5zrk7 1/1 Running 0 31h kube-flannel-ds-amd64-pql5n 1/1 Running 0 31h kube-flannel-ds-amd64-ssd29 1/1 Running 0 31h kube-proxy-ch4vp 1/1 Running 0 14d kube-proxy-cz2rf 1/1 Running 1 14d kube-proxy-kdp7d 1/1 Running 0 14d kube-scheduler-master 1/1 Running 0 14d kubernetes-dashboard-6f9998798-klf4t 1/1 Running 0 2d2h metrics-server-v0.3.1-65bd5d59b9-xvmns 2/2 Running 0 5h31m tiller-deploy-c4f47c598-gl6rp 1/1 Running 0 11m #安裝完成後,執行helm version能夠看到客戶端和服務端的版本號,兩個都顯示錶示正常安裝。 [root@master helm]# helm version Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
若是但願在安裝時自定義一些參數,能夠參考一下的一些參數:docker
(1)kubectl delete deployment tiller-deploy -n kube-system (2)helm reset
官方可用的Chart列表:
https://hub.kubeapps.com
[root@master helm]# helm -h The Kubernetes package manager To begin working with Helm, run the 'helm init' command: $ helm init This will install Tiller to your running Kubernetes cluster. It will also set up any necessary local configuration. Common actions from this point include: - helm search: search for charts #搜索charts - helm fetch: download a chart to your local directory to view #下載charts到本地 - helm install: upload the chart to Kubernetes #安裝charts - helm list: list releases of charts #列出charts的版本 Environment: $HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm $HELM_HOST set an alternative Tiller host. The format is host:port $HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. $TILLER_NAMESPACE set an alternative Tiller namespace (default "kube-system") $KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config") Usage: helm [command] Available Commands: completion Generate autocompletions script for the specified shell (bash or zsh) #爲指定的shell生成自動補全腳本(bash或zsh) create create a new chart with the given name #建立一個新的charts delete given a release name, delete the release from Kubernetes #刪除指定版本的release dependency manage a chart's dependencies # 管理charts的依賴 fetch download a chart from a repository and (optionally) unpack it in local directory # 下載charts並解壓到本地目錄 get download a named release# 下載一個release history fetch release history #release歷史信息 home displays the location of HELM_HOME #顯示helm的家目錄 init initialize Helm on both client and server #在客戶端和服務端初始化helm inspect inspect a chart #查看charts的詳細信息 install install a chart archive #安裝charts lint examines a chart for possible issues #檢測包的存在問題 list list releases #列出release package package a chart directory into a chart archive # 將chart目錄進行打包 plugin add, list, or remove Helm plugins #add(增長), list(列出), or remove(移除) Helm 插件 repo add, list, remove, update, and index chart repositories #add(增長), list(列出), remove(移除), update(更新), and index(索引) chart倉庫 reset uninstalls Tiller from a cluster #卸載tiller rollback roll back a release to a previous revision #release版本回滾 search search for a keyword in charts# 關鍵字搜索chart serve start a local http web server # 啓動一個本地的http server status displays the status of the named release #查看release狀態信息 template locally render templates #本地模板 test test a release # release測試 upgrade upgrade a release #release更新 verify verify that a chart at the given path has been signed and is valid #驗證chart的簽名和有效期 version print the client/server version information #打印客戶端和服務端的版本信息
Charts是Helm的程序包,它們都存在在Charts倉庫當中。Kubernetes官方的倉庫保存了一系列的Charts,倉庫默認的名稱爲stable。安裝Charts到集羣時,Helm首先會到官方倉庫獲取相關的Charts,並建立release。可執行 helm search 查看當前可安裝的 chart 。
Helm 能夠像 yum 管理軟件包同樣管理 chart。 yum 的軟件包存放在倉庫中,一樣的,Helm 也有倉庫。
Helm 安裝時已經默認配置好了兩個倉庫:stable 和 local。stable 是官方倉庫,local 是用戶存放本身開發的chart的本地倉庫。能夠經過helm repo list進行查看。因爲網絡緣由,國內可能沒法更新倉庫源(網絡不穩定偶爾出問題),這裏能夠更改成阿里雲的倉庫源,。
[root@master helm]# helm repo remove stable "stable" has been removed from your repositories [root@master helm]# [root@master helm]# helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts "stable" has been added to your repositories [root@master helm]# [root@master helm]# helm repo update 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!⎈ [root@master helm]# helm repo list NAME URL local http://127.0.0.1:8879/charts stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
與 yum 同樣,helm 也支持關鍵字搜索:
[root@master helm]# helm search stable/mysql NAME CHART VERSION APP VERSION DESCRIPTION stable/mysql 0.15.0 5.7.14 Fast, reliable, scalable, and easy to use open-... stable/mysqldump 2.4.0 2.4.0 A Helm chart to help backup MySQL databases usi..
使用helm inspect也能夠查看詳細信息
[root@master helm]# helm inspect stable/mysql
包括 DESCRIPTION 在內的全部信息,只要跟關鍵字匹配,都會顯示在結果列表中。
安裝 chart 也很簡單,執行以下命令能夠安裝 MySQL。
[root@master helm]# helm install stable/mysql Error: no available release name found #出現此類報錯主要是tiller權限的問題 [root@master helm]# kubectl create serviceaccount --namespace kube-system tiller Error from server (AlreadyExists): serviceaccounts "tiller" already exists [root@master helm]# kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller clusterrolebinding.rbac.authorization.k8s.io/tiller-cluster-rule created [root@master helm]# kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}' deployment.extensions/tiller-deploy patched (no change) #再次安裝 [root@master helm]# helm install stable/mysql NAME: callous-zorse #第一部分 LAST DEPLOYED: Thu Apr 11 09:31:41 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: #第二部分 ==> v1/Secret NAME TYPE DATA AGE callous-zorse-mysql Opaque 2 0s ==> v1/ConfigMap NAME DATA AGE callous-zorse-mysql-test 1 0s ==> v1/PersistentVolumeClaim NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE callous-zorse-mysql Pending 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE callous-zorse-mysql ClusterIP 10.109.125.202 <none> 3306/TCP 0s ==> v1beta1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE callous-zorse-mysql 1 1 1 0 0s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE callous-zorse-mysql-f5c97689b-ch5cf 0/1 Pending 0 0s NOTES: #第三部分 MySQL can be accessed via port 3306 on the following DNS name from within your cluster: callous-zorse-mysql.default.svc.cluster.local To get your root password run: MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default callous-zorse-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 callous-zorse-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 command to route the connection: kubectl port-forward svc/callous-zorse-mysql 3306 mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
輸出分爲三部分:
NAME
是 release
的名字,由於咱們沒用 -n 參數指定,Helm 隨機生成了一個,這裏是 callous-zorse
。NAMESPACE
是 release
部署的 namespace
,默認是 default
,也能夠經過 --namespace
指定。STATUS
爲 DEPLOYED
,表示已經將 chart
部署到集羣。release
包含的資源:Service
、Deployment
、Secret
和 PersistentVolumeClaim
,其名字都是 callous-zorse-mysql
,命名的格式爲 ReleasName-ChartName
。NOTES
部分顯示的是 release
的使用方法。好比如何訪問 Service
,如何獲取數據庫密碼,以及如何鏈接數據庫等。release
的各個對象:[root@master helm]# kubectl get deploy,svc,pvc,secret callous-zorse-mysql NAME READY UP-TO-DATE AVAILABLE AGE deployment.extensions/callous-zorse-mysql 0/1 1 0 10m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/callous-zorse-mysql ClusterIP 10.109.125.202 <none> 3306/TCP 10m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/callous-zorse-mysql Pending 10m NAME TYPE DATA AGE secret/callous-zorse-mysql Opaque 2 10m
因爲咱們尚未準備 PersistentVolume
,當前 release 還不可用。
helm list
顯示已經部署的 release
,helm delete
能夠刪除 release
。
[root@master helm]# helm list NAME REVISION UPDATED STATUS CHART NAMESPACE callous-zorse 1 Thu Apr 11 09:31:41 2019 DEPLOYED mysql-0.15.0 default [root@master helm]# helm delete callous-zorse release "callous-zorse" 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@master ~]# cd .helm/cache/archive/ [root@master archive]# ls mysql-0.15.0.tgz [root@master archive]# tar xf mysql-0.15.0.tgz tar: mysql/Chart.yaml:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/values.yaml:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/templates/NOTES.txt:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/templates/_helpers.tpl:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/templates/configurationFiles-configmap.yaml:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/templates/deployment.yaml:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/templates/initializationFiles-configmap.yaml:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/templates/pvc.yaml:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/templates/secrets.yaml:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/templates/svc.yaml:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/templates/tests/test-configmap.yaml:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/templates/tests/test.yaml:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/.helmignore:不可信的舊時間戳 1970-01-01 08:00:00 tar: mysql/README.md:不可信的舊時間戳 1970-01-01 08:00:00 [root@master archive]# tree . ├── mysql │ ├── Chart.yaml │ ├── README.md │ ├── templates │ │ ├── configurationFiles-configmap.yaml │ │ ├── deployment.yaml │ │ ├── _helpers.tpl │ │ ├── initializationFiles-configmap.yaml │ │ ├── NOTES.txt │ │ ├── pvc.yaml │ │ ├── secrets.yaml │ │ ├── svc.yaml │ │ └── tests │ │ ├── test-configmap.yaml │ │ └── test.yaml │ └── values.yaml └── mysql-0.15.0.tgz 3 directories, 14 files
Helm 經過模板建立 Kubernetes 可以理解的 YAML 格式的資源配置文件,咱們將經過例子來學習如何使用模板。
以 templates/secrets.yaml 爲例:
{{- if not .Values.existingSecret }} apiVersion: v1 kind: Secret metadata: name: {{ template "mysql.fullname" . }} labels: app: {{ template "mysql.fullname" . }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" type: Opaque data: {{ if .Values.mysqlRootPassword }} mysql-root-password: {{ .Values.mysqlRootPassword | b64enc | quote }} {{ else }} mysql-root-password: {{ randAlphaNum 10 | b64enc | quote }} {{ end }} {{ if .Values.mysqlPassword }} mysql-password: {{ .Values.mysqlPassword | b64enc | quote }} {{ else }} mysql-password: {{ randAlphaNum 10 | b64enc | quote }} {{ end }} {{- if .Values.ssl.enabled }} {{ if .Values.ssl.certificates }} {{- range .Values.ssl.certificates }} --- apiVersion: v1 kind: Secret metadata: name: {{ .name }} labels: app: {{ template "mysql.fullname" $ }} chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" release: "{{ $.Release.Name }}" heritage: "{{ $.Release.Service }}" type: Opaque data: ca.pem: {{ .ca | b64enc }} server-cert.pem: {{ .cert | b64enc }} server-key.pem: {{ .key | b64enc }} {{- end }} {{- end }} {{- end }} {{- end }}
從結構上看,文件的內容和咱們在定義Secret的配置上大體類似,只是大部分的屬性值變成了{{ xxx }}。這些{{ xx }}其實是模板的語法。Helm採用了Go語言的模板來編寫chart。
{{ template "mysql.fullname" . }}
定義 Secret 的 nametemplates/_helpers.tpl
文件中定義的。[root@master templates]# vim _helpers.tpl ...... If release name contains chart name it will be used as a full name. */}} {{- define "mysql.fullname" -}} {{- if .Values.fullnameOverride -}} {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} {{- else -}} {{- $name := default .Chart.Name .Values.nameOverride -}} {{- if contains $name .Release.Name -}} {{- printf .Release.Name | trunc 63 | trimSuffix "-" -}} {{- else -}} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} {{- end -}} {{- end -}} {{- end -}} ......
這個定義仍是很複雜的,由於它用到了模板語言中的對象、函數、流控制等概念。如今看不懂不要緊,這裏咱們學習的重點是:若是存在一些信息多個模板都會用到,則可在 templates/_helpers.tpl
中將其定義爲子模板,而後經過 templates 函數引用。
這裏 mysql.fullname
是由 release 與 chart 兩者名字拼接組成。
根據 chart 的最佳實踐,全部資源的名稱都應該保持一致,對於咱們這個 chart,不管 Secret 仍是 Deployment、PersistentVolumeClaim、Service,它們的名字都是子模板 mysql.fullname
的值。
Chart
和 Release
是 Helm 預約義的對象,每一個對象都有本身的屬性,能夠在模板中使用。若是使用下面命令安裝 chart:[root@master templates]# helm search stable/mysql NAME CHART VERSION APP VERSION DESCRIPTION stable/mysql 0.15.0 5.7.14 Fast, reliable, scalable, and easy to use open-... stable/mysqldump 2.4.0 2.4.0 A Helm chart to help backup MySQL databases usi... [root@master templates]# helm install stable/mysql -n my
則
{{ .Chart.Name }}
的值爲 mysql
。
{{ .Chart.Version }}
的值爲 0.15.0
。
{{ .Release.Name }}
的值爲 my
。
{{ .Release.Service }}
始終取值爲 Tiller
.
{{ template "mysql.fullname" . }}
計算結果爲 my-mysq
l。
mysql-root-password
的值,不過使用了 if-else
的流控制,其邏輯爲:.Values.mysqlRootPassword
有值,則對其進行 base64 編碼;不然隨機生成一個 10 位的字符串並編碼。Values
也是預約義的對象,表明的是values.yaml
文件。而 .Values.mysqlRootPassword
則是values.yaml
中定義的 mysqlRootPassword
參數:
[root@master mysql]# vim values.yaml ## mysql image version ## ref: https://hub.docker.com/r/library/mysql/tags/ ## image: "mysql" imageTag: "5.7.14" busybox: image: "busybox" tag: "1.29.3" testFramework: image: "dduportal/bats" tag: "0.4.0" ## Specify password for root user ## ## Default: random 10 character string # mysqlRootPassword: testing ## Create a database user ## # mysqlUser: ## Default: random 10 character string # mysqlPassword:
由於 mysqlRootPassword
被註釋掉了,沒有賦值,因此邏輯判斷會走 else,即隨機生成密碼。
randAlphaNum
、b64enc
、quote
都是 Go 模板語言支持的函數,函數之間能夠經過管道 | 鏈接。
{{ randAlphaNum 10 | b64enc | quote }}
的做用是首先隨機產生一個長度爲 10 的字符串,而後將其 base64 編碼,最後兩邊加上雙引號。
templates/secrets.yam
l 這個例子展現了chart
模板主要的功能,咱們最大的收穫應該是:模板將 chart
參數化了,經過 values.yaml
能夠靈活定製應用。
不管多複雜的應用,用戶均可以用 Go 模板語言編寫出 chart。無非是使用到更多的函數、對象和流控制
做爲準備工做,安裝以前須要先清楚 chart 的使用方法。這些信息一般記錄在 values.yaml 和 README.md 中。除了下載源文件查看,執行 helm inspect values
多是更方便的方法。
[root@master helm]# helm inspect values stable/mysql ## mysql image version ## ref: https://hub.docker.com/r/library/mysql/tags/ ## image: "mysql" imageTag: "5.7.14" busybox: image: "busybox" tag: "1.29.3" testFramework: image: "dduportal/bats" tag: "0.4.0" ## Specify password for root user ## ## Default: random 10 character string # mysqlRootPassword: testing ## Create a database user ## # mysqlUser: ## Default: random 10 character string # mysqlPassword: ## Allow unauthenticated access, uncomment to enable ## # mysqlAllowEmptyPassword: true ## Create a database ## # mysqlDatabase: ## Specify an imagePullPolicy (Required) ## It's recommended to change this to 'Always' if the image tag is 'latest' ## ref: http://kubernetes.io/docs/user-guide/images/#updating-images ## imagePullPolicy: IfNotPresent extraVolumes: | # - name: extras # emptyDir: {} extraVolumeMounts: | # - name: extras # mountPath: /usr/share/extras # readOnly: true extraInitContainers: | # - name: do-something # image: busybox # command: ['do', 'something'] # Optionally specify an array of imagePullSecrets. # Secrets must be manually created in the namespace. # ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod # imagePullSecrets: # - name: myRegistryKeySecretName ## Node selector ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector nodeSelector: {} ## Tolerations for pod assignment ## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ ## tolerations: [] livenessProbe: initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 3 readinessProbe: initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 1 successThreshold: 1 failureThreshold: 3 ## 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 annotations: {} ## Configure resource requests and limits ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ ## resources: requests: memory: 256Mi cpu: 100m # Custom mysql configuration files used to override default mysql settings configurationFiles: {} # mysql.cnf: |- # [mysqld] # skip-name-resolve # ssl-ca=/ssl/ca.pem # ssl-cert=/ssl/server-cert.pem # ssl-key=/ssl/server-key.pem # Custom mysql init SQL files used to initialize the database initializationFiles: {} # first-db.sql: |- # CREATE DATABASE IF NOT EXISTS first DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; # second-db.sql: |- # CREATE DATABASE IF NOT EXISTS second DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; metrics: enabled: false image: prom/mysqld-exporter imageTag: v0.10.0 imagePullPolicy: IfNotPresent resources: {} annotations: {} # prometheus.io/scrape: "true" # prometheus.io/port: "9104" livenessProbe: initialDelaySeconds: 15 timeoutSeconds: 5 readinessProbe: initialDelaySeconds: 5 timeoutSeconds: 1 ## Configure the service ## ref: http://kubernetes.io/docs/user-guide/services/ service: annotations: {} ## Specify a service type ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types type: ClusterIP port: 3306 # nodePort: 32000 ssl: enabled: false secret: mysql-ssl-certs certificates: # - name: mysql-ssl-certs # ca: |- # -----BEGIN CERTIFICATE----- # ... # -----END CERTIFICATE----- # cert: |- # -----BEGIN CERTIFICATE----- # ... # -----END CERTIFICATE----- # key: |- # -----BEGIN RSA PRIVATE KEY----- # ... # -----END RSA PRIVATE KEY----- ## Populates the 'TZ' system timezone environment variable ## ref: https://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html ## ## Default: nil (mysql will use image's default timezone, normally UTC) ## Example: 'Australia/Sydney' # timezone: # To be added to the database server pod(s) podAnnotations: {} podLabels: {} ## Set pod priorityClassName # priorityClassName: {}
輸出的其實是 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 annotations: {}
chart 定義了一個 PersistentVolumeClaim
,申請 8G 的 PersistentVolume。因爲咱們的實驗環境不支持動態供給,因此得預先建立好相應的 PV,其配置文件 mysql-pv.yml 內容爲:
[root@master helm]# cd ../volume/ [root@master volume]# vim 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: nfs [root@master volume]# kubectl apply -f mysql-pv.yaml persistentvolume/mysql-pv2 created [root@master volume]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mysql-pv2 8Gi RWO Retain Bound default/my-mysql 30s
除了接受 values.yaml 的默認值,咱們還能夠定製化 chart,好比設置 mysqlRootPassword
Helm有兩種方式傳遞配置參數:
helm inspect values mysql > myvalues.yaml
生成values,而後設置mysqlRootPassword
以後執行 helm install --values=myvalues.yaml mysql
[root@master helm]# helm install stable/mysql --set mysqlRootPassword=abc123 -n my-2 NAME: my-2 LAST DEPLOYED: Thu Apr 11 11:26:33 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-2-mysql ClusterIP 10.97.198.107 <none> 3306/TCP 1s ==> v1beta1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE my-2-mysql 1 1 1 0 1s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE my-2-mysql-5dc69d7d66-rmt2z 0/1 Pending 0 1s ==> v1/Secret NAME TYPE DATA AGE my-2-mysql Opaque 2 1s ==> v1/ConfigMap NAME DATA AGE my-2-mysql-test 1 1s ==> v1/PersistentVolumeClaim NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE my-2-mysql Pending 1s ......
mysqlRootPassword
設置爲 abc123。另外,-n
設置elease
爲 my-2,各種資源的名稱即爲my-2-mysql
。
經過 helm list
和helm status
能夠查看 chart 的最新狀態。
release 發佈後能夠執行 helm upgrade 對其升級,經過 --values 或 --set應用新的配置。好比將當前的 MySQL 版本升級到 5.7.15:
[root@master helm]# helm upgrade --set imageTag=5.7.15 my stable/mysql
helm history 能夠查看 release 全部的版本。經過 helm rollback 能夠回滾到任何版本。
[root@master helm]# helm history my-2 REVISION UPDATED STATUS CHART DESCRIPTION 1 Thu Apr 11 11:26:33 2019 SUPERSEDED mysql-0.15.0 Install complete 2 Thu Apr 11 11:29:41 2019 DEPLOYED mysql-0.15.0 Upgrade complete [root@master helm]# helm rollback my-2 1 Rollback was a success! Happy Helming! [root@master helm]# helm history my-2 REVISION UPDATED STATUS CHART DESCRIPTION 1 Thu Apr 11 11:26:33 2019 SUPERSEDED mysql-0.15.0 Install complete 2 Thu Apr 11 11:29:41 2019 SUPERSEDED mysql-0.15.0 Upgrade complete 3 Thu Apr 11 11:30:21 2019 DEPLOYED mysql-0.15.0 Rollback to 1
Kubernetes 給咱們提供了大量官方 chart,不過要部署微服務應用,仍是須要開發本身的 chart。
執行 helm create mychart
的命令建立 chart mychart
:
[root@master helm]# cd mychart/ [root@master mychart]# tree . ├── charts ├── Chart.yaml ├── templates │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── ingress.yaml │ ├── NOTES.txt │ └── service.yaml └── values.yaml 2 directories, 7 files
Helm 會幫咱們建立目錄 mychart
,並生成了各種 chart 文件。這樣咱們就能夠在此基礎上開發本身的 chart 了。
elm 提供了 debug 的工具:helm lint
和 helm install --dry-run --debug
。
helm lint
會檢測 chart 的語法,報告錯誤以及給出建議。 故意修改mychart中的value.yaml,進行檢測:
helm lint mychart
會指出這個語法錯誤。
[root@master helm]# 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 12: could not find expected ':' Error: 1 chart(s) linted, 1 chart(s) failed 1 chart(s) linted, no failures [root@master helm]# 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@master helm]# helm install --dry-run mychart --debug [debug] Created tunnel using local port: '28515' [debug] SERVER: "127.0.0.1:28515" [debug] Original chart version: "" [debug] CHART PATH: /root/manifests/helm/mychart NAME: early-marsupial REVISION: 1 RELEASED: Thu Apr 11 11:40:39 2019 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: early-marsupial-mychart labels: app: mychart chart: mychart-0.1.0 release: early-marsupial heritage: Tiller spec: type: ClusterIP ports: - port: 80 targetPort: http protocol: TCP name: http selector: app: mychart release: early-marsupial --- # Source: mychart/templates/deployment.yaml apiVersion: apps/v1beta2 kind: Deployment metadata: name: early-marsupial-mychart labels: app: mychart chart: mychart-0.1.0 release: early-marsupial heritage: Tiller spec: replicas: 1 selector: matchLabels: app: mychart release: early-marsupial template: metadata: labels: app: mychart release: early-marsupial 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: {}
咱們能夠檢視這些輸出,判斷是否與預期相符。
Helm自持四種方法安裝chart:
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@master helm]# helm install ./mychart/ NAME: soft-worm LAST DEPLOYED: Thu Apr 11 13:43:18 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1beta2/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE soft-worm-mychart 1 1 1 0 0s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE soft-worm-mychart-78ccf58c6-t6jp5 0/1 Pending 0 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE soft-worm-mychart ClusterIP 10.103.92.36 <none> 80/TCP 0s NOTES: 1. Get the application URL by running these commands: export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=soft-worm" -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 倉庫,下面演示在 nfs 10.0.0.14 上搭建倉庫。
在nfs上啓動nginx(容器也能夠)並建立一個server標籤(因爲實驗用nfs已經有nginx服務,新建個server標籤監聽8080端口)
...... server { listen 8080; location / { root /data/; } # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; } ..... [root@nfs ~]# mkdir /data/charts/ -p [root@nfs ~]# nginx -s reload
經過 helm package 將 mychart 打包。
[root@master helm]# helm package ./mychart/ Successfully packaged chart and saved it to: /root/manifests/helm/mychart-0.1.0.tgz #執行 helm repo index 生成倉庫的 index 文件 [root@master helm]# helm package ./mychart/ Successfully packaged chart and saved it to: /root/manifests/helm/mychart-0.1.0.tgz [root@master helm]# mkdir myrepo [root@master helm]# mv /root/manifests/helm/mychart-0.1.0.tgz ./myrepo/ [root@master helm]# helm repo index ./myrepo/ --url http://10.0.0.14:8080/charts [root@master helm]# ls myrepo/ index.yaml mychart-0.1.0.tgz
Helm 會掃描 myrepo 目錄中的全部 tgz 包並生成 index.yaml。--url指定的是新倉庫的訪問路徑。新生成的 index.yaml 記錄了當前倉庫中全部 chart 的信息:
當前只有 mychart 這一個 chart。
[root@master helm]# cat myrepo/index.yaml apiVersion: v1 entries: mychart: - apiVersion: v1 appVersion: "1.0" created: 2019-04-11T14:18:48.494631141+08:00 description: A Helm chart for Kubernetes digest: 08abeb3542e8a9ab90df776d3a646199da8be0ebfc5198ef032190938d49e30a name: mychart urls: - http://10.0.0.14:8080/charts/mychart-0.1.0.tgz version: 0.1.0 generated: 2019-04-11T14:18:48.494210001+08:00
將 mychart-0.1.0.tgz 和 index.yaml 上傳到 k8s-node1 的 /var/www/charts 目錄。
[root@master helm]# scp ./myrepo/* nfs:/data/charts/ index.yaml 100% 394 407.6KB/s 00:00 mychart-0.1.0.tgz 100% 2556 2.8MB/s 00:00
經過 helm repo add 將新倉庫添加到 Helm。
[root@master helm]# helm repo add nfs_repo http://10.0.0.14:8080/charts "nfs_repo" has been added to your repositories [root@master helm]# helm repo list NAME URL stable https://kubernetes-charts.storage.googleapis.com local http://127.0.0.1:8879/charts nfs_repo http://10.0.0.14:8080/charts
如今已經能夠 repo search 到 mychart 了。
[root@master helm]# helm search mychart NAME CHART VERSION APP VERSION DESCRIPTION local/mychart 0.1.0 1.0 A Helm chart for Kubernetes nfs_repo/mychart 0.1.0 1.0 A Helm chart for Kubernetes
除了 newrepo/mychart,這裏還有一個 local/mychart。這是由於在執行打包操做的同時,mychart 也被同步到了 local 的倉庫。
已經能夠直接重新倉庫安裝 mychart 了。
[root@master helm]# helm install --name my-3 nfs_repo/mychart NAME: my-3 LAST DEPLOYED: Thu Apr 11 14:26:53 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE my-3-mychart-69cdddc4fb-cljmt 0/1 ContainerCreating 0 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-3-mychart ClusterIP 10.97.149.58 <none> 80/TCP 0s ==> v1beta2/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE my-3-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=my-3" -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,須要用 helm repo update 更新本地的 index。相似於yum update /apt-get update
[root@master helm]# helm repo update Hang tight while we grab the latest from your chart repositories... ...Skip local chart repository ...Successfully got an update from the "nfs_repo" 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 172.217.161.176:443: connect: connection timed out Update Complete. ⎈ Happy Helming!⎈
https://www.cnblogs.com/linuxk