在Kubernetes中部署应用程序,需要创建Pod、Deployment和Service等资源,并且创建的步骤也是比较繁琐的。当遇到复杂系统时,Kubernetes的应用部署和管理就变得相当的复杂。好在可以使用Helm来管理Kubernetes,它可以很大程度上简化Kubernetes应用的部署和管理。视频讲解如下:
一、 什么是Helm?
Helm通过打包的方式动态创建Kubernetes应用的配置信息,然后生成应用程序的YAML清单文件,并最终由kubectl进行调用完成应用的部署。因此从使用方式上看,Helm类似于Linux YUM的包管理。下面展示了Helm的体系架构。
从Helm 3开始,Helm将所有的配置信息存储在Kubernetes集群的配置中。Helm中有三个非常重要的概念,它们分别是:Chart、Repository和Release。
- Chart:应用程序信息的集合,包括了应用程序中对Kubernetes资源的定义和依赖关系的说明等。
- Repository:存放Chart的仓库。
- Release:Chart的运行的实例,代表一个正在运行的应用。当Chart在Kubernetes集群中部署成功后,就会生成一个Release。
二、 部署Helm
在GitHub上提供了Helm多种操作系统的二进制版本,下面的步骤将在master节点上安装和部署Helm。这里使用的是helm-v3.5.4-linux-amd64.tar.gz。
(1)解压Helm安装包,并将helm的可执行命令复制到目录”/usr/bin/“目录下。
tar -zxvf helm-v3.5.4-linux-amd64.tar.gz cd linux-amd64/ mv helm /usr/bin/
(2)添加Helm的Repository仓库。
#添加Helm官方的Repository仓库 helm repo add stable https://charts.helm.sh/stable # 提示:这里可以添加多个Repository仓库地址,例如: helm repo add azure http://mirror.azure.cn/kubernetes/charts/ helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
(3)查看Repository仓库信息。
helm repo list # 输出的信息如下: NAME URL stable https://charts.helm.sh/stable azure http://mirror.azure.cn/kubernetes/charts/ aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
(4)Helm仓库的其他操作。
#更新仓库 helm repo update #删除仓库 helm repo remove aliyun
(5)查看Helm的配置信息。
helm env # 输出的信息如下: HELM_BIN="helm" HELM_CACHE_HOME="/root/.cache/helm" HELM_CONFIG_HOME="/root/.config/helm" HELM_DATA_HOME="/root/.local/share/helm" HELM_DEBUG="false" HELM_KUBEAPISERVER="" HELM_KUBEASGROUPS="" HELM_KUBEASUSER="" HELM_KUBECAFILE="" HELM_KUBECONTEXT="" HELM_KUBETOKEN="" HELM_MAX_HISTORY="10" HELM_NAMESPACE="kubernetes-plugin" HELM_PLUGINS="/root/.local/share/helm/plugins" HELM_REGISTRY_CONFIG="/root/.config/helm/registry.json" HELM_REPOSITORY_CACHE="/root/.cache/helm/repository" HELM_REPOSITORY_CONFIG="/root/.config/helm/repositories.yaml"
(6)在Repository仓库中搜索可用的Charts,搜索的结果如下图所示。
helm search repo # 提示:默认情况下会搜索所有添加的Helm Repository仓库,也可以指定搜索某一个Repository仓库。 # 例如:下面的搜索命令只会搜索aliyun的Repository仓库。 helm search repo aliyun
三、 使用Helm管理Kubernetes
要通过使用Helm管理Kubernetes,很重要的一步就是就是设置Helm管理的Kubernetes的环境变量。执行下面的命令:
export KUBECONFIG=/root/.kube/config # 提示:这一步非常重要,在文件“/root/.kube/config”文件中保存了Kubernetes集群的信息,该信息可以保证Helm与Kubernetes进行通信。为了方便可以将这一步写到"/etc/profile”里。
3.1 【实战】使用Helm部署应用
这里将使用Helm在Kubernetes中部署一个MySQL数据库的服务。下面是具体的演示步骤。
(1)在Repository仓库中搜索可用的MySQL Charts,搜索的结果如下图所示。
helm search repo mysql
(2)部署一个MySQL数据库的应用,执行命令:
helm install mysql-demo stable/mysql # 输出的信息如下: NAME: mysql-demo LAST DEPLOYED: Thu Feb 10 06:33:49 2022 NAMESPACE: kubernetes-plugin STATUS: deployed REVISION: 1 NOTES: MySQL can be accessed via port 3306 on the following DNS name from within your cluster: mysql-demo.kubernetes-plugin.svc.cluster.local ... ... ... ... # 提示:使用helm install命令至少需要两个参数:Release的名称和Charts名称。 # 以这里的命令为例:“mysql-demo”是Release的名称,而“stable/mysql”是Charts的名称。 # 另外可以使用“helm list”和“helm status mysql-demo”命令查询Release的状态信息。
(3)查看部署的Pod、Deployment和Service信息,如下图所示。
kubectl get all # 提示:这时候会发现Pod的状态一直是“Pending”的状态。
(4)查看Pod的详细信息。
kubectl describe pod/mysql-demo-5d85fc7bd7-cwpk4 # 输出的信息如下: Events: ... ... Message ... ... ------- ... ... pod has unbound immediate PersistentVolumeClaims # 提示:从Message信息中可以看到Pod缺少PVC资源。
(5)查看PVC的资源。
kubectl get pvc # 输出的信息如下: NAME STATUS VOLUME CAPACITY mysql-demo Pending
(6)查看Charts的详细信息。
helm show all stable/mysql # 通过查看输出的信息,可以确定这里需要一个8G的PV资源。 ... ... ## 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: {} ... ...
(7)创建MySQL的数据存储目录。
mkdir -p /mnt/mysql/data
(8)创建文件“mysql-pv-volume.yaml”并输入下面的内容:
kind: PersistentVolume apiVersion: v1 metadata: name: pv-volume-mysql namespace: kubernetes-plugin labels: type: local spec: capacity: storage: 8Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/mysql/data"
(9)创建PV资源。
kubectl apply -f mysql-pv-volume.yaml
(10)查看PV和PVC的资源。
kubectl get pv,pvc # 输出的信息如下: NAME CAPACITY ACCESS MODES persistentvolume/pv-volume-mysql 8Gi RWO NAME STATUS VOLUME persistentvolumeclaim/mysql-demo Bound pv-volume-mysql # 提示:这时候PVC已经与PV成功绑定。
(11)再次查看部署的Pod、Deployment和Service信息,如下图所示。
kubectl get all
(12)卸载部署的MySQL应用。
helm uninstall mysql-demo
3.2 【实战】使用Helm创建自己的Charts
用户可以使用Helm提供的Charts模板创建自己应用程序的Charts。这里将使用Helm创建一个自己的Nginx Charts,并部署到Kubernetes集群中。下面是具体的步骤:
(1)生成Nginx Charts的模板。
helm create my-nginx
(2)查看生成的Charts模板。
tree my-nginx/ # 输出的信息如下: my-nginx/ Charts包目录的名称 ├── charts 依赖的子包目录,里面可以包含多个依赖的chart包 ├── Chart.yaml Charts的描述信息,如:Charts的名称、版本信息等。 ├── templates Kubernetes应用程序的配置模版目录 │ ├── deployment.yaml Deployment的部署描述文件 │ ├── _helpers.tpl 公有库定义文件 │ ├── hpa.yaml │ ├── ingress.yaml Ingress的部署描述文件 │ ├── NOTES.txt │ ├── serviceaccount.yaml ServiceAccount的部署描述文件 │ ├── service.yaml Service的部署描述文件 │ └── tests │ └── test-connection.yaml └── values.yaml # 提示:用户可以基于这里生成的模板编辑其中的YAML文件完成相应配置即可,重点是编辑Deployment、Service和Ingress的描述文件。
(3)下面是一个最简单的Charts模板,这里只保留的必要的文件。
my-nginx/ ├── Chart.yaml ├── templates │ ├── deployment.yaml │ └── service.yaml └── values.yaml
(3)编辑文件“values.yaml”,输入下面的内容:
deployname: my-nginx replicaCount: 2 image: repository: nginx pullPolicy: IfNotPresent # 提示:这里定义了Deployment的名称,副本数以及镜像的相关信息。
(4)编辑文件“deployment.yaml”,输入下面的内容:
apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Values.deployname }} labels: app: my-nginx spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: my-nginx template: metadata: labels: app: my-nginx spec: containers: - name: my-nginx image: {{ .Values.images.repository }} imagePullPolicy: {{ .Values.images.pullPolicy }} ports: - containerPort: 80 # 提示:在文件“deployment.yaml”中引用了文件“values.yaml”中定义的变量值。
(5)编辑文件“service.yaml”,输入下面的内容:
apiVersion: v1 kind: Service metadata: name: my-nginx spec: type: NodePort ports: - name: http port: 80 protocol: TCP targetPort: 80 selector: app: my-nginx # 提示:文件“service.yaml”也可以使用文件“values.yaml”中定义的变量值。
(6)验证Charts中的各个文件格式是否正确,执行命令:
helm lint my-nginx/ # 输出的信息如下: ==> Linting my-nginx/ [INFO] Chart.yaml: icon is recommended 1 chart(s) linted, 0 chart(s) failed
(7)打包应用程序。
helm package my-nginx/ # 输出的信息如下: Successfully packaged chart and saved it to: /root/my-nginx-0.1.0.tgz
(8)试运行应用程序。
helm install --dry-run my-nginx my-nginx-0.1.0.tgz # 输出的信息如下: NAME: my-nginx LAST DEPLOYED: Thu Feb 10 08:10:16 2022 NAMESPACE: kubernetes-plugin STATUS: pending-install REVISION: 1 TEST SUITE: None HOOKS: MANIFEST: --- # Source: my-nginx/templates/service.yaml apiVersion: v1 kind: Service metadata: name: my-nginx spec: type: NodePort ports: - name: http port: 80 protocol: TCP targetPort: 80 selector: app: my-nginx --- # Source: my-nginx/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx labels: app: my-nginx spec: replicas: 2 selector: matchLabels: app: my-nginx template: metadata: labels: app: my-nginx spec: containers: - name: my-nginx image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80
(9)在Kubernetes集群中部署应用程序。
helm install my-nginx my-nginx-0.1.0.tgz
(10)查看创建的资源信息,如下图所示。
kubectl get all