在上一篇博文
kubernetes快速学习(七):用配置文件创建部署和服务_omage的专栏-CSDN博客
我们学习了如何用配置文件创建部署和服务,那本篇我将带大家了解如何部署一个单实例的有状态的应用,有状态的应用一般指需要存储数据的应用,这里就涉及到如何在kubernetes里去配置存储。
关于kubernetes的存储我反复看了很多次,概念和内容比较多,详细见这个链接
我们了解Docker的都知道,docker就是通过volume这个概念去绑定宿主机的某个磁盘路径,理解起来很简单,但是对于kubernetes而言,它是集群的管理工具,Pods的运行是跨节点的,如何让不同节点的Pods能够访问不同类型的存储,包括本地的、网络的、云服务的,这里就需要有各种各样的适配和参数,要一下子把kubernetes的存储全部理解对于新手来讲还是蛮难的。
这里我们就用minikube学习环境来部署一个单实例的有状态的应用,通过这个简单的例子来理解kubernetes存储里的一些常用基本概念。
查询默认的StorageClass
kubectl get storageclass
创建存储配置文件
编写一个创建存储的配置文件,起名mysql-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: standard
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mysql/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: standard
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
从上面配置文件里主要有三个概念:
StorageClass: 从字面意思理解就是存储类别,每个存储类别有对应的Provisioner(提供者/插件),例如:AWSElasticBlockStore 、NFS、Glusterfs、Local等等,这个和具体的存储硬件或云服务商高度相关,可以把它理解成类似电脑里硬件的驱动。上面minikube用到的Provisioner叫k8s.io/minikube-hostpath。
PersistentVolume: 简称 PV, 这个表示持久化存储卷,它和Docker里的Volume类似,是对存储的一种通用和抽象的表示,它具体的实现是通过StorageClass来实现的, 从上面的配置文件我们不难理解它定义了一个PV,名称叫mysql-pv-volume,使用standard这个StorageClass来实现,容量是10GB, 因为minikube用的是hostpath的类型,所以需要有一个hostPath参数定义path路径即/mysql/data。
PersistentVolumeClaim : 简称PVC, 表示持久化存储卷声明, 这个是用于将PV挂载到Pod上,PVC是一种不需要了解具体细节,以声明的方式来获取持久化存储的方式。从上面的配置文件不难理解,这个声明就是需要StorageClass为Standard的,容量10G的存储。至于怎么获取、关联、挂载存储到Pod上是由Kubernetes帮你完成的。
创建部署配置文件
编写一个mysql的配置部署的文件,名称叫mysql-deployment.yaml,内容如下
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
从上面配置文件我们可以看到关于存储的两个关键配置参数:
volumeMounts: 这里指定了挂载的卷名称和路径
volumes: 这里指定了卷的名称和PVC声明, 名称恰好和volumeMounts是对应的, PVC声明则和上面创建存储配置文件里的PVC名称是一致的,这样就对应上了。
可以用下面这个图来理解它们之间的关系:
Deployment只依赖PVC的定义,这样通过PVC,PV以及StorageClass这几个关系可以使得Deployment不直接依赖某个具体的存储实现,这样要变更或扩容存储时,只需要修改PV和PVC的配置参数即可,而Deployment只需要指定PVC的名称和容量需求和其他需求。非常类似于软件设计里面的思想,依赖接口或抽象,不依赖具体实现。
部署应用
应用创建存储的配置文件
kubectl apply -f ./mysql-pv.yaml
persistentvolume/mysql-pv-volume created
persistentvolumeclaim/mysql-pv-claim created
应用创建部署的配置文件
kubectl apply -f ./mysql-deployment.yaml
service/mysql created
deployment.apps/mysql created
查看PV
kubectl get pv
查看PVC
kubectl get pvc
查看mysql的deployment
kubectl describe deployment mysql
查看PVC的详细信息
kubectl describe pvc mysql-pv-claim
验证存储
我们从另外一个方面来验证下存储是否起作用。
因为我的学习环境是在docker下部署的minikube,所以需要进入到minikube容器里看看
docker exec -it minikube bash
可以看到minikube里出现了/mysql/data目录,这个也是我们上面存储配置文件里定义的hostpath。
查询mysql的Pods
kubectl get pods -l app=mysql
通过kubectl进入到mysql服务的Pod里
kubectl exec -it mysql-54bff57899-w5j8m -- bash
进入容器后,输入如下命令
mysql -uroot -p
输入密码: password (这个是在上面deployment配置文件里定义的,当然实际生产不能这么直接在配置文件里定义密码),如下所示:
然后随便创建一个数据库
CREATE DATABASE my_db;
show databases;
然后我们故意删除mysql的Deployment
kubectl delete deployments mysql
执行后,mysql的deployements和pods都会被删除掉。
然后重新执行
kubectl apply -f ./mysql-deployment.yaml
然后获取重新生成的pods
kubectl get pods -l app=mysql
再按照上面的步骤去查询下my_db数据库是否存在,如果存在,则说明存储的确是持久化了,不会因为Pods删除而消失。