【容器应用系列教程】Kubernetes数据卷Volume管理

一、关于Volume

  • 用于实现数据的持久化存储
  • Kubernetes支持多种类型的卷,例如EmptyDirHostPathnfsglusterfsceph

关于NFS搭建教程:https://www.wsjj.top/archives/62
关于glusterFS搭建教程:https://www.wsjj.top/archives/103
关于ceph搭建教程:https://www.wsjj.top/archives/105

二、EmptyDir临时卷

  • 创建Pod时,Pod运行的node节点会创建临时卷,并将卷挂载到Pod指定的目录中
  • 临时卷存放目录
    • /var/lib/kubelet/pods/<pod id>/volumes/kubernetes.io~empty-dir/自定义的卷名称
  • Pod宕机销毁后,该临时卷中的数据会随之被删除

1.创建基于EmptyDir临时卷的Pod

[root@k8s-master wordpress]# vim vo-centos.yml

apiVersion: apps/v1
kind: Deployment
metadata:
    name: test1
    labels:
        app: test1
spec:
    replicas: 1
    selector:
         matchLabels:
             app: test1
    template:
       metadata:
           labels:
              app: test1
       spec:
           containers:
           - name: test1
             image: centos:7
             imagePullPolicy: IfNotPresent
             tty: true
             volumeMounts:
               - name: test1-volume	#要挂载到哪个数据卷上
                 mountPath: /data	#容器内部data目录
           volumes:
             - name: test1-volume	#创个数据卷名
               emptyDir: {}
[root@k8s-master wordpress]# kubectl create -f vo-centos.yml

测试读写数据

注意:创建Pod的时候没有指定命名空间,所以默认使用default

[root@k8s-master wordpress]# kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
test1-77fbb8dbbc-cnp52   1/1     Running   0          3m36s

[root@k8s-master wordpress]# kubectl exec -it test1-77fbb8dbbc-cnp52 -- bash
[root@test1-77fbb8dbbc-cnp52 /]# touch /data/{1..10}.mp3
[root@test1-77fbb8dbbc-cnp52 /]# ls /data
1.mp3  10.mp3  2.mp3  3.mp3  4.mp3  5.mp3  6.mp3  7.mp3  8.mp3  9.mp3

查看Pod跑在哪个机器上

[root@k8s-master wordpress]# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP                NODE                   NOMINATED NODE   READINESS GATES
test1-77fbb8dbbc-cnp52   1/1     Running   0          5m58s   192.168.242.167   k8s-node02.linux.com   <none>           <none>

查看临时卷

前往node02操作
可以看到,这些是我们在容器内部创建的几个测试文件

[root@k8s-node02 ~]# ls /var/lib/kubelet/pods/0c1cbb4c-d6ce-4603-84c9-48c25c4aedc3/volumes/kubernetes.io~empty-dir/test1-volume/
10.mp3  1.mp3  2.mp3  3.mp3  4.mp3  5.mp3  6.mp3  7.mp3  8.mp3  9.mp3

删除Pod

[root@k8s-master wordpress]# kubectl delete -f vo-centos.yml
deployment.apps "test1" deleted
再次查看,发现数据自动被删掉了
[root@k8s-node02 ~]# ls /var/lib/kubelet/pods/0c1cbb4c-d6ce-4603-84c9-48c25c4aedc3/volumes/kubernetes.io~empty-dir/test1-volume/
ls: 无法访问/var/lib/kubelet/pods/0c1cbb4c-d6ce-4603-84c9-48c25c4aedc3/volumes/kubernetes.io~empty-dir/test1-volume/: 没有那个文件或目录

三、hostPath永久卷

  • 创建Pod时,Pod运行的node节点会在本地创建目录,并该目录挂载到Pod
  • Pod宕机后,宿主机对应目录中的文件不会消失

1.创建基于hostPathPod

[root@k8s-master wordpress]# vim vo-centos.yml

apiVersion: apps/v1
kind: Deployment
metadata:
    name: test2
    labels:
        app: test2
spec:
    replicas: 1
    selector:
         matchLabels:
             app: test2
    template:
       metadata:
           labels:
              app: test2
       spec:
           containers:
           - name: test2
             image: centos:7
             imagePullPolicy: IfNotPresent
             tty: true
             volumeMounts:
               - name: test2-volume
                 mountPath: /data	#挂载到容器内/data目录
           volumes:
             - name: test2-volume
               hostPath:
                 path: /test2	#指定物理机上的/test2为数据目录

kubernetes有一点和Docker不同,当Docker想要通过-v永久挂载的话,物理机必须存在被挂载的目录,但是kubernetes会自动创建不存在的目录

[root@k8s-master wordpress]# kubectl create -f vo-centos.yml

进入容器测试数据永久挂载

[root@k8s-master wordpress]# kubectl exec -it test2-645897fbd8-67plx -- bash
[root@test2-645897fbd8-67plx /]# touch /data/{1..20}.jpg
[root@test2-645897fbd8-67plx /]# ls /data
1.jpg   12.jpg  15.jpg  18.jpg  20.jpg  5.jpg  8.jpg
10.jpg  13.jpg  16.jpg  19.jpg  3.jpg   6.jpg  9.jpg
11.jpg  14.jpg  17.jpg  2.jpg   4.jpg   7.jpg

查看Pod跑在哪个node节点上

[root@k8s-master wordpress]# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP                NODE                   NOMINATED NODE   READINESS GATES
test2-645897fbd8-67plx   1/1     Running   0          86s   192.168.242.168   k8s-node02.linux.com   <none>           <none>

查看node2节点上的test2目录

[root@k8s-node02 ~]# ls /test2
10.jpg  12.jpg  14.jpg  16.jpg  18.jpg  1.jpg   2.jpg  4.jpg  6.jpg  8.jpg
11.jpg  13.jpg  15.jpg  17.jpg  19.jpg  20.jpg  3.jpg  5.jpg  7.jpg  9.jpg
删除Pod测试
[root@k8s-master wordpress]# kubectl delete -f vo-centos.yml 
deployment.apps "test2" deleted
可以看到Pod被删了,数据还在
[root@k8s-node02 ~]# ls /test2
10.jpg  12.jpg  14.jpg  16.jpg  18.jpg  1.jpg   2.jpg  4.jpg  6.jpg  8.jpg
11.jpg  13.jpg  15.jpg  17.jpg  19.jpg  20.jpg  3.jpg  5.jpg  7.jpg  9.jpg

四、基于NFS的网络卷

1.准备阶段

新开一台虚拟机作为NFS服务器
所有k8s-node节点安装NFS依赖,负责让node节点可以识别NFS文件系统

[root@k8s-node01 ~]# yum install -y nfs-utils
[root@k8s-node02 ~]# yum install -y nfs-utils

2.配置NFS服务器

过程省略
关于NFS安装配置教程:https://www.wsjj.top/archives/62

[root@k8s-master wordpress]# vim vo-centos.yml

apiVersion: apps/v1
kind: Deployment
metadata:
    name: test3
    labels:
        app: test3
spec:
    replicas: 1
    selector:
         matchLabels:
             app: test3
    template:
       metadata:
           labels:
              app: test3
       spec:
           containers:
           - name: test3
             image: centos:7
             imagePullPolicy: IfNotPresent
             tty: true
             volumeMounts:
               - name: test3-volume	#挂载自定义卷
                 mountPath: /data	#挂载到容器/data目录
           volumes:
             - name: test3-volume	#自定义卷名
               nfs:
                 server: "192.168.140.13"	#NFS服务器地址
                 path: /test3	#NFS共享的路径
[root@k8s-master wordpress]# kubectl create -f vo-centos.yml 
deployment.apps/test3 created

测试数据挂载

[root@k8s-master wordpress]# kubectl exec -it test3-68c44c86b7-25dp2 -- bash
[root@test3-68c44c86b7-25dp2 /]# touch /data/{1..5}.iso
[root@test3-68c44c86b7-25dp2 /]# ls /data
1.iso  2.iso  3.iso  4.iso  5.iso

查看NFS服务器上的共享目录

[root@k8s-nfs ~]# ls /test3
1.iso  2.iso  3.iso  4.iso  5.iso

可以看到,我们的数据被存到了远程NFS服务器身上

五、PV与PVC持久卷

1.PVPVC的介绍

  • PV全称PersistentVolume
    • 用于后端真实存储空间的映射
  • PVC全称PersistentVolumeClain
    • Pod使用存储空间的申请
  • 使用流程
    • 创建PV标识真实的存储空间
    • 创建PVC发送申请存储空间的请求,K8S集群会自动在PVPVC间建立映射关系
      • 建立映射关系:
        • 依靠存储空间的大小
        • 依靠PV的访问模式
    • 创建POD时绑定PVC,实现持久化

2.准备NFS服务器

过程省略
关于NFS安装配置教程:https://www.wsjj.top/archives/62

3.创建PV

[root@k8s-master wordpress]# vim pv1.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv1
spec:
  capacity:
    storage: 1.9G	#卷大小
  accessModes:	#指定访问模式
    - ReadWriteMany	#可以被多个节点以读写模式挂载
  persistentVolumeReclaimPolicy: Recycle	#自动回收策略
  nfs:
    server: 192.168.140.13	#远程NFS服务器地址
    path: /data1	#NFS共享的目录
  • accessModes:用于指定PV的访问模式,共有三种
    • ReadWriteOnce被单个节点以读写模式挂载
    • ReadWriteMany被多个节点以读写模式挂载
    • ReadOnlyMany被多个节点以只读模式挂载
  • persistentVolumeReclaimPolicy: Recycle
    • 指定回收模式是自动回收,当空间被释放时,K8S自动清理,然后可以继续被绑定使用
[root@k8s-master wordpress]# vim pv2.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv2
spec:
  capacity:
    storage: 4G
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    server: 192.168.140.13
    path: /data2
[root@k8s-master wordpress]# kubectl create -f pv1.yml 
persistentvolume/nfs-pv1 created
[root@k8s-master wordpress]# kubectl create -f pv2.yml 
persistentvolume/nfs-pv2 created

查看PV

[root@k8s-master wordpress]# kubectl get pv -n default
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
nfs-pv1   1900M      RWX            Recycle          Available                                   6m55s
nfs-pv2   4G         RWX            Recycle          Available                                   91s

4.创建PVC

PVC会自动寻找和关联符合要求的PV

[root@k8s-master wordpress]# vim pvc.yml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:
    - ReadWriteMany	#寻找符合多个节点以读写模式挂载条件的
  resources:
    requests:
      storage: 4G	#寻找容量4G
[root@k8s-master wordpress]# kubectl create -f pvc.yml 
persistentvolumeclaim/test-pvc created

查看PVC

可以看到STATUSBound绑定状态,这就说明PVC已经找到符合条件的PV,并且自动绑定好了

[root@k8s-master wordpress]# kubectl get pvc -n default
NAME       STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-pvc   Bound    nfs-pv2   4G         RWX                           61s

再次查看PV

可以看到nfs-pv2的状态变成的Bound绑定状态

[root@k8s-master wordpress]# kubectl get pv -n default
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM              STORAGECLASS   REASON   AGE
nfs-pv1   1900M      RWX            Recycle          Available                                              35m
nfs-pv2   4G         RWX            Recycle          Bound       default/test-pvc                           29m

5.创建Pod绑定PVC

apiVersion: apps/v1
kind: Deployment
metadata:
    name: test4	#注意命名空间问题,我这里没有指定,使用默认的default,PV和PVC同样都在default命名空间内
    labels:
        app: test4
spec:
    replicas: 1
    selector:
         matchLabels:
             app: test4
    template:
       metadata:
           labels:
              app: test4
       spec:
           containers:
           - name: test4
             image: centos:7
             imagePullPolicy: IfNotPresent
             tty: true
             volumeMounts:
               - name: test4-volume
                 mountPath: /data
           volumes:
             - name: test4-volume
               persistentVolumeClaim:	#指定为PVC的方式
                    claimName: test-pvc	#刚刚创建的PVC的名字
[root@k8s-master wordpress]# kubectl create -f vo-centos.yml 
deployment.apps/test4 created

进入容器测试数据

[root@k8s-master wordpress]# kubectl exec -it test4-75b7f4458d-swjcs -- bash
[root@test4-75b7f4458d-swjcs /]# touch /data/{1..10}.pdf
[root@test4-75b7f4458d-swjcs /]# touch /data/{1..10}.mp4
[root@test4-75b7f4458d-swjcs /]# ls /data
1.mp4  10.mp4  2.mp4  3.mp4  4.mp4  5.mp4  6.mp4  7.mp4  8.mp4  9.mp4
1.pdf  10.pdf  2.pdf  3.pdf  4.pdf  5.pdf  6.pdf  7.pdf  8.pdf  9.pdf

查看NFS服务器上是否有数据

[root@k8s-nfs ~]# ls /data2
10.mp4  1.mp4  2.mp4  3.mp4  4.mp4  5.mp4  6.mp4  7.mp4  8.mp4  9.mp4
10.pdf  1.pdf  2.pdf  3.pdf  4.pdf  5.pdf  6.pdf  7.pdf  8.pdf  9.pdf