您好,登錄后才能下訂單哦!
每個成功的軟件平臺都有一個優秀的打包系統,比如 Debian、Ubuntu 的 apt,Redhat、Centos 的 yum。而 Helm 則是 Kubernetes 上的包管理器。
Helm,架構和組件,以及如何使用 Helm。
Helm 到底解決了什么問題?為什么 Kubernetes 需要 Helm?
答案是:Kubernetes 能夠很好地組織和編排容器,但它缺少一個更高層次的應用打包工具,而 Helm 就是來干這件事的。
先來看個例子。
比如對于一個 MySQL 服務, Kubernetes 需要部署下面這些對象:
Service,讓外界能夠訪問到 MySQL。
apiVersion: v1
kind: Service
metadata:
name: my-mysql
labels:
app: my-mysql
spec:
ports:
- name: mysql
port: 3306
targetPort: mysql
selector:
app: my-mysql
Secret,定義 MySQL 的密碼。
apiVersion: v1
kind: Secret
metadata:
name: my-mysql
labels:
app: my-mysql
type: Opaque
data:
mysql-root-password: "M0MzREhRQWRjeQ=="
mysql-password: "eGNXZkpMNmlkSw=="
PersistentVolumeClaim,為 MySQL 申請持久化存儲空間。
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: my-mysql
labels:
app: my-mysql
spec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 8Gi
Deployment,部署 MySQL Pod,并使用上面的這些支持對象。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-mysql
labels:
app: my-mysql
spec:
template:
metadata:
labels:
app: my-mysql
spec:
containers:
- name: my-mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: my-mysql
key: mysql-password
- name: MYSQL_USER
value: ""
- name: MYSQL_DATABASE
value: ""
ports:
- name: mysql
containerPort: 3306
volumMounts:
- name: data
mountPath: /var/lib/mysql
volumes:
- name: data
persistentVolumeClaim:
claimName: my-mysql
我們可以將上面這些配置保存到對象各自的文件中,或者集中寫進一個配置文件,然后通過 kubectl apply -f 部署。
到目前為止,Kubernetes 對服務的部署支持得都挺好,如果應用只由一個或幾個這樣的服務組成,上面的部署方式完全足夠了。
但是,如果我們開發的是微服務架構的應用,組成應用的服務可能多達十個甚至幾十上百個,這種組織和管理應用的方式:
Helm 能夠解決上面這些問題,Helm 幫助 Kubernetes 成為微服務架構應用理想的部署平臺。
Helm 的架構。
Helm 有兩個重要的概念:chart 和 release。
chart 是創建一個應用的信息集合,包括各種 Kubernetes 對象的配置模板、參數定義、依賴關系、文檔說明等。chart 是應用部署的自包含邏輯單元。可以將 chart 想象成 apt、yum 中的軟件安裝包。
release 是 chart 的運行實例,代表了一個正在運行的應用。當 chart 被安裝到 Kubernetes 集群,就生成一個 release。chart 能夠多次安裝到同一個集群,每次安裝都是一個 release。
Helm 是包管理工具,這里的包就是指的 chart。Helm 能夠:
Helm 包含兩個組件:Helm 客戶端 和 Tiller 服務器。
Helm 客戶端是終端用戶使用的命令行工具,用戶可以:
Tiller 服務器運行在 Kubernetes 集群中,它會處理 Helm 客戶端的請求,與 Kubernetes API Server 交互。Tiller 服務器負責:
簡單的講:Helm 客戶端負責管理 chart;Tiller 服務器負責管理 release。
通常,我們將 Helm 客戶端安裝在能夠執行 kubectl 命令的節點上,只需要下面一條命令:
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash
執行 helm version 驗證。
[root@k8s-master ~]# helm version
Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
Error: could not find tiller
目前只能查看到客戶端的版本,服務器還沒有安裝。
helm 有很多子命令和參數,為了提高使用命令行的效率,通常建議安裝 helm 的 bash 命令補全腳本,方法如下:
# source <(helm completion bash)
# echo "source <(helm completion bash)" >> ~/.bashrc
重新登錄后就可以通過 Tab 鍵補全 helm 子命令和參數了。
[root@k8s-master ~]# helm
completion history list search verify
create home package serve version
delete init plugin status
dependency inspect repo template
fetch install reset test
get lint rollback upgrade
[root@k8s-master ~]# helm install --
--atomic --render-subchart-notes
--ca-file= --replace
--cert-file= --repo=
--debug --set=
--dep-up --set-file=
--description= --set-string=
--devel --tiller-connection-timeout=
--dry-run --tiller-namespace=
--home= --timeout=
--host= --tls
--key-file= --tls-ca-cert=
--keyring= --tls-cert=
--kubeconfig= --tls-hostname=
--kube-context= --tls-key=
--name= --tls-verify
--namespace= --username=
--name-template= --values=
--no-crd-hook --verify
--no-hooks --version=
--password= --wait
[root@k8s-master ~]# helm install --
Tiller 服務器安裝非常簡單,只需要執行 helm init:
[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.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Tiller 本身也是作為容器化應用運行在 Kubernetes Cluster 中的:
[root@k8s-master ~]# kubectl get --namespace=kube-system svc tiller-deploy
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
tiller-deploy ClusterIP 10.104.165.164 <none> 44134/TCP 30s
# docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.3
# docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.3 gcr.io/kubernetes-helm/tiller:v2.14.3
可以看到 Tiller 的 Service、Deployment 和 Pod。
[root@k8s-master ~]# kubectl get --namespace=kube-system svc tiller-deploy
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
tiller-deploy ClusterIP 10.104.165.164 <none> 44134/TCP 19m
[root@k8s-master ~]# kubectl get -n kube-system deployments. tiller-deploy
NAME READY UP-TO-DATE AVAILABLE AGE
tiller-deploy 1/1 1 1 16m
[root@k8s-master ~]# kubectl get -n kube-system pod tiller-deploy-75f6c87b87-qlw4h
NAME READY STATUS RESTARTS AGE
tiller-deploy-75f6c87b87-qlw4h 1/1 Running 0 17m
現在, helm version 已經能夠查看到服務器的版本信息了。
[root@k8s-master ~]# helm version
Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
Helm 安裝成功后,可執行 helm search 查看當前可安裝的 chart。
# helm search
Helm 可以像 apt 和 yum 管理軟件包一樣管理 chart。apt 和 yum 的軟件包存放在倉庫中,同樣的,Helm 也有倉庫。
[root@k8s-master ~]# helm repo list
NAME URL
stable https://kubernetes-charts.storage.googleapis.com
local http://127.0.0.1:8879/charts
[root@k8s-master ~]#
Helm 安裝時已經默認配置好了兩個倉庫:stable 和 local。stable 是官方倉庫,local 是用戶存放自己開發的 chart 的本地倉庫。
helm search 會顯示 chart 位于哪個倉庫,比如 local/cool-chart 和 stable/acs-engine-autoscaler。
用戶可以通過 helm repo add 添加更多的倉庫,比如企業的私有倉庫,倉庫的管理和維護方法請參考官網文檔 https://docs.helm.sh
與 apt 和 yum 一樣,helm 也支持關鍵字搜索:
[root@k8s-master ~]# helm search mysql
NAME CHART VERSION APP VERSION DESCRIPTION
stable/mysql 1.4.0 5.7.27 Fast, reliable, scalable, and easy to use open-source rel...
stable/mysqldump 2.6.0 2.4.1 A Helm chart to help backup MySQL databases using mysqldump
stable/prometheus-mysql-exporter 0.5.1 v0.11.0 A Helm chart for prometheus mysql exporter with cloudsqlp...
stable/percona 1.2.0 5.7.17 free, fully compatible, enhanced, open source drop-in rep...
stable/percona-xtradb-cluster 1.0.2 5.7.19 free, fully compatible, enhanced, open source drop-in rep...
stable/phpmyadmin 3.0.7 4.9.1 phpMyAdmin is an mysql administration frontend
stable/gcloud-sqlproxy 0.6.1 1.11 DEPRECATED Google Cloud SQL Proxy
stable/mariadb 6.11.1 10.3.18 Fast, reliable, scalable, and easy to use open-source rel...
包括 DESCRIPTION 在內的所有信息,只要跟關鍵字匹配,都會顯示在結果列表中。
安裝 chart 也很簡單,執行如下命令可以安裝 MySQL。
helm install stable/mysql
如果看到如下報錯,通常是因為 Tiller 服務器的權限不足。
[root@k8s-master ~]# helm install stable/mysql
Error: failed to download "stable/mysql" (hint: running `helm repo update` may help)
執行如下命名添加權限:
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"}}}}'
[root@k8s-master ~]# kubectl create serviceaccount -n kube-system tiller
serviceaccount/tiller created
[root@k8s-master ~]# kubectl create clusterrolebinding tille[root@k8s-master ~]# kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
clusterrolebinding.rbac.authorization.k8s.io/tiller-cluster-rule created
[root@k8s-master ~]# kubectl patch deploy -n kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
deployment.extensions/tiller-deploy patched
然后再次執行
[root@k8s-master ~]# helm install stable/mysql
NAME: olfactory-bird
LAST DEPLOYED: Tue Oct 15 17:36:02 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
olfactory-bird-mysql-test 1 0s
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
olfactory-bird-mysql 0/1 1 0 0s
==> v1/PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
olfactory-bird-mysql Pending 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
olfactory-bird-mysql-5cd5bc6b7-qmbj6 0/1 Pending 0 0s
==> v1/Secret
NAME TYPE DATA AGE
olfactory-bird-mysql Opaque 2 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
olfactory-bird-mysql ClusterIP 10.102.142.220 <none> 3306/TCP 0s
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
olfactory-bird-mysql.default.svc.cluster.local
To get your root password run:
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default olfactory-bird-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 olfactory-bird-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/olfactory-bird-mysql 3306
mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
輸出分為三部分:
① chart 本次部署的描述信息:
NAME 是 release 的名字,因為我們沒用 -n 參數指定,Helm 隨機生成了一個,這里是 fun-zorse。
NAMESPACE 是 release 部署的 namespace,默認是 default,也可以通過 --namespace 指定。
STATUS 為 DEPLOYED,表示已經將 chart 部署到集群。
② 當前 release 包含的資源:Service、Deployment、Secret 和 PersistentVolumeClaim,其名字都是 fun-zorse-mysql,命名的格式為 ReleasName-ChartName。
③ NOTES 部分顯示的是 release 的使用方法。比如如何訪問 Service,如何獲取數據庫密碼,以及如何連接數據庫等。
通過 kubectl get 可以查看組成 release 的各個對象:
[root@k8s-master ~]# kubectl get service olfactory-bird-mysql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
olfactory-bird-mysql ClusterIP 10.102.142.220 <none> 3306/TCP 4m14s
[root@k8s-master ~]# kubectl get deployments.
nginx-configmap olfactory-bird-mysql
[root@k8s-master ~]# kubectl get deployments. olfactory-bird-mysql
NAME READY UP-TO-DATE AVAILABLE AGE
olfactory-bird-mysql 0/1 1 0 4m29s
[root@k8s-master ~]# kubectl get pod olfactory-bird-mysql-5cd5bc6b7-qmbj6
NAME READY STATUS RESTARTS AGE
olfactory-bird-mysql-5cd5bc6b7-qmbj6 0/1 Pending 0 4m40s
[root@k8s-master ~]# kubectl get pvc olfactory-bird-mysql
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
olfactory-bird-mysql Pending 4m56s
因為我們還沒有準備 PersistentVolume,當前 release 還不可用。
helm list 顯示已經部署的 release,helm delete 可以刪除 release。
[root@k8s-master ~]# helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
olfactory-bird 1 Tue Oct 15 17:36:02 2019 DEPLOYED mysql-1.4.0 5.7.27 default
[root@k8s-master ~]#
Helm 的使用方法像極了 apt 和 yum,用 Helm 來管理 Kubernetes 應用非常方便。
chart 是 Helm 的應用打包格式。chart 由一系列文件組成,這些文件描述了 Kubernetes 部署應用時所需要的資源,比如 Service、Deployment、PersistentVolumeClaim、Secret、ConfigMap 等。
單個的 chart 可以非常簡單,只用于部署一個服務,比如 Memcached;chart 也可以很復雜,部署整個應用,比如包含 HTTP Servers、 Database、消息中間件、cache 等。
chart 將這些文件放置在預定義的目錄結構中,通常整個 chart 被打成 tar 包,而且標注上版本信息,便于 Helm 部署。
下面我們將詳細討論 chart 的目錄結構以及包含的各類文件。
以前面 MySQL chart 為例。一旦安裝了某個 chart,我們就可以在 ~/.helm/cache/archive 中找到 chart 的 tar 包。
# ls ~/.helm/cache/archive/
mysql-1.4.0.tgz
解壓后,MySQL chart 目錄結構如下:
[root@k8s-master ~]# tree mysql
mysql
├── Chart.yaml
├── README.md
├── templates
│?? ├── configurationFiles-configmap.yaml
│?? ├── deployment.yaml
│?? ├── _helpers.tpl
│?? ├── initializationFiles-configmap.yaml
│?? ├── NOTES.txt
│?? ├── pvc.yaml
│?? ├── secrets.yaml
│?? ├── servicemonitor.yaml
│?? ├── svc.yaml
│?? └── tests
│?? ├── test-configmap.yaml
│?? └── test.yaml
└── values.yaml
2 directories, 14 files
目錄名就是 chart 的名字(不帶版本信息),這里是 mysql,包含如下內容:
YAML 文件,描述 chart 的概要信息。
apiVersion: v1
appVersion: 5.7.27
description: Fast, reliable, scalable, and easy to use open-source relational database
system.
engine: gotpl
home: https://www.mysql.com/
icon: https://cache.yisu.com/upload/information/20200309/33/54090.jpg
keywords:
- mysql
- database
- sql
maintainers:
- email: o.with@sportradar.com
name: olemarkus
- email: viglesias@google.com
name: viglesiasce
name: mysql
sources:
- https://github.com/kubernetes/charts
- https://github.com/docker-library/mysql
version: 1.4.0
name 和 version 是必填項,其他都是可選。
Markdown 格式的 README 文件,相當于 chart 的使用文檔,此文件為可選。
文本文件,描述 chart 的許可信息,此文件為可選。
chart 可能依賴其他的 chart,這些依賴關系可通過 requirements.yaml 指定,比如:
在安裝過程中,依賴的 chart 也會被一起安裝。
values.yaml
chart 支持在安裝的時根據參數進行定制化配置,而 values.yaml 則提供了這些配置參數的默認值。
templates 目錄
各類 Kubernetes 資源的配置模板都放置在這里。Helm 會將 values.yaml 中的參數值注入到模板中生成標準的 YAML 配置文件。
模板是 chart 最重要的部分,也是 Helm 最強大的地方。模板增加了應用部署的靈活性,能夠適用不同的環境,我們后面會詳細討論。
templates/NOTES.txt
chart 的簡易使用文檔,chart 安裝成功后會顯示此文檔內容。
與模板一樣,可以在 NOTE.txt 中插入配置參數,Helm 會動態注入參數值。
Helm 通過模板創建 Kubernetes 能夠理解的 YAML 格式的資源配置文件,我們將通過例子來學習如何使用模板。
以 templates/secrets.yaml 為例:
{{- if not .Values.existingSecret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "mysql.fullname" . }}
namespace: {{ .Release.Namespace }}
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 }}。這些 {{ xxx }} 實際上是模板的語法。Helm 采用了 Go 語言的模板來編寫 chart。Go 模板非常強大,支持變量、對象、函數、流控制等功能。下面我們通過解析 templates/secrets.yaml 快速學習模板。
① {{ 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:
helm install stable/mysql -n my
那么:
{{ .Chart.Name }} 的值為 mysql。
{{ .Chart.Version }} 的值為 0.3.0。
{{ .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。根據二八定律,這些 chart 已經覆蓋了絕大部分情況,而且采用了最佳實踐。如何遇到不懂的函數、對象和其他語法,可參考官網文檔 https://docs.helm.sh
作為準備工作,安裝之前需要先清楚 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"
busybox:
image: "busybox"
tag: "1.29.3"
testFramework:
enabled: true
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
## Additionnal arguments that are passed to the MySQL container.
## For example use --default-authentication-plugin=mysql_native_password if older clients need to
## connect to a MySQL 8 instance.
args: []
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: {}
## Use an alternate scheduler, e.g. "stork".
## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/
##
# schedulerName:
## Security context
securityContext:
enabled: false
runAsUser: 999
fsGroup: 999
## Configure resource requests and limits
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
resources:
requests:
memory: 256Mi
cpu: 100m
# Custom mysql configuration files path
configurationFilesPath: /etc/mysql/conf.d/
# 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
flags: []
serviceMonitor:
enabled: false
additionalLabels: {}
## 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
# loadBalancerIP:
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:
# Deployment Annotations
deploymentAnnotations: {}
# To be added to the database server pod(s)
podAnnotations: {}
podLabels: {}
## Set pod priorityClassName
# priorityClassName: {}
## Init container resources defaults
initContainer:
resources:
requests:
memory: 10Mi
cpu: 10m
輸出的實際上是 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 內容為:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 8Gi
persistentVolumeReclaimPolicy: Retain
nfs:
path: /nfsdata/mysql-pv
server: 192.168.77.10
創建 PV mysql-pv:
[root@k8s-master ~]# kubectl apply -f mysql-pv.yml
persistentvolume/mysql-pv created
[root@k8s-master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mysql-pv 8Gi RWO Retain Available 5s
接下來就可以安裝 chart 了。
除了接受 values.yaml 的默認值,我們還可以定制化 chart,比如設置 mysqlRootPassword。
Helm 有兩種方式傳遞配置參數:
[root@k8s-master ~]# helm install stable/mysql --set mysqlRootPassword=abc123 -n my
NAME: my
LAST DEPLOYED: Tue Oct 15 21:52:35 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
my-mysql-test 1 0s
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
my-mysql 0/1 1 0 0s
==> v1/PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-mysql Pending 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
my-mysql-6dcc9b7d67-qh7m4 0/1 Pending 0 0s
==> v1/Secret
NAME TYPE DATA AGE
my-mysql Opaque 2 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-mysql ClusterIP 10.105.14.41 <none> 3306/TCP 0s
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
my-mysql.default.svc.cluster.local
To get your root password run:
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default my-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 my-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/my-mysql 3306
mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
mysqlRootPassword 設置為 abc123。另外,-n 設置 release 為 my,各類資源的名稱即為my-mysql。
通過 helm list 和 helm status 可以查看 chart 的最新狀態。
[root@k8s-master ~]# helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
my 1 Tue Oct 15 21:52:35 2019 DEPLOYED mysql-1.4.0 5.7.27 default
[root@k8s-master ~]# helm status my
LAST DEPLOYED: Tue Oct 15 21:52:35 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
my-mysql-test 1 10m
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
my-mysql 1/1 1 1 10m
==> v1/PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-mysql Bound mysql-pv 8Gi RWO 10m
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
my-mysql-6dcc9b7d67-qh7m4 1/1 Running 0 10m
==> v1/Secret
NAME TYPE DATA AGE
my-mysql Opaque 2 10m
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-mysql ClusterIP 10.105.14.41 <none> 3306/TCP 10m
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
my-mysql.default.svc.cluster.local
To get your root password run:
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default my-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 my-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/my-mysql 3306
mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
PVC 已經 Bound,Deployment 也 AVAILABLE。
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.
LAST DEPLOYED: Tue Oct 15 22:13:15 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
my-mysql-test 1 20m
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
my-mysql 1/1 1 1 20m
==> v1/PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-mysql Bound mysql-pv 8Gi RWO 20m
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
my-mysql-67f47db69b-tx2kt 0/1 Init:0/1 0 0s
my-mysql-6dcc9b7d67-qh7m4 1/1 Running 0 20m
==> v1/Secret
NAME TYPE DATA AGE
my-mysql Opaque 2 20m
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-mysql ClusterIP 10.105.14.41 <none> 3306/TCP 20m
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
my-mysql.default.svc.cluster.local
To get your root password run:
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default my-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 my-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/my-mysql 3306
mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
等待一些時間,升級成功。
[root@k8s-master ~]# kubectl get deployments. my-mysql -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-mysql 1/1 1 1 21m my-mysql mysql:5.7.15 app=my-mysql,release=my
helm history 可以查看 release 所有的版本。通過 helm rollback 可以回滾到任何版本。
[root@k8s-master ~]# helm history my
REVISION UPDATED STATUS CHART DESCRIPTION
1 Tue Oct 15 21:52:35 2019 SUPERSEDED mysql-1.4.0 Install complete
2 Tue Oct 15 22:13:15 2019 DEPLOYED mysql-1.4.0 Upgrade complete
[root@k8s-master ~]# helm rollback my 1
Rollback was a success.
回滾成功,MySQL 恢復到 5.7.14。
[root@k8s-master ~]# helm history my
REVISION UPDATED STATUS CHART DESCRIPTION
1 Tue Oct 15 21:52:35 2019 SUPERSEDED mysql-1.4.0 Install complete
2 Tue Oct 15 22:13:15 2019 SUPERSEDED mysql-1.4.0 Upgrade complete
3 Tue Oct 15 22:16:21 2019 DEPLOYED mysql-1.4.0 Rollback to 1
[root@k8s-master ~]# kubectl get deployments. my-mysql -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-mysql 1/1 1 1 24m my-mysql mysql:5.7.14 app=my-mysql,release=my
Kubernetes 給我們提供了大量官方 chart,不過要部署微服務應用,還是需要開發自己的 chart。
執行 helm create mychart 的命令創建 chart mychart:
[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
│?? └── tests
│?? └── test-connection.yaml
└── values.yaml
3 directories, 8 files
Helm 會幫我們創建目錄 mychart,并生成了各類 chart 文件。這樣我們就可以在此基礎上開發自己的 chart 了。
新建的 chart 默認包含一個 nginx 應用示例,values.yaml 內容如下:
# Default values for mychart.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: nginx
tag: stable
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
service:
type: ClusterIP
port: 80
ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths: []
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
開發時建議大家參考官方 chart 中的模板、values.yaml、Chart.yaml,里面包含了大量最佳實踐和最常用的函數、流控制。
只要是程序就會有 bug,chart 也不例外。Helm 提供了 debug 的工具:helm lint 和 helm install --dry-run --debug。
helm lint 會檢測 chart 的語法,報告錯誤以及給出建議。
比如我們故意在 values.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 12: could not find expected ':'
Error: 1 chart(s) linted, 1 chart(s) failed
mychart 目錄被作為參數傳遞給 helm lint。錯誤修復后則能通過檢測。
helm install --dry-run --debug 會模擬安裝 chart,并輸出每個模板生成的 YAML 內容。
[root@k8s-master ~]# helm install --dry-run mychart --debug
[debug] Created tunnel using local port: '37754'
[debug] SERVER: "127.0.0.1:37754"
[debug] Original chart version: ""
[debug] CHART PATH: /root/mychart
NAME: quieting-quetzal
REVISION: 1
RELEASED: Wed Oct 16 23:12:34 2019
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
affinity: {}
fullnameOverride: ""
image:
pullPolicy: IfNotPresent
repository: nginx
tag: stable
imagePullSecrets: []
ingress:
annotations: {}
enabled: false
hosts:
- host: chart-example.local
paths: []
tls: []
nameOverride: ""
nodeSelector: {}
replicaCount: 1
resources: {}
service:
externalPort: 80
internalPort: 80
type: ClusterIP
tolerations: []
HOOKS:
---
# quieting-quetzal-mychart-test-connection
apiVersion: v1
kind: Pod
metadata:
name: "quieting-quetzal-mychart-test-connection"
labels:
app.kubernetes.io/name: mychart
helm.sh/chart: mychart-0.1.0
app.kubernetes.io/instance: quieting-quetzal
app.kubernetes.io/version: "1.0"
app.kubernetes.io/managed-by: Tiller
annotations:
"helm.sh/hook": test-success
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['quieting-quetzal-mychart:']
restartPolicy: Never
MANIFEST:
---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: quieting-quetzal-mychart
labels:
app.kubernetes.io/name: mychart
helm.sh/chart: mychart-0.1.0
app.kubernetes.io/instance: quieting-quetzal
app.kubernetes.io/version: "1.0"
app.kubernetes.io/managed-by: Tiller
spec:
type: ClusterIP
ports:
- port:
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: mychart
app.kubernetes.io/instance: quieting-quetzal
---
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: quieting-quetzal-mychart
labels:
app.kubernetes.io/name: mychart
helm.sh/chart: mychart-0.1.0
app.kubernetes.io/instance: quieting-quetzal
app.kubernetes.io/version: "1.0"
app.kubernetes.io/managed-by: Tiller
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: mychart
app.kubernetes.io/instance: quieting-quetzal
template:
metadata:
labels:
app.kubernetes.io/name: mychart
app.kubernetes.io/instance: quieting-quetzal
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:
{}
我們可以檢視這些輸出,判斷是否與預期相符。
同樣,mychart 目錄作為參數傳遞給 helm install --dry-run --debug。
安裝 chart
當我們覺得準備就緒,就可以安裝 chart,Helm 支持四種安裝方法:
安裝倉庫中的 chart,例如:helm install stable/nginx
通過 tar 包安裝,例如:helm install ./nginx-1.2.3.tgz
通過 chart 本地目錄安裝,例如:helm install ./nginx
通過 URL 安裝,例如:helm install https://example.com/charts/nginx-1.2.3.tgz
這里我們使用本地目錄安裝:
[root@k8s-master ~]# helm install mychart
NAME: exasperated-olm
LAST DEPLOYED: Wed Oct 16 23:49:18 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
exasperated-olm-mychart 0/1 1 0 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
exasperated-olm-mychart-6845d8bb6c-mflfj 0/1 ContainerCreating 0 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
exasperated-olm-mychart ClusterIP 10.109.135.88 <none> 80/TCP 0s
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=exasperated-olm" -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上搭建倉庫。
在 k8s-node1 上啟動一個 httpd 容器。
[root@k8s-node1 ~]# mkdir /var/www
[root@k8s-node1 ~]# docker run -d -p 8080:80 -v /var/www:/usr/local/apache2/htdocs/ httpd
f571b574a59017de31b615402ae7d6886cde18907bb14c22fe82b8a68757e859
通過 helm package 將 mychart 打包。
[root@k8s-master ~]# helm package mychart
Successfully packaged chart and saved it to: /root/mychart-0.1.0.tgz
執行 helm repo index 生成倉庫的 index 文件。
[root@k8s-master ~]# mkdir myrepo
[root@k8s-master ~]# mv mychart-0.1.0.tgz myrepo
[root@k8s-master ~]# helm repo index myrepo/ --url http://192.168.77.20:8080/charts
[root@k8s-master ~]# ls myrepo/
index.yaml mychart-0.1.0.tgz
[root@k8s-master ~]#
Helm 會掃描 myrepo 目錄中的所有 tgz 包并生成 index.yaml。--url指定的是新倉庫的訪問路徑。新生成的 index.yaml 記錄了當前倉庫中所有 chart 的信息:
apiVersion: v1
entries:
mychart:
- apiVersion: v1
appVersion: "1.0"
created: "2019-10-16T23:58:54.835722169+08:00"
description: A Helm chart for Kubernetes
digest: 31c8cc4336c1afd09be0094a6bbb5d4c37abb20bbffbcc0c3e72101f6f0635b6
name: mychart
urls:
- http://192.168.77.20:8080/charts/mychart-0.1.0.tgz
version: 0.1.0
generated: "2019-10-16T23:58:54.834212265+08:00"
當前只有 mychart 這一個 chart。
將 mychart-0.1.0.tgz 和 index.yaml 上傳到 k8s-node1 的 /var/www/charts 目錄。
通過 helm repo add 將新倉庫添加到 Helm。
[root@k8s-master ~]# helm repo add newrepo http://192.168.77.20:8080/charts
"newrepo" has been added to your repositories
[root@k8s-master ~]#
[root@k8s-master ~]# helm repo list
NAME URL
stable https://kubernetes-charts.storage.googleapis.com
local http://127.0.0.1:8879/charts
newrepo http://192.168.77.20:8080/charts
倉庫命名為 newrepo,Helm 會從倉庫下載 index.yaml。
現在已經可以 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 的倉庫。
已經可以直接從新倉庫安裝 mychart 了。
[root@k8s-master ~]# helm install newrepo/mychart
NAME: ardent-pug
LAST DEPLOYED: Thu Oct 17 00:06:23 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
ardent-pug-mychart 0/1 1 0 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
ardent-pug-mychart-7858fd5f-j8mpb 0/1 ContainerCreating 0 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ardent-pug-mychart ClusterIP 10.98.167.6 <none> 80/TCP 0s
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=ardent-pug" -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。
[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.
這個操作相當于CentOS的yum update。
小結
Helm 讓我們能夠像 apt 管理 deb 包那樣安裝、部署、升級和刪除容器化應用。
Helm 由客戶端和 Tiller 服務器組成。客戶端負責管理 chart,服務器負責管理 release。chart 是 Helm 的應用打包格式,它由一組文件和目錄構成。其中最重要的是模板,模板中定義了 Kubernetes 各類資源的配置信息,Helm 在部署時通過 values.yaml 實例化模板。
Helm 允許用戶開發自己的 chart,并為用戶提供了調試工具。用戶可以搭建自己的 chart 倉庫,在團隊中共享 chart。
Helm 幫助用戶在 Kubernetes 上高效地運行和管理微服務架構應用,Helm 非常重要。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。