helm基础

一、helm介绍

Helm 可以帮助我们管理 Kubernetes 应用程序 - Helm Charts 可以定义、安装和升级复杂的 Kubernetes 应用程序,Charts 包很容易创建、版本管理、分享和分布。Helm 对于 Kubernetes 来说就相当于 centos中的yum ,可以减少复杂的Kubernetes 应用程序的维护成本,接下来讲解一下 Helm 的使用方法。

二、helm安装

首先需要一个可用的 Kubernetes 集群,因为 Helm 是读取 kubeconfig 文件来访问集群的。

由于 Helm V2 版本要在 Kubernetes 集群中安装一个 Tiller 服务进行通信,这样大大降低了其安全性和可用性,在 V3 版本中移除了服务端,采用了通用的 Kubernetes CRD 资源来进行管理,这样就只需要连接上 Kubernetes 即可,而且 V3 版本已经发布了稳定版,可以在此链接中选择版本下载:https://github.com/helm/helm/releases,本环境中使用的版本是3.9.0

[root@node1 ~]# helm version
version.BuildInfo{Version:"v3.9.0", GitCommit:"7ceeda6c585217a19a1131663d8cd1f7d641b2a7", GitTreeState:"clean", GoVersion:"go1.17.5"}
[root@node1 ~]# 

helm客户端安装成功之后,就需要配置一个chart仓库了,类似我们的yum源,由于没有本地的helm chart仓库,此处就使用微软的 charts 仓库代替:

[root@node1 ~]# helm repo add stable http://mirror.azure.cn/kubernetes/charts/
[root@node1 ~]# 
[root@node1 ~]# helm repo list
NAME  	URL                                      
stable	http://mirror.azure.cn/kubernetes/charts/
[root@node1 ~]# 
[root@node1 ~]# 

更新chart信息到本地,去人使用的是最新的chart仓库,类似yum update

[root@node1 ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
[root@node1 ~]# 

三、安装应用

首先我们通过search命令查看下可用的chart信息

[root@node1 ~]# helm search repo stable
NAME                                 	CHART VERSION	APP VERSION            	DESCRIPTION                                       
stable/acs-engine-autoscaler         	2.2.2        	2.1.1                  	DEPRECATED Scales worker nodes within agent pools 
stable/aerospike                     	0.3.5        	v4.5.0.5               	DEPRECATED A Helm chart for Aerospike in Kubern...
stable/airflow                       	7.13.3       	1.10.12                	DEPRECATED - please use: https://github.com/air...
stable/ambassador                    	5.3.2        	0.86.1                 	              	
####内容太多,只展示部分

接下来安装一个mysql的应用,如下:

[root@node1 ~]# helm install mysql stable/mysql 
WARNING: This chart is deprecated
NAME: mysql
LAST DEPLOYED: Thu Jul 27 15:09:59 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql.default.svc.cluster.local

我们可以看到 stable/mysql 这个 chart 已经安装成功,我们将安装成功的这个应用叫做一个 release,在安装的时候指定了release的名称,如果想要随机生成的话,可以使用--generate-name 参数,这样生成的 release 名称是随机生成的,名为 mysql-xxxxxxxx,如下:

root@node1 ~]# helm install stable/mysql  --generate-name
WARNING: This chart is deprecated
NAME: mysql-1690442034      ######生成的名字为mysql-1690442034
LAST DEPLOYED: Thu Jul 27 15:13:57 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql-1690442034.default.svc.cluster.local

查看release安装状态

[root@node1 ~]# helm list 
NAME            	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART      	APP VERSION
mysql-1690442034	default  	1       	2023-07-27 15:13:57.307585051 +0800 CST	deployed	mysql-1.6.9	5.7.30     
[root@node1 ~]#
####helm状态为deployed,说明已经部署成功

[root@node1 ~]# kubectl get po 
NAME                                      READY   STATUS    RESTARTS      AGE
mysql-1690442034-6bc58c56c9-zxgxg         0/1     Pending   0             2m21s

删除helm,如下:

[root@node1 ~]# helm list 
NAME            	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART      	APP VERSION
mysql-1690442034	default  	1       	2023-07-27 15:13:57.307585051 +0800 CST	deployed	mysql-1.6.9	5.7.30     
[root@node1 ~]# helm uninstall mysql-1690442034
release "mysql-1690442034" uninstalled
[root@node1 ~]# 
[root@node1 ~]# helm list 
NAME	NAMESPACE	REVISION	UPDATED	STATUS	CHART	APP VERSION
[root@node1 ~]# 
#####
###########
确认是否被完全删除
[root@node1 ~]# kubectl get all -l release=mysql-1690442034
No resources found in default namespace.
[root@node1 ~]# 
每一个release部署成功时,helm所部署的资源都会被打上一个标签,release=release_name

另外删除release时使用 --keep-history 参数,则会保留 release 的历史记录,可以获取该 release 的状态就是 uninstalled,而不是找不到 release了,如下:

[root@node1 ~]# helm uninstall mysql-1690442716 --keep-history
release "mysql-1690442716" uninstalled
[root@node1 ~]#    
[root@node1 ~]# helm list -a
NAME            	NAMESPACE	REVISION	UPDATED                                	STATUS     	CHART      	APP VERSION
mysql-1690442716	default  	1       	2023-07-27 15:25:19.566544004 +0800 CST	uninstalled	mysql-1.6.9	5.7.30 

要想恢复被删除的release,可以使用rollback,如下:

[root@node1 ~]# helm list -a
NAME            	NAMESPACE	REVISION	UPDATED                                	STATUS     	CHART      	APP VERSION
mysql-1690442716	default  	1       	2023-07-27 15:25:19.566544004 +0800 CST	uninstalled	mysql-1.6.9	5.7.30     
[root@node1 ~]# helm rollback mysql-1690442716 1   ###恢复时加上REVISION版本
Rollback was a success! Happy Helming!
[root@node1 ~]# helm list 
NAME            	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART      	APP VERSION
mysql-1690442716	default  	2       	2023-07-27 15:30:15.395892875 +0800 CST	deployed	mysql-1.6.9	5.7.30     

四、定制chart

上面的操作都是直接使用的 helm install 命令安装的 chart 包,这种情况下使用的 是chart 的默认配置,在实际场景下需要我们自己根据要求来定制我们自己的 chart 包

1、首先查看stable/mysql的信息,获取默认的配置项
[root@node1 ~]# helm show values stable/mysql  > values.yaml
## mysql image version
## ref: https://hub.docker.com/r/library/mysql/tags/
##
image: "mysql"
imageTag: "5.7.30"

strategy:
  type: Recreate

busybox:
  image: "busybox"
  tag: "1.32"

testFramework:
  enabled: true
  image: "bats/bats"
  tag: "1.2.1"
....................
....................

2、根据实际情况修改values.yaml文件
[root@node1 ~]# cat values.yaml | grep -Ev '^#|^$'
image: "mysql"
imageTag: "5.7.30"
strategy:
  type: Recreate
busybox:
  image: "busybox"
  tag: "1.32"
testFramework:
  enabled: true
  image: "bats/bats"
  tag: "1.2.1"
  imagePullPolicy: IfNotPresent
  securityContext: {}
imagePullPolicy: IfNotPresent
args: []
extraVolumes: |
  # - name: extras
  #   emptyDir: {}
extraVolumeMounts: |
  # - name: extras
  #   mountPath: /usr/share/extras
  #   readOnly: true
extraInitContainers: |
  # - name: do-something
  #   image: busybox
  #   command: ['do', 'something']
  # - name: myRegistryKeySecretName
nodeSelector: {}
affinity: {}
tolerations: []
livenessProbe:
  initialDelaySeconds: 30
  periodSeconds: 10
  timeoutSeconds: 5
  successThreshold: 1
  failureThreshold: 3
readinessProbe:
  initialDelaySeconds: 5
  periodSeconds: 10
  timeoutSeconds: 1
  successThreshold: 1
  failureThreshold: 3
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: nfs            #####修成我们环境实际的sc名称
  accessMode: ReadWriteOnce
  size: 8Gi
  annotations: {}
securityContext:
  enabled: false
  runAsUser: 999
  fsGroup: 999
resources:
  requests:
    memory: 256Mi
    cpu: 100m
configurationFilesPath: /etc/mysql/conf.d/
configurationFiles: {}
initializationFiles: {}
mysqlx:
  port:
    enabled: false
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: {}
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:
serviceAccount:
  ## Specifies whether a ServiceAccount should be created
  ##
  create: false
  ## The name of the ServiceAccount to use.
  ## If not set and create is true, a name is generated using the mariadb.fullname template
  # name:
ssl:
  enabled: false
  secret: mysql-ssl-certs
  certificates:
deploymentAnnotations: {}
podAnnotations: {}
podLabels: {}
initContainer:
  resources:
    requests:
      memory: 10Mi
      cpu: 10m
[root@node1 ~]# 

使用修改完的配置重新安装release

[root@node1 ~]# helm install -f mysql-values.yaml mysql stable/mysql
WARNING: This chart is deprecated
NAME: mysql
LAST DEPLOYED: Thu Jul 27 15:44:25 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql.default.svc.cluster.local

#####查看已经安装好的资源
[root@node1 ~]# helm list 
NAME 	NAMESPACE	REVISION	UPDATED                               	STATUS  	CHART      	APP VERSION
mysql	default  	1       	2023-07-27 15:44:25.43518257 +0800 CST	deployed	mysql-1.6.9	5.7.30     
[root@node1 ~]# kubectl get all -l release=mysql
NAME                         READY   STATUS    RESTARTS   AGE
pod/mysql-7cf789c785-qrqtf   1/1     Running   0          43s   ###pod已经running

NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/mysql   ClusterIP   10.233.51.21   <none>        3306/TCP   43s

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mysql   1/1     1            1           43s

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/mysql-7cf789c785   1         1         1       43s
[root@node1 ~]# 

查看release目前生效的values值

[root@node1 ~]# helm get values mysql
USER-SUPPLIED VALUES:
affinity: {}
args: []
busybox:
  image: busybox
  tag: "1.32"
configurationFiles: {}
configurationFilesPath: /etc/mysql/conf.d/
deploymentAnnotations: {}
extraInitContainers: |
  # - name: do-something
  #   image: busybox
  #   command: ['do', 'something']
extraVolumeMounts: |
  # - name: extras
  #   mountPath: /usr/share/extras
  #   readOnly: true
extraVolumes: |
  # - name: extras
  #   emptyDir: {}
image: mysql
imagePullPolicy: IfNotPresent
imageTag: 5.7.30
initContainer:
  resources:
    requests:
      cpu: 10m
      memory: 10Mi
initializationFiles: {}
livenessProbe:
  failureThreshold: 3
  initialDelaySeconds: 30
  periodSeconds: 10
  successThreshold: 1
  timeoutSeconds: 5
metrics:
  annotations: {}
  enabled: false
  flags: []
  image: prom/mysqld-exporter
  imagePullPolicy: IfNotPresent
  imageTag: v0.10.0
  livenessProbe:
    initialDelaySeconds: 15
    timeoutSeconds: 5
  readinessProbe:
    initialDelaySeconds: 5
    timeoutSeconds: 1
  resources: {}
  serviceMonitor:
    additionalLabels: {}
    enabled: false
mysqlx:
  port:
    enabled: false
nodeSelector: {}
persistence:
  accessMode: ReadWriteOnce
  annotations: {}
  enabled: true
  size: 8Gi
  storageClass: nfs
podAnnotations: {}
podLabels: {}
readinessProbe:
  failureThreshold: 3
  initialDelaySeconds: 5
  periodSeconds: 10
  successThreshold: 1
  timeoutSeconds: 1
resources:
  requests:
    cpu: 100m
    memory: 256Mi
securityContext:
  enabled: false
  fsGroup: 999
  runAsUser: 999
service:
  annotations: {}
  port: 3306
  type: ClusterIP
serviceAccount:
  create: false
ssl:
  certificates: null
  enabled: false
  secret: mysql-ssl-certs
strategy:
  type: Recreate
testFramework:
  enabled: true
  image: bats/bats
  imagePullPolicy: IfNotPresent
  securityContext: {}
  tag: 1.2.1
tolerations: []
[root@node1 ~]# 

五、升级回滚

  • 升级
    在实际环境中,可能会面临着业务的版本升级,可以使用 helm upgrade 命令来操作。Helm 会尝试以最小的侵入性进行升级,它只会更新自上一版本以来发生的变化:

    ###为了有升级效果,我们修改下values.yaml文件中,pod的探针,如下:
    livenessProbe:
    initialDelaySeconds: 60
    periodSeconds: 20
    timeoutSeconds: 1
    successThreshold: 1
    failureThreshold: 30

    readinessProbe:
    initialDelaySeconds: 50
    periodSeconds: 20
    timeoutSeconds: 1
    successThreshold: 1
    failureThreshold: 30

    ###升级release
    [root@node1 ~]# helm upgrade -f mysql-values.yaml mysql stable/mysql
    WARNING: This chart is deprecated
    Release "mysql" has been upgraded. Happy Helming!
    NAME: mysql
    LAST DEPLOYED: Thu Jul 27 15:58:38 2023
    NAMESPACE: default
    STATUS: deployed
    REVISION: 3
    NOTES:
    MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
    mysql.default.svc.cluster.local

    ###查看升级后的结果
    [root@node1 ~]# helm list -a
    NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
    mysql default 2 2023-07-27 15:58:38.796980792 +0800 CST deployed mysql-1.6.9 5.7.30

    [root@node1 ~]# kubectl get all -l release=mysql
    NAME READY STATUS RESTARTS AGE
    pod/mysql-f6cf967bb-nrf4v 1/1 Running 0 4m28s

    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    service/mysql ClusterIP 10.233.51.21 <none> 3306/TCP 18m

    NAME READY UP-TO-DATE AVAILABLE AGE
    deployment.apps/mysql 1/1 1 1 18m

    NAME DESIRED CURRENT READY AGE
    replicaset.apps/mysql-7cf789c785 0 0 0 18m
    replicaset.apps/mysql-f6cf967bb 1 1 1 4m28s

    ###查看mysql这个release的历史记录
    [root@node1 ~]# helm history mysql
    REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
    1 Thu Jul 27 15:44:25 2023 superseded mysql-1.6.9 5.7.30 Install complete
    2 Thu Jul 27 15:58:38 2023 deployed mysql-1.6.9 5.7.30 Upgrade complete

    ###查看升级后的探针values值是否修改成功
    [root@node1 ~]# helm get values mysql
    USER-SUPPLIED VALUES:
    affinity: {}
    args: []
    busybox:
    image: busybox
    tag: "1.32"
    ...........
    ..............
    livenessProbe:
    failureThreshold: 30
    initialDelaySeconds: 60
    periodSeconds: 20
    successThreshold: 1
    timeoutSeconds: 1
    readinessProbe:
    failureThreshold: 30
    initialDelaySeconds: 50
    periodSeconds: 20
    successThreshold: 1
    timeoutSeconds: 1

  • 回滚

    ###当我们版本升级失败时,这时候需要回滚到上一次的版本,每次进行安装、升级或回滚时,修订号都会加 1,第一个修订号始终为1
    通过上面的helm history mysql可以看到升级后的REVISION为2,回滚到REVISION为的1状态
    [root@node1 ~]# helm rollback mysql 1
    Rollback was a success! Happy Helming!
    [root@node1 ~]# helm list
    NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
    mysql default 3 2023-07-27 16:09:20.74561689 +0800 CST deployed mysql-1.6.9 5.7.30

    ###可以看到这次回滚之后,REVISION的值变为3
    [root@node1 ~]# helm history mysql
    REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
    1 Thu Jul 27 15:44:25 2023 superseded mysql-1.6.9 5.7.30 Install complete
    2 Thu Jul 27 15:58:38 2023 superseded mysql-1.6.9 5.7.30 Upgrade complete
    3 Thu Jul 27 16:09:20 2023 deployed mysql-1.6.9 5.7.30 Rollback to 1
    ###可以看到Rollback to 1 已经回滚成功

六、总结

在我们进行上述的安装、升级、回滚等动作时,还可以进行一些参数的添加

  • --timeout: 等待 Kubernetes 命令完成的时间,默认是 300(5分钟)
  • --wait: 等待直到所有 Pod 都处于就绪状态、PVC 已经绑定、Deployment具有处于就绪状态的最小 Pods 数量(期望值减去 maxUnavailable)以及 Service 有一个 IP 地址,然后才标记 release 为成功状态。它将等待与 --timeout 值一样长的时间,如果达到超时,则 release 将标记为失败。注意:在 Deployment 将副本设置为 1 并且作为滚动更新策略的一部分,maxUnavailable 未设置为0的情况下,--wait 将返回就绪状态,因为它已满足就绪状态下的最小 Pod 数量
  • --recreate-pods: 仅适用于 upgrade 和 rollback,这个标志将导致重新创建所有的 Pods。
相关推荐
橙子家14 小时前
关于 K8s 的一些基础概念整理-补充【k8s系列之五】
k8s
于顾而言2 天前
【Enjoy Kubernetes】1. 基础入门
开发语言·云原生·k8s
roshy3 天前
POD 存储、PV、PVC
docker·k8s·pod
qq_338032923 天前
k8s总结
云原生·容器·kubernetes·k8s
KubeSphere 云原生3 天前
云原生周刊:Kubernetes v1.32 正式发布
云计算·k8s·容器平台·kubesphere
TiDB_PingCAP4 天前
知乎 PB 级别 TiDB 数据库集群管控实践
k8s·tidb·tidb operator
KubeSphere 云原生4 天前
拒绝 Helm? 如何在 K8s 上部署 KRaft 模式 Kafka 集群?
云计算·k8s·容器平台·kubesphere
年薪丰厚4 天前
如何查看K8S集群中service和pod定义的网段范围
docker·云原生·容器·kubernetes·k8s
麻辣翅尖8 天前
【解决】k8s使用flannel网络插件的问题整理
kubernetes·k8s·报错
kainx9 天前
AWS EKS 相关错误修复 - remote error: tls: internal error - CSR pending
kubernetes·云计算·k8s·aws·eks·csr