K8S 生产实践-12-共享存储-PV、PVC 和 StorageClass

一、为什么需要共享存储?

PV(PersistentVolume) 持久化存储卷

持久卷(PersistentVolume)简称PV,是集群中的一块存储,可以由管理员事先供应。
可以配置NFS、Ceph等常用存储配置,相对于volumes,提供了更多的功能,如生命周期管理、大小的限制。
PV 卷的供应有两种方式:静态供应或动态供应

静态:
集群管理员预先创建许多PV,在PV的定义中能够体现存储资源的特性。

动态:
集群管理员无须预先创建PV,而是通过 StorageClass 的设置对后端存储资源进行描述,标记存储的类型和特性。用户通过创建PVC对存储类型进行申请,系统将自动完成PV的创建及与PVC的绑定。如果PVC声明的Class为空"",则说明PVC不使用动态模式。

file

如上,挂载的nfs的路径为“/tmp”,服务器地址为: 172.22.1.2

PVC (PersistentVolumeClaim) 持久化存储卷声明

file

file

持久卷申领(PersistentVolumeClaim,PVC)表达的是用户对存储的请求。就像Pod消耗Node的资源一样,PVC消耗PV资源。PVC可以申请存储空间的大小(size)和访问模式。

file

由管理员创建PV连接到后端存储,使用人员或管理员创建PVC使用PV资源。

Pod与PVC与PV的关系
file

由一张图说一下PV与PVC的绑定,Pod又是怎么挂载PVC

  • 首先创建一个PV,它的名字是 pv-nfsstorageClassName 名字是nfs-slow(这个名字不唯一,就是说其他PV也可以叫这个名字)
  • 然后创建一个PVC,它的名字是test-pv-claimstorageClassName名字是nfs-slow(PVC绑定PV也是根据这个名字判断,根据上一点说的特性也就是说一个PVC可以绑定多个storageClassName名字是nfs-slow的PV)注意PVC设置的资源大小要等于小于PV。
  • 最后Pod使用的时候创建一个volumes,这个名字是test-pv-storage,这个volumes使用的PVC资源要写PVC的name,也就是 test-pv-claim;等Pod中的容器挂载资源的时候挂载的名字是volumes的name,也就是test-pv-storage。

Pod 使用
file

StorageClass
file

file

file

gluster

Gluster 是一种软件定义的分布式存储,可以扩展到数 PB。它为对象、块和文件存储提供接口。

https://github.com/gluster/glusterfs

二、实战

1、创建NAS/NFS类型的PV

生产不推荐NFS。可以使用NAS。

准备一台NFS服务器

第一步:准备一台NFS服务器,我这个装的有点多,你也可以只安装nfs服务器

[root@localhost ~]# yum -y install nfs* rpcbind

第二步:所有节点安装nfs客户端,不然不能识别,每一个需要挂载nfs的节点都需要装

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

第三步:在服务端创建共享目录

[root@localhost ~]# mkdir -p /data/k8s

第四步:服务端配置共享目录

[root@localhost ~]# cat /etc/exports
/data/k8s/ *(rw,sync,no_subtree_check,no_root_squash)
[root@localhost ~]# exportfs -r
[root@localhost ~]# systemctl restart nfs rpcbind

第五步:有另外一台机器挂载共享目录测试是否成功

[root@k8s-master01 hgfs]# mount -t nfs 192.168.10.6:/data/k8s /mnt
[root@k8s-master01 mnt]# mkdir hah
[root@k8s-master01 mnt]# ls
111.txt  hah
# 在nfs服务端查看
[root@localhost k8s]# ls
111.txt  hah

创建一个PV

第一步:编写一个PV的yaml文件

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
spec:
  capacity:
    storage: 2Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs-slow
  nfs:
    path: /data/k8s
    server: 192.168.10.6

对上面的yaml文件做一下说明:

  • 通用的开头就不说了
  • capacity:容量配置,这个pv使用多大容量,当然需要后端存储支持才行
  • volumeMode:卷的模式,目录4有说明
  • accessModes:PV的访问模式,目录3有说明
  • accessClassName:PV的类,特定的PV只能绑定特定的PVC
  • persistentVolumeReclaimPolicy:回收策略,目录2有说明
  • nfs:NFS服务配置,里面包含共享目录和服务端IP

第二步:执行yaml文件创建此PV;注意PV的成功跟后端存储正不正常没什么关系。

[root@k8s-master01 ~]# kubectl create -f pv-nfs.yaml 
persistentvolume/pv-nfs created
[root@k8s-master01 ~]# kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv-nfs   2Gi        RWO            Recycle          Available           nfs-slow                54s

第三步:说一下PV的状态(STATUS)

  • Available:可用,没有被PVC绑定的空闲资源
  • Bound:已绑定,已经被PVC绑定
  • Released:已释放,PVC被删除,资源未被重新使用
  • Failed:失败,自动回收失败

实例:创建一个hostPath类型的PV

当你没有一个可靠的存储,但是数据又不能丢失,可以挂载到宿主机的路径,即使重启数据还在。

第一步:创建一个pv-host.yaml文件

apiVersion: v1
kind: PersistentVolume
metadata:
  name: host-pv-volume
  labels:
    type: local
spec:
  storageClassName: hostpath
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"  # 宿主机路径

第二步:执行yaml文件创建PV

[root@k8s-master01 ~]# kubectl create -f pv-host.yaml 
persistentvolume/host-pv-volume created
您在 /var/spool/mail/root 中有新邮件
[root@k8s-master01 ~]# kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
host-pv-volume   1Gi        RWO            Retain           Available           hostpath                9s
pv-nfs           2Gi        RWO            Recycle          Available           nfs-slow                30m

2、PVC

创建一个PVC挂载到Pod

注意:pvc要和Pod在同一个命名空间,而pv不需要;因为都是在默认空间,就没指定,需要注意。

第一步:编写一个PVC的yaml文件

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pv-claim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 2Gi  # 小于等于pv
  storageClassName: nfs-slow

第二步:执行yaml文件创建PVC;从下面这个状态来看已经绑定成功了,绑定了pv-nfs,类型为nfs-slow,都是前面指定的。

[root@k8s-master01 ~]# kubectl create -f pvc-nfs.yaml 
persistentvolumeclaim/test-pv-claim created
[root@k8s-master01 ~]# kubectl get pvc
NAME            STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-pv-claim   Bound    pv-nfs   2Gi        RWO            nfs-slow       20s

第三步:创建Pod挂载PVC

kind: Deployment
metadata:
  labels:
    app: dp-nginx
  name: dp-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: dp-nginx
    spec:
      volumes:
      - name: test-pv-storage
        persistentVolumeClaim:
          claimName: test-pv-claim
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: test-pv-storage
l
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dp-nginx
  name: dp-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: dp-nginx
    spec:
      volumes:
      - name: test-pv-storage
        persistentVolumeClaim:
          claimName: test-pv-claim
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: test-pv-storage

第四步:创建Pod,进入Pod查看挂载情况

[root@k8s-master01 ~]# kubectl get pod
NAME                       READY   STATUS    RESTARTS   AGE
dp-nginx-fcd88d6f8-prxcd   1/1     Running   0          22s
[root@k8s-master01 ~]# kubectl exec -ti dp-nginx-fcd88d6f8-prxcd -- bash
root@dp-nginx-fcd88d6f8-prxcd:/# df -Th
Filesystem              Type     Size  Used Avail Use% Mounted on
overlay                 overlay   17G  5.2G   12G  31% /
tmpfs                   tmpfs     64M     0   64M   0% /dev
tmpfs                   tmpfs    2.0G     0  2.0G   0% /sys/fs/cgroup
shm                     tmpfs     64M     0   64M   0% /dev/shm
/dev/mapper/centos-root xfs       17G  5.2G   12G  31% /etc/hosts
192.168.10.6:/data/k8s  nfs4      17G  2.4G   15G  14% /usr/share/nginx/html
tmpfs                   tmpfs    3.8G   12K  3.8G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                   tmpfs    2.0G     0  2.0G   0% /proc/acpi
tmpfs                   tmpfs    2.0G     0  2.0G   0% /proc/scsi
tmpfs                   tmpfs    2.0G     0  2.0G   0% /sys/firmware
# 可以看到10.6的共享目录已经挂载到了/nginx/html下

第五步:测试,在nfs服务器共享目录下创建资源,进入Pod容器内查看是否存在

# nfs服务器中创建资源
[root@localhost k8s]# ls
111.txt  hah
# 在Pod的nginx容器中查看
root@dp-nginx-fcd88d6f8-prxcd:/# cd /usr/share/nginx/html/
root@dp-nginx-fcd88d6f8-prxcd:/usr/share/nginx/html# ls
111.txt  hah
# 内容存在,说明创建成功

相关文章:
持久化存储PV与PVC/创建NAS/NFS类型的PV
PV和PVC
Kubernetes学习之路(十九)存储卷资源|nfs|Storage Class

为者常成,行者常至