一、PV配置示例

在企业内,可能存储很多不同类型的存储,比如NFS、Ceph、GlusterFS等,针对不同类型的后端存储具有不同的配置方式,这也是对集群管理员的一种挑战,因为集群管理员需要对每种存储都有所了解。接下来看一下几个常用的PV配置示例。

1.1 基于NFS的PV

首先我们需要安装一下NFS

1.每台机器安装NFS客户端

$ yum install nfs-utils -y

2.在k8s-node01(192.168.1.34)启动nfs

[root@k8s-node01 ~]# systemctl start nfs-server

在k8s-node01(192.168.1.34)查看nfs支持的版本

[root@k8s-node01 ~]# cat /proc/fs/nfsd/versions
-2 +3 +4 +4.1 +4.2

3.在k8s-node01(192.168.1.34)上创建一个共享目录

[root@k8s-node01 ~]# mkdir  -p  /data/nfs/test_nfs

4.在k8s-node01(192.168.134)编辑授权文件,这里网段根据自己主机来定,我这里网段是192.168.1.0/24

[root@k8s-node01 ~]# vim /etc/exports
/data/nfs/ 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)

5.在k8s-node01(192.168.1.34)配置生效

[root@k8s-node01 ~]# exportfs -r

6.在k8s-node01(192.168.1.34)重新加载NFS

[root@k8s-node01 ~]# systemctl reload nfs-server

7.在k8s-master01上进行挂载测试

[root@k8s-master01 ~]# mount -t nfs 192.168.1.34:/data/nfs /mnt/
[root@k8s-master01 ~]# cd /mnt/
[root@k8s-master01 mnt]# touch test123

8.在k8s-node01(192.168.1.34)进行验证

[root@k8s-node01 ~]# cd /data/nfs/
[root@k8s-node01 nfs]# ls
test123  test_nfs

接下来,我们对上面的测试进行卸载

1.针对上诉测试进行卸载

[root@k8s-master01 ~]# umount /mnt/

最后进行NFS配置示例

1.定义一个yaml文件

[root@k8s-master01 pv]# vim pv-nfs.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs-slow
  nfs:
    path: /data/nfs/test_nfs
    server: 192.168.1.34

上面参数说明:

  • capacity:容量配置
  • volumeMode:卷的模式,目前支持Filesystem (文件系统) 和 Block(块),其中Block类型需 要后端存储支持,默认为文件系统
  • accessModes:该PV的访问模式,这里设置为RWO,可以被单节点以读写模式挂载
  • storageClassName:PV的类,一个特定类型的PV 只能绑定到特定类别的PVC
  • persistentVolumeReclaimPolicy:回收策略
  • nfs:NFS服务配置,包括以下两个选项:path:NFS上的共享目录;server:NFS的IP地址

2.部署

[root@k8s-master01 pv]# kubectl create -f pv-nfs.yaml

3.结果验证

[root@k8s-master01 pv]# kubectl get -f pv-nfs.yaml
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv-nfs   5Gi        RWO            Recycle          Available           nfs-slow                16s

1.2 基于HostPath的PV

当公司目前没有可靠性的存储,但是想要部署k8s集群中应用的数据不丢失,这时把宿主机目录直接挂载到Pod,Pod的数据直接落在宿主机上。接下来介绍基于HostPath的PV:

1.在master01节点上创建挂载目录

[root@k8s-master01 pv]# mkdir -p /mnt/data

2.定义一个yaml文件

[root@k8s-master01 pv]# vim pv-hostpath.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-hostpath
  labels:
    type: local
spec:
  storageClassName: hostpath
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"

上面参数说明:

  • capacity:容量配置
  • accessModes:该PV的访问模式,这里设置为RWO,可以被单节点以读写模式挂载
  • storageClassName:PV的类,一个特定类型的PV 只能绑定到特定类别的PVC
  • hostPath:hostPath配置,path:"/mnt/data",其中/mnt/data为宿主机的目录

3.部署

[root@k8s-master01 pv]# kubectl create -f pv-hostpath.yaml

4.结果验证

[root@k8s-master01 pv]# kubectl get -f pv-hostpath.yaml
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
task-pv-volume   10Gi       RWO            Retain           Available           hostpath                26s

1.3 基于Ceph RBD的PV

Ceph可能是目前企业内最常用的一种分布式存储之一,同时支持文件系统、块存储及对象存储,和上述NFS和HostPath相比,具有高可用性和读写高效性。接下来看一下Ceph RBD类型的PV配置:

1.定义一个yaml文件

[root@k8s-master01 pv]# vim pv-cephrbd.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: ceph-rbd-pv
spec:
  capacity:
    storage: 1Gi
  storageClassName: ceph-fast
  accessModes:
    - ReadWriteOnce
rbd:
  monitors:
    - 192.168.1.123:6789
    - 192.168.1.124:6789
    - 192.168.1.125:6789
  pool: rbd
  image: ceph-rbd-pv-test
  user: admin
  secretRef:
    name: ceph-secret
  fsType: ext4
  readOnly: false

上面参数说明:

  • monitors:Ceph的monitor节点的IP
  • pool:所用Ceph Pool的名称,可以使用ceph osd pool ls查看
  • image:Ceph块设备中的磁盘映像文件,可以使用rbd create POOL_NAME/IMAGE_NAME--size 1024创建,使用rbd list POOL_NAME查看
  • user:Rados的用户名,默认是admin
  • secretRef:用于验证Ceph身份的密钥
  • fsType:文件类型,可以是Ext4、XFS等
  • readOnly:是否是只读挂载

注意:Ceph的Pool和Image需要提前创建才能使用。虽然前面讲述了RBD类型的PV配置示例,但是在实际使用时,大多数Ceph存储的使用都是采用动态存储的方式,很少通过静态方式去管理。同时,Kubernetes所有的节点都需要安装ceph-common才能正常挂载Ceph.

2.部署

[root@k8s-master01 pv]# kubectl create -f pv-cephrbd.yaml

3.结果验证

[root@k8s-master01 pv]# kubectl get -f pv-cephrbd.yaml

二、PVC绑定PV

在工作场景中,k8s管理员会碰到两种场景:

  • 场景一:k8s管理员成功创建好PV,请求开发人员申请该PV并创建PVC配置到Volumes配置一个PVC类型的存 储,并指定PVC的名字是xxx即可
  • 场景二:k8s管理员成功创建好PV和PVC,请求开发人员在Volumes指定PVC的名字是xxx即可

持久化存储入门-PVC绑定PV

注意:PVC和PV进行绑定的前提条件是一些参数必须匹配,比如accessModes、storageClassName、volumeMode都需要相同,并且PVC的storage需要小于等于PV的storage配置。

下面进行PVC挂载示例:

首先创建PV

1.定义一个yaml文件

[root@k8s-master01 pv]# vim pv-nfs.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs-slow
  nfs:
    path: /data/nfs/test_nfs
    server: 192.168.1.34

上面参数说明:

  • capacity:容量配置
  • volumeMode:卷的模式,目前支持Filesystem (文件系统) 和 Block(块),其中Block类型需 要后端存储支持,默认为文件系统
  • accessModes:该PV的访问模式,这里设置为RWO,可以被单节点以读写模式挂载
  • storageClassName:PV的类,一个特定类型的PV 只能绑定到特定类别的PVC
  • persistentVolumeReclaimPolicy:回收策略
  • nfs:NFS服务配置,包括以下两个选项:path:NFS上的共享目录;server:NFS的IP地址

2.部署

[root@k8s-master01 pv]# kubectl create -f pv-nfs.yaml

3.结果验证

[root@k8s-master01 pv]# kubectl get -f pv-nfs.yaml
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv-nfs   5Gi        RWO            Recycle          Available           nfs-slow                16s

其次创建PVC

1.定义一个名为pvc-nfs.yaml 的yaml文件

[root@k8s-master01 pv]# vim pvc-nfs.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nfs-pvc-claim
spec:
  storageClassName: nfs-slow #要求PV一致
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi #小于等于PV大小

注意:PVC有命名空间限制,这里默认是default空间

2.部署

[root@k8s-master01 pv]# kubectl create -f pvc-nfs.yaml

3.结果验证,观察到状态已更改为Bound,但此时并不代表可用

[root@k8s-master01 pv]# kubectl get -f pvc-nfs.yaml
NAME            STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
nfs-pvc-claim   Bound    pv-nfs   5Gi        RWO            nfs-slow       60s

4.查看PV状态,此时PV状态由原来的Available变为Bound ,但此时并不代表可用

[root@k8s-master01 pv]# kubectl get pv pv-nfs
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                   STORAGECLASS   REASON   AGE
pv-nfs   5Gi        RWO            Recycle          Bound    default/nfs-pvc-claim   nfs-slow                79m

最后,创建Pod

1.在k8s-master01上定义一个名为pvc-nfs-pod.yaml的yaml文件

[root@k8s-master01 pv]# vim pvc-nfs-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      volumes:
      - name: task-pv-storage
        persistentVolumeClaim:
          claimName: nfs-pvc-claim
      containers:
      - env:
        - name: TZ
          value: Asia/Shanghai
        - name: LANG
          value: C.UTF-8
        image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        imagePullPolicy: IfNotPresent
        name: nginx
        volumeMounts:
          - mountPath: "/usr/share/nginx/html"
            name: task-pv-storage

2.在k8s-master01上开始部署

[root@k8s-master01 pv]# kubectl create  -f pvc-nfs-pod.yaml

3.在k8s-master01上查看pod状态

[root@k8s-master01 pv]# kubectl get po
NAME                            READY   STATUS    RESTARTS       AGE
nginx-59fdd74bd4-2c2hk          1/1     Running   0              19s
nginx-59fdd74bd4-dlfgf          1/1     Running   0              19s

4.在k8s-master01上以容器的方式进入pod,修改文件内容,用于测试另一个Pod是否会同步

[root@k8s-master01 pv]# kubectl exec -it  nginx-59fdd74bd4-2c2hk  -- sh
/ # cd /usr/share/nginx/html/
/usr/share/nginx/html # echo "test_nfs" > /usr/share/nginx/html/index.html
/usr/share/nginx/html # cat /usr/share/nginx/html/index.html
test_nfs

5.继续在k8s-master01上以容器的方式进入另一个pod后,查看已经同步

[root@k8s-master01 pv]# kubectl exec  nginx-59fdd74bd4-dlfgf  -- cat /usr/share/nginx/html/index.html
test_nfs

三、PVC创建和挂载失败的原因

3.1 PVC一直Pending的原因

1.PVC的空间申请大小大于PV的大小 2.PVC的StorageClassName没有和PV的一致 3.PVC的accessModes和PV的不一致

3.2 挂载PVC的Pod一直处于Pending

1.PVC没有创建成功/PVC不存在 2.PVC和Pod不在同一个Namespace

四、常见存储分类

1.文件存储 一些数据可能需要被多个节点使用,比如用户的头像、用户上传的文 件等,实现方式:NFS、NAS、FTP、CephFS等。 2.块存储 一些数据只能被一个节点使用,或者是需要将一块裸盘整个挂载使用, 比如数据库、Redis等,实现方式:Ceph、GlusterFS、公有云。 3.对象存储 由程序代码直接实现的一种存储方式,云原生应用无状态化常用的实现方式,实现方式:一般是符合S3协议的云存储,比如AWS的S3存储、Minio、七牛云等。