K8s存储
Volume: 数据卷,实现数据本地存储
PV: PersistenVolume持久卷,实现数据网络存储
-------------------------------------------
Volume简介:
Volume是kubernetes Pod中多个容器访问的共享目录。
volume被定义在pod上,被这个pod的多个容器挂载到相同或不同的路径下。
volume的生命周期与pod的生命周期相同,pod内的容器停止和重启时一般不会影响volume中的数据(数据存储在宿主机目录)。
volume一般被用于持久化,保存pod产生的数据。
volume类型:
emptyDir(临时)
hostPath(持久)
- emptyDir:
-
- emptyDir数据卷的特点:
- emptyDir的生命周期与所属的pod相同,pod删除时,emptyDir中的数据也会被删除。
- emptyDir类型需要在volums字段中定义,用volumsMounts字段挂载使用
- kubernetes会在node上自动创建一个目录,无需提前创建。
- emptyDir Volume主要用于某些应用程序无需永久保存数据,多个容器的共享目录等。
-
- 示例:多个容器共享数据
[root@master01 ~]# vim emptyDir.yaml
kind: Pod
apiVersion: v1
metadata:
name: auth-vol
spec:
containers:
- name: vol1
image: busybox
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /vol1_dir
name: shared-volume
args:
- /bin/sh
- -c
- echo "hello world" > /vol1_dir/hello.txt ; sleep 30000
- name: vol2
image: busybox
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /vol2_dir
name: shared-volume
args:
- /bin/sh
- -c
- cat /vol2_dir/hello.txt ;sleep 30000
volumes:
- name: shared-volume
emptyDir: {}
分析:
volumes是指k8s的存储方案,容器内volumeMounts使用的是volumes内定义的存储,
volumes定义的宿主机上的目录或文件,分别挂载到了vol1(/vol1_dir)和vol2(/vol2_dir)这个两个容器的对应目录
在vol1容器的/vol1_dir目录下创建的文件,在vol2容器的/vol2_dir目录下,同样可以看到
-
- 验证:
-
-
- 应用emptyDir.yaml
-
[root@master01 ~]# kubectl apply -f emptyDir.yaml
-
-
- 查看vol2容器的日志
-
[root@master01 ~]# kubectl logs auth-vol vol2
hello world
-
-
- 查看一个Pod运行在了哪个Node节点上
-
[root@master01 ~]# kubectl get pod -o wide
-
-
- 到对应Node节点上(此处为worker01)查看该容器的详细信息(Mounts)
-

注:pause 容器,用于管理 Pod 的网络和存储资源的基础容器。
查看容器19abea5a4291 详细信息中Mounts区域中内容,确定数据源目录

-
-
- 查看宿主机数据源目录中的文件
-
![]()
-
-
- 删除pod,宿主机中的数据被删除
-
[root@master01 ~]# kubectl delete -f emptyDir.yaml
在worker01上查看文件:
![]()
注:emptyDir的使用场景:
如果Pod被删除,那么数据也会被删除,不具备持久化。
Pod内的容器,需要共享数据卷的时候,使用的是临时数据卷。
- HostPath 数据卷
-
- Hostpath数据卷的特点:
hostPath卷将主机节点中的文件或目录挂载到集群中
hostPath就等于运行容器时使用的命令:
docker run -v /host/path:/container/path
除了path属性之外,用户还可以指定type:
DirectoryOrCreate 如果指定的位置没有目录,将创建,权限755,与kubelet具有相同的所有权
Directory 指定的位置必须存在目录
FileOrCreate 如果指定的位置没有文件,将创建,权限644,与kubelet具有相同的所有权
File 指定的位置必须存在文件
[root@master01 ~]# kubectl delete all --all
[root@master01 ~]# vim hostPath.yaml
kind: Pod
apiVersion: v1
metadata:
name: auth-vol
spec:
containers:
- name: vol1
image: busybox
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /vol1_dir
name: shared-volume
args:
- /bin/sh
- -c
- echo "hello world" > /vol1_dir/hello.txt ; sleep 30000
- name: vol2
image: busybox
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /vol2_dir
name: shared-volume
args:
- /bin/sh
- -c
- cat /vol2_dir/hello.txt ;sleep 30000
volumes:
- name: shared-volume
hostPath:
path: "/data/hostPath"
type: DirectoryOrCreate
[root@master01 ~]# kubectl apply -f hostPath.yaml
[root@master01 ~]# kubectl get pod -o wide #查看pod节点(此处在worker02上)
[root@worker02 ~]# ls /data/hostPath/ #查看数据存储位置
hello.txt
[root@master01 ~]# kubectl logs auth-vol vol2
hello world
[root@master01 ~]# kubectl delete all --all #删除pod
[root@worker02 ~]# ls /data/hostPath/ #查看数据存储位置
hello.txt
- PV持久卷(PersistenVolume)
-
- PV、PVC简介:
-
-
- PV:
-
PersistentVolume ( PV )是集群之中的一块网络存储。
跟 Node 一样,也是集群的资源。
-
-
- PVC:
-
PV 是存储资源,而 PersistentVolumeClaim (PVC) 是对 PV 的请求。
-
- 实现过程:
- 准备存储设备
- 创建pv(关联到存储)
- 创建pvc(向pv申请资源)
- 创建pod(连接pvc)
-
-
- 准备存储设备:此处使用NFS
-
# 所有节点都安装nfs-utils工具包和rpc-bind服务。
yum install nfs-utils -y
# 这里准备将NFS服务部署在master01节点上,需要在master01节点上提前规划好共享的目录
生产环境下网络存储是独立存在的
[root@master01 ~]# mkdir /nfsdata
[root@master01 ~]# vim /etc/exports
/nfsdata *(rw,sync,no_root_squash)
[root@master01 ~]# systemctl start nfs-server
[root@master01 ~]# systemctl enable nfs-server
[root@master01 ~]# showmount -e
-
-
- 创建PV(关联到存储):
-
[root@master01 ~]# vim pv1.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: pv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata
server: 192.168.10.11
[root@master01 ~]# kubectl apply -f pv1.yaml
[root@master01 ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 1Gi RWO Retain Available nfs 58s
PV所支持的访问模式:
ReadWriteOnce:PV能以read-write的模式mount到单个节点。(命令模式:RWO)
ReadOnlyMany: PV能以read-only 的模式mount到多个节点。(命令模式:ROX)
ReadWriteMany: PV能以read-write的模式Mount到多个节点。(命令模式:RWX)
PV状态:
Available(可用):一块空闲资源还没有被任何声明绑定
Bound(绑定):卷已经被声明绑定
Released(已释放):声明被删除,但是资源还未被集群重新声明
Failed(失败):该卷的自动回收失败
PV空间的回收策略:persistentVolumeReclaimPolicy
Recycle: 回收,会清除数据,自动回收(新k8s版本已不支持)。
Retain: 保留,需要手动清理回收。
Delete: 删除,(自动删除pv,网络存储数据仍保留,一般在动态供给中使用)
-
-
- 创建一个PVC(向pv申请资源)
-
PV与PVC的绑定,通过storageClassName和accessModes这两个字段共同决定。
[root@master01 ~]# vim pvc1.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc1
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs
resources:
requests:
storage: 1Gi
[root@master01 ~]# kubectl apply -f pvc1.yaml
[root@master01 ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pv1 1Gi RWO Retain Bound default/pvc1 nfs 6h1m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/pvc1 Bound pv1 1Gi RWO nfs 4m40s
再次查看pv,状态status由Available换成了Bound,CLAIM(宣称)换成了default/pvc1占用
总结:
1. RWO模式:当系统中的pv被绑定之后,就不会被其他的PVC绑定了。
2. 如果系统中有多个能够满足pvc要求的pv,那么,系统会自动选择一个符合pvc申请空间大小的PV,进行绑定,尽量不浪费存储空间。
-
-
- 创建pod(连接pvc)
-
-
-
-
- 创建pod1:
-
-
[root@master01 ~]# vim pod1.yaml
kind: Pod
apiVersion: v1
metadata:
name: pod1
spec:
containers:
- name: pod1
image: busybox
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- sleep 30000
volumeMounts:
- mountPath: "/data"
name: mydata
volumes:
- name: mydata
persistentVolumeClaim:
claimName: pvc1
[root@master01 ~]# kubectl apply -f pod1.yaml
[root@master01 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 31s 10.244.2.4 worker02 <none> <none>
在pod1的容器中,创建一个文件
[root@master01 ~]# kubectl exec -it pod1 -- touch /data/auth.txt
nfs服务器上查看:
[root@master01 ~]# ls /nfsdata/
auth.txt
-
-
-
- 再创建pod2,连接相同的pvc
-
-
[root@master01 ~]# vim pod2.yaml
kind: Pod
apiVersion: v1
metadata:
name: pod2
spec:
containers:
- name: pod2
image: busybox
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- sleep 30000
volumeMounts:
- mountPath: "/data"
name: mydata
volumes:
- name: mydata
persistentVolumeClaim:
claimName: pvc1
查看相应容器/data目录内容为nfs共享数据
[root@master01 ~]# kubectl apply -f pod2.yaml
[root@master01 ~]# kubectl exec -it pod2 -- ls /data
auth.txt
-
-
- PV的空间回收
-
当pv中回收策略为:Retain
[root@master01 ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pv1 1Gi RWO Retain Bound default/pvc1 nfs 4m4s
-
-
-
- 验证dockerhost上PV上存放的数据
-
-
[root@master01 ~]# ls /nfsdata/
auth.txt
-
-
-
- 删除Pod,PVC,PV
-
-
[root@master01 ~]# kubectl delete pod,pv,pvc --all
-
-
-
- 查看数据
-
-
[root@master01 ~]# ls /nfsdata
auth.txt
可重复实验测试
[root@master01 ~]# rm -rf /nfsdata/*
[root@master01 ~]# kubectl apply -f pv1.yaml
[root@master01 ~]# kubectl apply -f pvc1.yaml
[root@master01 ~]# kubectl apply -f pod1.yaml
[root@master01 ~]# kubectl apply -f pod2.yaml
[root@master01 ~]# kubectl exec pod1 -- touch /data/auth2.txt
[root@master01 ~]# ls /nfsdata/
auth2.txt
//再次删除Pod,PVC,验证PV目录下存放的数据
[root@master01 ~]# kubectl delete pod,pvc,pv --all
[root@master01 ~]# ls /nfsdata/
auth2.txt
================================================
-
- PV,PVC的运用
现在部署一个MySQL服务,并且将MySQL的数据进行持久化存储。
-
-
- 创建PV,PVC
-
[root@master01 ~]# 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.10.11
[root@master01 ~]# vim mysql-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs
resources:
requests:
storage: 1Gi
[root@master01 ~]# mkdir /nfsdata/mysql-pv
[root@master01 ~]# kubectl apply -f mysql-pv.yaml
[root@master01 ~]# kubectl apply -f mysql-pvc.yaml
[root@master01 ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/mysql-pv 1Gi R Retain Bound default/mysql-pvc nfs 44s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/mysql-pvc Bound mysql-pv 1Gi RWO nfs 4s
-
-
- 部署MySQL
-
[root@master01 ~]# vim mysql.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
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:
- port: 3306
targetPort: 3306
nodePort: 31306
[root@master01 ~]# kubectl apply -f mysql.yaml
-
-
- 在MySQL数据库中添加数据
-
[root@master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-5d86c64fc9-5krvs 1/1 Running 0 56s
[root@master01 ~]# kubectl exec -it mysql-5d86c64fc9-5krvs -- mysql -uroot -p123.com
mysql> SHOW DATABASES; //查看当前的库。
mysql> CREATE DATABASE auth; //创建auth库。
mysql> USE auth; //选择使用auth库。
mysql> CREATE TABLE users(user_name char(10),user_passwd char(40)); //创建my_id表
mysql> INSERT users values ('zhangsan','123'); //往my_id表中,插入数据。
mysql> SELECT * FROM users; //查看my_id表中所有数据
-
-
- 模拟MySQ服务器节点故障
-
删除pod,k8s集群会产生一个新的Pod,验证这个Pod内是否有之前数据。
[root@master01 ~]# kubectl get pod -o wide
。。。。
[root@master01 ~]# kubectl exec -it 新pod -- mysql -u root -p123.com
mysql> show databases;
mysql> use auth;
mysql> show tables;
mysql> select * from users;
验证数据还在
Nfs服务器上查看:
[root@master01 ~]# ls /nfsdata/mysql-pv
Mysql数据
更多推荐
所有评论(0)