k8s存储类型详解
k8s存储一、k8s存储类型简介二、PV和PVC相关介绍三、pv的空间回收策略验证四、pv和pvc的运用示例一、k8s存储类型简介1.类比docker的存储类型回顾docker的数据持久化。docker的容器层可以提供存储:存储在可写层(CopyOnWrite)docker的数据持久化解决方案:data volume---->1、bind mount 2、docker manager vol
一、k8s存储类型简介
1.类比docker的存储类型
回顾docker的数据持久化。
docker的容器层可以提供存储:存储在可写层(CopyOnWrite)
docker的数据持久化解决方案:
data volume---->1、bind mount 2、docker manager volume
其实两者没有什么显著差别,不同点在于是否需要提前准备dockerHost上的相关文件或目录。
2.k8s存储类型详解
volume
与docker类似:将宿主机上的某个文件或者目录挂载到Pod内。
emptyDir
写一个emptyDir.yaml的文件
[root@master ~]# vim emptyDir.yaml
kind: Pod
apiVersion: v1
metadata:
name: producer-consumer
spec:
containers:
- name: producer
image: busybox
volumeMounts:
- name: shared-volume
mountPath: /producer_dir #容器内的路径
args:
- /bin/sh
- -c
- echo "hello world" > /producer_dir/hello.txt; sleep 30000
- name: consumer
image: busybox
volumeMounts:
- name: shared-volume
mountPath: /consumer_dir
args:
- /bin/sh
- -c
- cat /consumer_dir/hello.txt; sleep 30000
volumes:
- name: shared-volume
emptyDir: {}
总结:根据上述yaml文件分析,volumes是指k8s的存储方案.容器内volumeMounts使用的是volumes内定义的存储,所以现在可以理解为,volumes定义的dockerHost上的目录或文件,分别挂载到了producer(/producer_dir)和consumer(/consumer_dir)这个两个容器的对应目录。可以判断出在consumer这个容器的/consumer_dir目录下,应该也会有一个hello.txt的文件。
验证查看conumer容器的日志
[root@master ~]# kubectl logs producer-consumer consumer
hello world
查看一个Pod运行在了那个Node节点上
[root@master ~]# kubectl get pod -o wide
到对应Node节点上查看该容器的详细信息(Mounts)
"Mounts": [
{
"Type": "bind",
"Source": "/var/lib/kubelet/pods/9dcfac16-
c55b-458c-bf49-f20867shared-volume",
"Destination": "/producer_dir",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
注意:查看到该容器的Mounts字段,等于是运行docker容器的时候使用这么一条命令:
docker run -v /producer_dir busybox
emptyDir的使用场景:如果Pod被删除,那么数据也会被删除,不具备持久化。Pod内的容器,需要共享数据卷的时候,使用的临时数据卷。
hostpath
hostPath就等于运行容器时使用下面的命令
docker run -v /host/path:/container/path
编写一个hostpath.yaml文件,直接将emptyDir.yaml文件的volumes字段更改为:hostPath。
[root@master volume]# mkdir -p /data/hostPath
[root@master ~]# vim hostpath.yaml
kind: Pod
apiVersion: v1
metadata:
name: producer-consumer
spec:
containers:
- name: producer
image: busybox
volumeMounts:
- name: shared-volume
mountPath: /producer_dir #容器内的路径
args:
- /bin/sh
- -c
- echo "hello world" > /producer_dir/hello.txt; sleep 30000
- name: consumer
image: busybox
volumeMounts:
- name: shared-volume
mountPath: /consumer_dir
args:
- /bin/sh
- -c
- cat /consumer_dir/hello.txt; sleep 30000
volumes:
- name: shared-volume
hostPath:
path: "/data/hostPath"
总结:HostPath这种方式相比emptyDir来说,持久化功能强,但它实际增加了Pod与host的耦合,所以大部分资源不会使用这种持久化方案,通常关于docker或者k8s集群本身才会使用。
二、PV和PVC相关介绍
1.pv与pvc简介
PV:PersistentVolume
是k8s集群的外部存储系统,一般是设定好的存储空间(文件系统中的一个目录);
PVC:PersistentVolumeClaim
如果应用需要用到持久化的时候,可以直接向PV申请空间;
2.基于nfs服务来创建的pv
(1)master和node节点都需要安装nfs-utils、rpcbind。
[root@master ~]# yum -y install nfs-utils rpcbind
(2)将NFS服务部署在master节点上,需要在master节点上提前规划好共享的目录。
[root@master ~]# mkdir /nfsdata
[root@master ~]# vim /etc/exports
/nfsdata *(rw,sync,no_root_squash)
[root@master ~]# systemctl start rpcbind
[root@master ~]# systemctl enable rpcbind
[root@master ~]# systemctl start nfs-server
[root@master ~]# systemctl enable nfs-server
[root@master ~]# showmount -e
Export list for master:
/nfsdata *
[root@node1 ~]# showmount -e 192.168.229.187
[root@node2 ~]# showmount -e 192.168.229.187
(3)创建pv.yaml文件。
[root@master ~]# mkdir yaml
[root@master ~]# mkdir -p /nfsdata/pv1
[root@master ~]# cd yaml
[root@master yaml]# vim pv.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: pv1
spec:
capacity: #PV的容量
storage: 1Gi
accessModes: #访问模式
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.168.229.187
[root@master yaml]# kubectl apply -f pv.yaml
[root@master yaml]# kubectl get pv
pv所支持的访问模式
ReadWriteOnce:PV能以read-write的模式mount到单个节点;
ReadOnlyMany:PV能以read-only的模式mount到多个节点;
ReadWriteMany:PV能以read-write的模式Mount到多个节点;
关于pv所支持的访问模式的理解:
主要分为两个方面
读写方面:如果是可以读写的,则认为pod可以在挂载的路径下执行读写操作。
如果是只读的,那么pod就只能够读取pv共享目录下的数据。
节点方面:挂载到单个或者多个节点,指的是kubernetes的工作节点。
验证结果:
k8s官方表示,readonly是以只读的方式挂载,但实际上仍需要在挂载时指定其挂载类型为readonly:true,才可以实现只读。
这里所说的挂载到单个或多个节点,和官方描述不一致,需进一步验证。
persistentVolumeReclaimPolicy:PV空间的回收策略
Recycle:会清除数据,自动回收;
Retain:需要手动清理回收;
Delete:云存储专用的回收空间使用命令;
(4)创建一个PVC,向刚才的PV申请使用空间。注意这里PV与PVC的绑定是通过storageClassName和accessModes这两个字段共同决定。
[root@master yaml]# vim pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Mi
storageClassName: nfs
[root@master yaml]# kubectl apply -f pvc.yaml
[root@master yaml]# kubectl get pvc
总结
1.当系统中的PV被绑定之后,就不会被其他PVC所绑定了。
2.如果系统中有多个可以满足PVC要求的PV,则系统会自动选择一个符合PVC申请空间大小的PV进行绑定,尽量不浪费存储空间。
(5)创建一个Pod,来使用上述PVC。
[root@master yaml]# vim pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: pod1
spec:
containers:
- name: pod1
image: busybox
args:
- /bin/sh
- -c
- sleep 30000
volumeMounts:
- name: mydata
mountPath: "/data"
volumes:
- name: mydata
persistentVolumeClaim:
claimName: pvc1
[root@master yaml]# kubectl apply -f pod.yaml
[root@master yaml]# kubectl get pod
(6)验证/nfsdata/pv1目录与Pod内"/data"目录的一致性。
[root@master pv1]# pwd
/nfsdata/pv1
[root@master pv1]# echo "hello persistentVolume" > test.txt
[root@master pv1]# kubectl exec pod1 cat /data/test.txt
hello persistentVolume
三、pv的空间回收策略验证
1.回收策略为:recycle
[root@master ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM
POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pv1 1Gi RWO Recycle
Bound default/pvc1 nfs 21h
(1)验证master上PV上存放的数据
[root@master ~]# ls /nfsdata/pv1/
test.txt
(2)删除pod资源和pvc
[root@master ~]# kubectl delete pod pod1
[root@master ~]# kubectl delete pvc pvc1
(3)查看PV的状态为Released然后变为Available
[root@master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS
CLAIM STORAGECLASS REASON AGE
pv1 1Gi RWO Recycle Released default/pvc1 nfs 21h
[root@master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS
CLAIM STORAGECLASS REASON AGE
pv1 1Gi RWO Recycle Available nfs 21h
(4)验证数据被删除
[root@master ~]# ls /nfsdata/pv1/
注意:在释放空间的过程中,其实K8S生成了一个新的Pod,由这个Pod执行删除数据的操作。
2.回收策略为:Retain
...
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
...
(1)重新运行pvc,pod资源,然后在Pod内,创建对应的资源。
[root@master storage]# kubectl apply -f pvc.yaml
[root@master storage]# kubectl apply -f pod.yaml
[root@master storage]# kubectl exec pod1 touch /data/test.txt
[root@master storage]# ls /nfsdata/pv1/
test.txt
(2)再次删除Pod和PVC,验证PV目录下存放的数据。
[root@master storage]# kubectl delete pod pod1
[root@master storage]# kubectl delete pvc pvc1
[root@master storage]# ls /nfsdata/pv1/
test.txt
四、pv和pvc的运用示例
部署一个MySQL服务,并且将MySQL的数据进行持久化存储。
1.创建PV和PVC
[root@master mysql]# vim mysql-pv.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: mysql-pv
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 1Gi
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/mysql-pv
server: 192.168.229.187
[root@master mysql]# vim mysql-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
[root@master mysql]# mkdir -p /nfsdata/mysql-pv
[root@master mysql]# kubectl apply -f mysql-pv.yaml
[root@master mysql]# kubectl get pv
[root@master mysql]# kubectl apply -f mysql-pvc.yaml
[root@master mysql]# kubectl get pvc
2.部署mysql
[root@master mysql]# vim mysql.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: mysql
spec:
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: 123.com
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
---
kind: Service
apiVersion: v1
metadata:
name: mysql
spec:
type: NodePort
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
nodePort: 31306
3.在MySQL数据库中添加数据
[root@master mysql]# kubectl exec -it pod mysql-6fccccd487-pkx86 bash
mysql -u root -p123.com
mysql> SHOW DATABASES; #查看当前的库
mysql> CREATE DATABASE TEST; #创建test库
mysql> USE TEST; #选择使用test库
mysql> SHOW TABLES; #查看test库中的表
mysql> CREATE TABLE my_id(id int(4)); #创建my_id表
mysql> INSERT my_id values (9527); #往my_id表中插入数据
mysql> SELECT * FROM my_id; #查看my_id表中所有数据
4.模拟MySQL服务故障
k8s集群会生产一个新的Pod,验证这个Pod内是否有之前数据。
先查看运行MySQL服务的Pod在哪个节点,然后将该节点挂起,我们知道k8s肯定会在另外一个节点重新生成一个Pod。
[root@master ~]# kubectl get pod -o wide
新生成Pod后,同样进入Pod验证数据是否存在?存在。
[root@master ~]# kubectl get pod
[root@master ~]# kubectl exec -it pod mysql-6fccccd487-5q2dt bash
mysql -u root -p123.com
mysql> show databases;
mysql> use test;
mysql> show tables;
mysql> select * from my_id;
更多推荐
所有评论(0)