helm入門
簡介
Helm是一個由CNCF范訓和管理的專案,用于對需要在Kubernetes 上部署的復雜應用進行定義、安裝和更新,Helm以Chart的方式對應用軟體進行描述,可以方便地創建、版本化、共享和發布復雜的應用軟體,
helm3架構

helm3安裝
#github地址
#https://github.com/helm/helm
#本文示例使用的是v3.7.0版本
wget https://get.helm.sh/helm-v3.7.0-linux-amd64.tar.gz
#解壓->helm放入PATH一個路徑下
helm中三大概念
- Chart:一個Helm包,其中包含運行一個應用所需要的工具和資源定義,還可能包含Kubernetes集群中的服務定義,類似于Homebrew 中的formula、APT中的dpkg或者Yum中的RPM檔案,
- Release:在Kubernetes集群上運行的一個Chart實體,在同一個 集群上,一個Chart可以被安裝多次,例如有一個MySQL Chart,如果想在服務器上運行兩個MySQL資料庫,就可以基于這個Chart安裝兩次, 每次安裝都會生成新的Release,會有獨立的Release名稱,
- Repository:用于存放和共享Chart倉庫, 簡單來說,Helm整個系統的主要任務就是,在倉庫中查找需要的 Chart,然后將Chart以Release的形式安裝到Kubernetes集群中,
Helm Chart的使用
下面將使用一個例子展示helm chart的使用,
創建
$ helm create nginx
該命令會創建一個nginx檔案目錄,tree查看目錄結構
$ tree
.
├── charts #包含chart依賴的其他chart
├── Chart.yaml #包含了chart資訊的YAML檔案
├── templates #模板目錄, 當和values 結合時,可生成有效的Kubernetes manifest檔案
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests #測驗
│ └── test-connection.yaml
└── values.yaml #chart 默認的配置值
Chart.yaml
$ cat Chart.yaml
apiVersion: v2 #在heml3中apiVersion必須是v2
name: nginx #chart名字
description: A Helm chart for Kubernetes #chart描述
type: application #chart型別 application(默認)、library
version: 0.1.0 #chart的版本
appVersion: "1.16.0" #應用的版本
values.yaml
$ cat values.yaml
# Default values for nginx.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
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
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
templates目錄下存放了應用編排檔案,
-
(_)開頭的檔案用來存盤區域和輔助物件,供其他chart模板使用,模板命令都是嵌入在
{{和}}之間的,cat _helpers.tpl {{/* Expand the name of the chart. */}} {{- define "nginx.name" -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- end }} {{/* Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). If release name contains chart name it will be used as a full name. */}} {{- define "nginx.fullname" -}} {{- if .Values.fullnameOverride }} {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} {{- else }} {{- $name := default .Chart.Name .Values.nameOverride }} {{- if contains $name .Release.Name }} {{- .Release.Name | trunc 63 | trimSuffix "-" }} {{- else }} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} {{- end }} {{- end }} {{- end }} {{/* Create chart name and version as used by the chart label. */}} {{- define "nginx.chart" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }} {{/* Common labels */}} {{- define "nginx.labels" -}} helm.sh/chart: {{ include "nginx.chart" . }} {{ include "nginx.selectorLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end }} {{/* Selector labels */}} {{- define "nginx.selectorLabels" -}} app.kubernetes.io/name: {{ include "nginx.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} {{/* Create the name of the service account to use */}} {{- define "nginx.serviceAccountName" -}} {{- if .Values.serviceAccount.create }} {{- default (include "nginx.fullname" .) .Values.serviceAccount.name }} {{- else }} {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }} -
yaml格式的編排檔案中將某些欄位設定為“模板命令”,這些“模板命令”會在Helm部署應用時進行引數注入和模板的動態渲染,
$ cat deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "nginx.fullname" . }} labels: {{- include "nginx.labels" . | nindent 4 }} spec: {{- if not .Values.autoscaling.enabled }} replicas: {{ .Values.replicaCount }} {{- end }} selector: matchLabels: {{- include "nginx.selectorLabels" . | nindent 6 }} template: metadata: {{- with .Values.podAnnotations }} annotations: {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "nginx.selectorLabels" . | nindent 8 }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "nginx.serviceAccountName" . }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: 80 protocol: TCP livenessProbe: httpGet: path: / port: http readinessProbe: httpGet: path: / port: http resources: {{- toYaml .Values.resources | nindent 12 }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }}可是使用
helm template [NAME] [CHART] [flags]命令在本地渲染Helm Chart并列印最終的應用模板內容,values.yaml和(_)開頭的檔案中的值會被注入到yaml中,引數--set則會覆寫value.yaml檔案中的值,$ helm template nginx ./nginx --set image.repository=docker.io/library/nginx,service.type=NodePort ... ... --- # Source: nginx/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: helm.sh/chart: nginx-0.1.0 app.kubernetes.io/name: nginx app.kubernetes.io/instance: nginx app.kubernetes.io/version: "1.16.0" app.kubernetes.io/managed-by: Helm spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: nginx app.kubernetes.io/instance: nginx template: metadata: labels: app.kubernetes.io/name: nginx app.kubernetes.io/instance: nginx spec: serviceAccountName: nginx securityContext: {} containers: - name: nginx securityContext: {} image: "docker.io/library/nginx:1.16.0" imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 protocol: TCP livenessProbe: httpGet: path: / port: http readinessProbe: httpGet: path: / port: http resources: {} --- ... ... -
NOTES.txt在
helm install或helm upgrade命令的最后,Helm會列印出對用戶有用的資訊,該檔案是純文本,但會像模板一樣處理, 所有正常的模板函式和物件都是可用的,$ cat NOTES.txt 1. Get the application URL by running these commands: {{- if .Values.ingress.enabled }} {{- range $host := .Values.ingress.hosts }} {{- range .paths }} http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} {{- end }} {{- end }} {{- else if contains "NodePort" .Values.service.type }} export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "nginx.fullname" . }}) export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT {{- else if contains "LoadBalancer" .Values.service.type }} NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "nginx.fullname" . }}' export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "nginx.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") echo http://$SERVICE_IP:{{ .Values.service.port }} {{- else if contains "ClusterIP" .Values.service.type }} export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "nginx.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") echo "Visit http://127.0.0.1:8080 to use your application" kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT {{- end }}
部署
helm install [NAME] [CHART] [flags]命令安裝部署,同樣values.yaml和(_)開頭的檔案中的值會被注入到yaml中,引數--set則會覆寫value.yaml檔案中的值,
$ helm -n default install nginx ./nginx --set image.repository=docker.io/library/nginx,service.type=NodePort
NAME: nginx
LAST DEPLOYED: Sat Oct 9 16:26:50 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services nginx)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
-
查看部署的release
$ helm -n default ls NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION nginx default 1 2021-10-09 16:26:50.820014356 +0800 CST deployed nginx-0.1.0 1.16.0 -
release版本資訊存盤
默認存盤在release相應namespace下的secret(可配置configmap、sql),每一個REVISION都會生成一個secret,
$ kubectl -n default get secret -l "owner=helm" NAME TYPE DATA AGE sh.helm.release.v1.nginx.v1 helm.sh/release.v1 1 1m查看存盤內容
kubectl -n default get secret sh.helm.release.v1.nginx.v1 -ojsonpath={.data.release} |base64 -d |base64 -d |gzip -d -
測驗release是否符合預期(需等待所有部署的資源物件創建成功),原理:通過在集群中部署templates/tests/下的yaml,根據容器退出狀態判斷(exit 0:通過)是否測驗通過,測驗的yaml必須含有注解:helm.sh/hook: test,
$ helm test nginx NAME: nginx LAST DEPLOYED: Sat Oct 9 16:26:50 2021 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: nginx-test-connection Last Started: Sat Oct 9 16:47:02 2021 Last Completed: Sat Oct 9 16:47:20 2021 Phase: Succeeded NOTES: 1. Get the application URL by running these commands: export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services nginx) export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT
升級、回滾、卸載
-
helm upgrade [RELEASE] [CHART] [flags]命令進行升級,升級之前查看nginx release當前版本:REVISION=1
helm -n default ls NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION nginx default 1 2021-10-09 16:26:50.820014356 +0800 CST deployed nginx-0.1.0 1.16.0使用升級命令,將deployment中的鏡像tag升級到1.17.0,可使用
--dry-run試運行測驗是否可以升級成功,并列印升級清單,$ helm -n default upgrade nginx ./nginx/ --set image.repository=docker.io/library/nginx,service.type=NodePort,image.tag=1.17.0 Release "nginx" has been upgraded. Happy Helming! NAME: nginx LAST DEPLOYED: Sun Oct 10 13:41:17 2021 NAMESPACE: default STATUS: deployed REVISION: 2 NOTES: 1. Get the application URL by running these commands: export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services nginx) export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT再次查看nginx release當前版本:REVISION=2
$ helm -n default ls NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION nginx default 2 2021-10-10 13:41:17.486033411 +0800 CST deployed nginx-0.1.0 1.16.0 -
helm rollback <RELEASE> [REVISION] [flags]命令進行回滾,回滾之前可使用
helm history RELEASE_NAME [flags]查看nginx release歷史版本,$ helm -n default history nginx REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION 1 Sat Oct 9 16:26:50 2021 superseded nginx-0.1.0 1.16.0 Install complete 2 Sun Oct 10 13:41:17 2021 deployed nginx-0.1.0 1.16.0 Upgrade complete將nginx release回滾到REVISION=1,回滾完成后可查看deployment image tag:1.16.0,
$ helm -n default rollback nginx 1 Rollback was a success! Happy Helming! -
helm uninstall RELEASE_NAME [...] [flags]命令卸載release,卸載完成后release、release secret、k8s manifest都被洗掉,$ helm -n default uninstall nginx release "nginx" uninstalled
倉庫使用
Harbor
-
使用helm安裝harbor
$ helm repo add harbor https://helm.goharbor.io "harbor" has been added to your repositories #查看本地repo串列 $ helm repo ls NAME URL harbor https://helm.goharbor.io #查看harbor倉庫helm chart版本 $ helm search repo harbor NAME CHART VERSION APP VERSION DESCRIPTION harbor/harbor 1.7.3 2.3.3 An open source trusted cloud native registry th... #部署harbor release #persistence.enabled=false 關閉持久化存盤 #expose.type=nodePort service型別設定為nodeport方便暴露服務 #expose.tls.enabled=false 關閉tls #--create-namespace 沒有harbor命名空間,則會創建 #externalURL中的ip為本機網卡ip $ helm -n harbor install harbor harbor/harbor --set persistence.enabled=false,expose.type=nodePort,expose.tls.enabled=false,externalURL=http://10.23.18.211:30002 --create-namespace NAME: harbor LAST DEPLOYED: Mon Oct 11 18:38:47 2021 NAMESPACE: harbor STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Please wait for several minutes for Harbor deployment to complete. Then you should be able to visit the Harbor portal at http://10.23.18.211:30002 For more details, please visit https://github.com/goharbor/harbor #等待所有pod running $ kubectl -n harbor get pod NAME READY STATUS RESTARTS AGE harbor-chartmuseum-6c9f9c84f8-ztpgp 1/1 Running 0 3m20s harbor-core-c6dc8c895-vn5kx 1/1 Running 0 3m19s harbor-database-0 1/1 Running 0 3m20s harbor-jobservice-6c4d647bcb-nd64t 1/1 Running 0 3m20s harbor-nginx-7bc597c58b-67x6x 1/1 Running 0 3m19s harbor-notary-server-5f598b9555-4qjpm 1/1 Running 0 3m20s harbor-notary-signer-65b84d688d-g92tv 1/1 Running 0 3m19s harbor-portal-945d945f-ks6tx 1/1 Running 0 3m20s harbor-redis-0 1/1 Running 0 3m20s harbor-registry-6d976587dc-dbrnt 2/2 Running 0 3m20s harbor-trivy-0 1/1 Running 0 3m20s瀏覽器訪問http://10.23.18.211:30002即可訪問harbor頁面,admin/Harbor12345為默認用戶密碼,
-
推送nginx chart到倉庫
登錄harbor頁面,專案–>新建專案,創建一個名為helm的helm chart倉庫,
添加helm倉庫,
$ helm repo add my-harbor http://10.23.18.211:30002/chartrepo/helm --username=admin --password=Harbor12345 "my-harbor" has been added to your repositories #查看當前repo $ helm repo ls NAME URL harbor https://helm.goharbor.io my-harbor http://10.23.18.211:30002/chartrepo/helm由于原生helm沒有推送命令,所以需要安裝一個推送插件,
$ helm plugin install https://github.com/chartmuseum/helm-push.git Downloading and installing helm-push v0.10.0 ... https://github.com/chartmuseum/helm-push/releases/download/v0.10.0/helm-push_0.10.0_linux_amd64.tar.gz Installed plugin: cm-push #查看已安裝的插件 $ helm plugin ls NAME VERSION DESCRIPTION cm-push 0.10.0 Push chart package to ChartMuseum(備選方案)如果服務器不能訪問外網,可以從能夠訪問外網的機器clone插件代碼和插件壓縮包,然后放到此服務器上,
#在能夠訪問外網的機器上 $ git clone https://github.com/chartmuseum/helm-push.git $curl https://github.com/chartmuseum/helm-push/releases/download/v0.10.0/helm-push_0.10.0_linux_amd64.tar.gz #將插件代碼上傳到服務器/root/.cache/helm/plugins目錄下,創建release目錄 $ mkdiir /root/.cache/helm/plugins/helm-push/release #將插件壓縮包上傳到服務器/root/.cache/helm/plugins/helm-push/releases下 $ cd /root/.cache/helm/plugins #vim 編輯helm-push/scripts/install_plugin.sh,根據需要注釋掉 `# Download with curl if possible.`下邊代碼,以注釋掉curl為例: $ vim helm-push/scripts/install_plugin.sh $ cat helm-push/scripts/install_plugin.sh ... ... # Download with curl if possible. if [ -x "$(which curl 2>/dev/null)" ]; then # curl -sSL "${url}" -o "releases/v${version}.tar.gz" echo "jump curl" else wget -q "${url}" -O "releases/v${version}.tar.gz" fi ... ... #安裝推送插件 $ helm plugin install ./helm-push/ Downloading and installing helm-push v0.10.0 ... https://github.com/chartmuseum/helm-push/releases/download/v0.10.0/helm-push_0.10.0_linux_amd64.tar.gz jump curl Installed plugin: cm-push [root@master01 plugins]# helm plugin ls NAME VERSION DESCRIPTION cm-push 0.10.0 Push chart package to ChartMuseum推送nginx chart,
#cd到nginx目錄,推送 $ helm cm-push ./nginx my-harbor Pushing nginx-0.1.0.tgz to my-harbor... Done. #更新本地快取的my-harbor倉庫資訊,可以確認nginx chart上傳到harbor上,也可以在harbor頁面上確認 $ helm repo update my-harbor Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "my-harbor" chart repository Update Complete. ?Happy Helming!? $ helm search repo my-harbor NAME CHART VERSION APP VERSION DESCRIPTION my-harbor/nginx 0.1.0 1.16.0 A Helm chart for Kubernetes -
拉取、部署倉庫中的chart
helm pull [chart URL | repo/chartname] [...] [flags]拉取倉庫中chart,pull只會拉取到本地當前目錄下的.tgz壓縮包,可使用tar xzvf xxx.tgz解壓,#更新本地helm repo 快取 $ helm repo update #pull拉取nginx chart $ helm pull my-harbor/nginxhelm install [NAME] [CHART] [flags]部署倉庫中的chart,和上邊部署篇幅類似,把使用本地檔案改成使用倉庫中的chart即可,$ helm -n test install nginx my-harbor/nginx --set image.repository=docker.io/library/nginx,service.type=NodePort --create-namespace NAME: nginx LAST DEPLOYED: Mon Oct 11 19:47:36 2021 NAMESPACE: test STATUS: deployed REVISION: 1 NOTES: 1. Get the application URL by running these commands: export NODE_PORT=$(kubectl get --namespace test -o jsonpath="{.spec.ports[0].nodePort}" services nginx) export NODE_IP=$(kubectl get nodes --namespace test -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/337662.html
標籤:其他
