helm使用
什么是helm
Helm是Deis開發的一個用於Kubernetes應用的包管理工具,主要用來管理Charts。有點類似於Ubuntu中的APT或CentOS中的YUM。
Helm chart是用來封裝Kubernetes原生應用程序的YAML文件,可以在你部署應用的時候自定義應用程序的一些metadata,便與應用程序的分發。
安裝helm
Helm V2 & V3 架構設計
Helm V2到V3經歷了較大的變革,其中最大的改動就是移除了Tiller組件,所有功能都通過Helm CLI與ApiServer直接交互。Tiller在V2的架構中扮演着重要的角色,但是它與K8S的設計理念是沖突的。
-
1、圍繞 Tiller 管理應用的生命周期不利於擴展。
-
2、增加用戶的使用壁壘,服務端需要部署 Tiller 組件才可以使用,侵入性強。
-
3、K8S 的 RBAC 變得毫無用處,Tiller 擁有過大的 RBAC 權限存在安全風險。
-
4、造成多租戶場景下架構設計與實現復雜。

所以對應v3版本的helm直接安裝客戶端就好了。
關於helm版本的安裝選擇需要根據自己的k8s版本做選擇,具體的版本策略Helm版本支持策略
具體的安裝參考安裝Helm就好了
我的k8s版本是v1.19.9,所以本次我選擇的helm版本是v3.4.2
需要借助於kubectl中的Kubeconfig,來實現對遠端k8s集群的訪問操作
配置kube config
1、配置KUBECONFIG變量
$ KUBECONFIG=~/.kube/config
2、完成Kubeconfig配置后,依次執行以下命令查看並切換context以訪問本集群
$ kubectl config get-contexts
$ kubectl config use-context cls-3jju4zdc-context-default
3、執行以下命令,測試是否可正常訪問集群
$ kubectl get node
helm使用
上面helm安裝好之后,以及配置好本地的kubectl之后,我們就可以對遠端k8s集群,使用helm進行操作了
查看版本
$ helm version
version.BuildInfo{Version:"v3.4.2", GitCommit:"23dd3af5e19a02d4f4baa5b2f242645a1a3af629", GitTreeState:"clean", GoVersion:"go1.14.13"}
添加倉庫
在Helm中默認是不會添加Chart倉庫,所以這里我們需要手動添加,下面是添加一些常用的Charts庫,命令如下:
helm repo add elastic https://helm.elastic.co
helm repo add gitlab https://charts.gitlab.io
helm repo add harbor https://helm.goharbor.io
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com
helm repo add stable https://kubernetes-charts.storage.googleapis.com
# 添加國內倉庫
helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
# 執行更新命令,將倉庫中的信息進行同步:
helm repo update
# 查看倉庫信息
helm repo list
helm安裝nginx
通過Helm在Repo中查詢可安裝的Nginx包
$ helm search repo nginx
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/nginx 8.9.0 1.19.10 Chart for the nginx server
bitnami/nginx-ingress-controller 7.6.6 0.46.0 Chart for the nginx Ingress controller
stable/nginx-ingress 1.41.2 v0.34.1 An nginx Ingress controller that uses ConfigMap...
stable/nginx-ldapauth-proxy 0.1.6 1.13.5 DEPRECATED - nginx proxy with ldapauth
stable/nginx-lego 0.3.1 Chart for nginx-ingress-controller and kube-lego
bitnami/kong 3.7.3 2.4.1 Kong is a scalable, open source API layer (aka ...
創建Namespace並且部署應用
# 創建命名空間test
$ kubectl create namespace test
# 查看創建的命名空間
$ kubectl get ns
# 選擇一個chart在k8s上部署我們的應用
$ helm install nginx bitnami/nginx -n test
# 查看應用狀態
$ helm status nginx -n test
$ helm list -n test
# 查看pod的狀態
$ kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
nginx-7b9d7c59ff-69mgz 1/1 Running 0 2m39s
查看部署的結果
$ kubectl get svc -n test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx LoadBalancer xx.xxx.xxx.xx <pending> 80:31998/TCP 6m3s
訪問結果

helm的核心概念
Chart
Helm采用Chart的格式來標准化描述一個應用(K8S 資源文件集合),Chart有自身標准的目錄結構,可以將目錄打包成版本化的壓縮包進行部署。就像我們下載一個軟件包之后,就可以在電腦上直接安裝一樣,同理Chart包可以通過Helm部署到任意的K8S集群中。
Config
Config指應用配置參數,在Chart中由values.yaml和命令行參數組成。Chart采用Go Template的特性 + values.yaml對部署的模板文件進行參數渲染,也可以通過Helm Client的命令–set key=value的方式進行參數賦值。
Repository
類似於Docker Hub,Helm官方、阿里雲等社區都提供了Helm Repository,我們可以通過helm repo add導入倉庫地址,便可以檢索倉庫並選擇別人已經制作好的Chart包,開箱即用。
Release
Release代表Chart在集群中的運行實例,同一個集群的同一個Namespace下Release名稱是唯一的。Helm圍繞Release對應用提供了強大的生命周期管理能力,包括Release的查詢、安裝、更新、刪除、回滾等。
基本使用
chart的目錄
chart-demo/
├── Chart.yaml # chart原數據信息
├── charts # 應用依賴集合
├── templates # k8s資源模板集合
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml # 資源配置文件
模板管理
創建 Chart 骨架
helm create ./chart-demo
Chart 打包
helm package ./chart-demo
獲取 Chart 包元數據信息
helm inspect chart ./chart-demo
本地渲染模板文件
helm template ${chart-demo-release-name} --namespace ${namespace} ./chart-demo
查詢 Chart 依賴信息
helm dependency list ./chart-demo
檢查依賴和模板配置是否正確
$ helm lint chart-demo
==> Linting charts/chart-demo/
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
模板部署
查詢 Release 列表
helm list --namespace xxxx
Chart 安裝
helm install ${chart-demo-release-name} ./chart-demo --namespace ${namespace}
Chart 版本升級
helm upgrade ${chart-demo-release-name} ./chart-demo-new-version --namespace ${namespace}
Chart 版本回滾
helm rollback ${chart-demo-release-name} ${revision} --namespace ${namespace}
查看 Release 歷史版本
helm history ${chart-demo-release-name} --namespace ${namespace}
卸載應用
卸載應用,並保留安裝記錄
helm uninstall ${chart-demo-release-name} -n ${namespace} --keep-history
查看全部應用(包含安裝和卸載的應用)
helm list -n ${namespace} --all
卸載應用,不保留安裝記錄
helm delete ${chart-demo-release-name} -n ${namespace}
${}中的替換成自己的名字
自定義參數安裝應用
Helm中支持使用自定義yaml文件和--set命令參數對要安裝的應用進行參數配置,使用如下:
方式一:使用自定義values.yaml文件安裝應用
我們知道chart的目錄結構中有一個values.yaml,里面就是用來放參數的配置文件,修改對應的values.yaml就可以了
# 展示對應配置參數信息
$ helm show values bitnami/nginx
image:
registry: docker.io
repository: bitnami/nginx
tag: 1.19.10-debian-10-r14
...
方式二:使用--set配置參數進行安裝
--set參數是在使用helm命令時候添加的參數,可以在執行helm安裝與更新應用時使用,多個參數間用,隔開,使用如下:
注意:如果配置文件和--set同時使用,則--set設置的參數會覆蓋配置文件中的參數配置。
# 使用set創建一個release
helm install --set 'registry.registry=docker.io,registry.repository=bitnami/nginx' nginx bitnami/nginx -n blog
# 更新一個release
helm upgrade --set 'servers[0].port=8080' nginx bitnami/nginx -n blog
應用發布順序依賴
雖然Chart可以通過requirements.yaml來管理依賴關系,並按照順序下發模板資源,但是並無法控制子Chart之間的發布順序。例如服務 B 部署必須依賴服務 A 的資源全部Ready。可以通過自定義子Chart之間的依賴順序,在產品層控制每個子Chart的發布過程。
發布應用
上面我們使用helm初始化了一個charts結構,我們使用上面初始化的好的結構,把我之前打包的一個鏡像,發布到k8s環境中
鏡像liz2019/main-test:1.1.72
開始部署,為了方便查看結果,我們使用NodePort的類型部署,修改values.yaml
service:
# type: ClusterIP
# port: 80
type: NodePort
port: 80
部署
$ helm upgrade --install --force --wait --namespace test --set image.repository=liz2019/main-test --set image.tag=1.1.72 chart-demo ./chart-demo
Release "chart-demo" does not exist. Installing it now.
NAME: chart-demo
LAST DEPLOYED: Tue Jun 15 16:27:22 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 chart-demo)
export NODE_IP=$(kubectl get nodes --namespace test -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
查看下結果
可以看到已經成功部署了
遇到的問題
UPGRADE FAILED: failed to replace object: Service "chart-demo" is invalid: spec.clusterIP: Invalid value: "": field is immutable
這種嘗試設置不可變字段為空值的Chart,在Helm 2中可能正常工作,因為Helm 2僅僅比對新舊配置。只要你沒有后續設置clusterIP為非空就不會出問題。但是到了Helm 3中則肯定會出現問題。
強制更新的行為
指定--force標記時,可以在升級時,進行必要的強制更新:
-
對於Helm 2,當PATCH操作失敗時,會刪除、再重建目標資源
-
對於Helm 3,會用PUT操作來替換(replace/overwrite)目標資源
如果三方合並出現問題,有可能通過強制更新解決。對於Helm 3來說,更多情況下無濟於事,主要是K8S限制某些字段一旦創建即不可變更。
在Helm 3中,即使強制更新,你也可能遇到類似下面的錯誤:
1、ersistentVolumeClaim "ng" is invalid: spec: Forbidden: is immutable after creation except resources.requests for bound claims
2、failed to replace object: Service "ng" is invalid: spec.clusterIP: Invalid value: "": field is immutable
PUT操作解決不了不可變字段的問題,然而Helm 2刪除后再創建,則規避了不可變字段問題,但會引發其它問題:
-
PVC刪除,PV級聯刪除么?數據怎么辦
-
Service刪除,會導致暫時的服務不可用么?
參考
【YAML 模版老去?Helm Chart 或將應用分發事實標准】https://www.infoq.cn/article/dwc0ipnguogq4kbap*9g
【Helm V3使用指北】http://www.wangyapu.com/2020/04/10/helm_user_guide/
【Helm v3安裝與應用】https://blog.51cto.com/wutengfei/2569465
【基於Helm的Kubernetes資源管理】https://blog.gmem.cc/helm
