一 总述

1 存储卷概念

POD 自身具有生命周期,因此其内部运行的容器及相关数据无法完成持久化,docker支持配置容器使用存储卷将数据持久存储于自身文件系统之外的存储系统,其可以是节点文件系统或网络文件系统。相应的Kubernetes 提供的存储卷属于POD资源级别,共享与POD内的所有容器,可用于在勇气的文件系统之外存储应用程序的相关数据,甚至还可独立于POD生命周期之外实现数据持久化


存储卷: 定义在POD资源之上,可被其内部的所有容器挂载的共享目录,它关联至某外部的存储设备之上的存储空间,从而独立于容器自身的文件系统,而数据是否具有持久能力则取决于存储卷自身能否支持持久化

2 存储卷类型

1 节点级别的存储卷

empty: 其生命周期和POD资源相同
hostPath:其虽然可实现持久化存储,但若POD被调度至其他节点,则该节点的存储资源需要被迁移到指定节点,否则将无法持久化

2 网络级别存储卷

NFS
ceph
GlusterFS
...

其可实现数据的持久化存储

3 特殊存储卷

secret: 用于向POD传递某些敏感信息,如密码、私钥、证书等。
configmap:用于向POD中注入非敏感数据,如配置文件,其可实现容器配置文件集中化定义和管理

3 存储卷使用方式

1 直接在POD中进行指定和配置

POD中定义的存储有两部分组成:
1 pods.spec.volumes: 用于定义在POD之上挂载的存储卷列表,及存储的来源
核心字段
pods.spec.volumes.name : 用于定义此存储卷的名称,下面的挂载中需要通过此名称关联此存储卷
pods.spec.volumes.TYPE:用于指定此存储卷的类型, 如emptydir、NFS、gitRepo等


2 pods.spec.containers.volumeMounts : 用于定义存储卷被挂载到POD的位置及其相关的挂载形式
核心字段
pods.spec.containers.volumeMounts.mountPath :用于定义挂载到目标容器的具体位置,如/usr/share/nginx/html
pods.spec.containers.volumeMounts.name: 用于引用上述存储卷名称。
pods.spec.containers.volumeMounts.readOnly : 指定存储卷是否为只读存储卷。默认为false,及为读写存储卷。
pods.spec.containers.volumeMounts.subPath: 定义挂载存储卷时使用的子路径,及在mountPath指定的路径下使用一个子路径作为其挂载点。

2 通过PV和PVC 进行引用和配置

二 临时存储卷

1 概述

emptyDir 存储卷生命周期与其POD相同,其长用于对数据缓存或临时存储,数据的共享等。
gitRepo 存储卷可以看做是emptyDir存储卷的一种实际应用,使用该存储卷的POD创建资源可以通过挂载目录访问指定的代码仓库中的数据,使用gitRepo存储卷的POD资源在创建时,会首先创建一个空目录(emptyDir)并克隆(clone)一份指定的GIT仓库中的数据到该目录,而后再创建容器并挂载该存储卷。

2 emptyDir存储卷

pods.spec.volumes.emptyDir 其主要包含两个字段

pods.spec.volumes.emptyDir.medium:此目录所在的存储介质类型,取值有"default"或 "memory",默认为"default",表示使用节点的默认存储介质。"memory"则表示基于RAM的临时文件系统tmpfs,空间受限于内存,但性能好,通常用于为容器中提供缓存空间。

pods.spec.volumes.emptyDir.sizeLimit: 用于指定当前存储卷的限额,默认为nil,表示不限制。

实例

#[root@master1 emptyDir]# cat demo.yaml 
apiVersion: v1
kind: Pod
metadata:
    name: demo-empty
    namespace: default
spec:
    volumes:  #定义挂载的存储卷
        - name: html  # 指定存储卷名称
          emptyDir: {}  # 指定存储卷类型
    containers:
        - name: nginx1
          image: nginx:1.14
          ports:
            - name: http
              containerPort: 80
          volumeMounts:  #指定挂载存储卷
            - name: html  #指定挂载存储卷名称 
              mountPath: /usr/share/nginx/html  #指定挂载存储卷目录
              readOnly: true  # 指定挂载存储卷读写方式
        - name: nginx2  # 配置另一个容器,用于指定写入临时存储卷
          image: alpine
          volumeMounts:
            - name: html
              mountPath: /html
          command: ["/bin/sh","-c"]  # 配置写入存储卷数据
          args:
            - while true; do
                echo $(date) >> /html/index.html;
                sleep 5;
              done

部署

kubectl apply -f demo.yaml 

查看
kubernetes 存储卷与数据持久化

kubernetes 存储卷与数据持久化

测试

kubernetes 存储卷与数据持久化

3 gitRepo存储卷

1 核心字段

pods.spec.volumes.gitRepo.repository: git仓库URL,其是必选字段
pods.spec.volumes.gitRepo.directory: 目标目录名称,名称中不能包含".."字符,"."表示将仓库中的数据直接复制到卷目录中,否则,为复制到卷目录中以用户指定的字符串为名称的子目录中。
pods.spec.volumes.gitRepo.revision: 特定的revision提交的哈希码。

使用gitRepo存储卷的POD资源运行的工作节点上必须安装GIT程序,否则克隆仓库的操作将无法完成,在1.12起,gitRepo存储卷已经被废弃。

2 实战

1 安装git

yum -y install git

2 创建实例并挂载存储卷

[root@master em]# cat demo.yaml 
apiVersion: v1
kind: Pod
metadata:
    name: demo
    namespace: default
spec:
    containers:
        - name: demo
          image: nginx:1.14
          ports:
            - name: http
              containerPort: 80
          volumeMounts:
            - name: html
              mountPath: /usr/share/nginx/html
    volumes:
        - name: html
          gitRepo:
            directory: "."
            repository:  https://gitee.com/ChangPaoZhe/test
            revision: "develop"

3 部署

kubectl apply -f demo.yaml 

4 查看并测试

kubernetes 存储卷与数据持久化

kubernetes 存储卷与数据持久化

三 节点存储卷

1 概述

Hostpath 类型的存储卷时将工作节点上某个文件系统的目录或文件挂载到POD中的一种存储卷,可独立于POD资源的生命周期,因此具有持久性,但其在本地,因此只能应用于特定情况下的存储卷的使用需求。

2 核心字段

配置 hostPath 存储卷的嵌套字段共有两个:
1 用于指定工作节点上的目录路径的必选字段
pods.spec.volumes.hostPath.path

2 指定存储卷类型type,它支持使用的卷类型包含
pods.spec.volumes.hostPath.type

A DirectoryOrCreate: 指定的路径不存在时自动将其创建为权限为0755的空目录,属主属组均为kubelet;
B Directory: 必须存在的文件路径
C FileOrCreate: 指定的路径不存在时自动将其创建的权限为0644的空文件,属主和属组同样是kubelet。
D File: 必须存在的文件路径
E Socket: 必须存在的socket 文件路径
F CharDevice: 必须存在的字符设备文件路径
G BlockDevice: 必须存在的块设备文件路径

3 实例

#[root@master em]# cat demo1.yaml 
apiVersion: v1
kind: Pod
metadata:
    name: demo1
spec:
    containers:
        - name: demo1
          image: ikubernetes/filebeat:5.6.7-alpine
          env:    #设置环境变量
            - name: REDIS_HOST
              value: redis.ilinux.io:6379
            - name: LOG_DEVEL
              value: info
          volumeMounts:  # 设置容器挂载 
            - name: varlog
              mountPath: /var/log
            - name: socket
              mountPath: /var/run/docker.sock
            - name: varlib
              mountPath: /var/lib/docker/containers
              readOnly: true
    volumes:
        - name: varlog  # 设置节点挂载名称
          hostPath:  # 设置节点挂载路径
            path: /var/log  
        - name: varlib
          hostPath:
            path: /var/lib/docker/containers
        - name: socket  
          hostPath:
            path: /var/run/docker.sock

部署

kubectl apply -f demo1.yaml 

kubernetes 存储卷与数据持久化

这类Pod资源通常受控于daemonset类型的POD控制器,起运行与集群中的每个工作节点上,负责收集工作节点上系统级别的相关数据,但其不同节点的文件或许不完全相同,于是,那些要求事先必须存在的文件或目录的满足状态也可能会不同,在节点中创建的文件或目录默认仅有root可写,若期望容器内的进程有写权限,则要么将其设置为特权容器,要么修改节点上的目录路径权限。

四 网络存储卷

1 概述

专用的网络存储卷:
1 传统的NAS或SAM设备(如 NFS,iscsi,fc)
2 分布式存储 (clusterFS,RBD)
3 云端存储
4 构建在各类存储系统上的抽象管理层等

2 NFS 存储卷

1 核心字段

pods.spec.volumes.nfs
NFS 存储卷在POD对象终止后仅仅是被卸载而非删除,其能够实现调度的持久化存储
核心字段:
pods.spec.volumes.nfs.server : 用于指定NFS服务器的IP地址或主机名,必选字段

pods.spec.volumes.nfs.path: NFS 服务到处的文件系统路径,必选字段

pods.spec.volumes.nfs.readOnly:是否以只读方式挂载,默认为false。

2 实例

1 部署无密码的NFS 服务。部署结果如下
kubernetes 存储卷与数据持久化

2 配置相关实例并进行部署

apiVersion: v1
kind: Pod
metadata:
    name: demo2
    namespace: default
spec:
    containers:
        - name: demo2
          image: nginx:1.14
          ports:
            - name: http
              containerPort: 80
          volumeMounts:
            - name: html
              mountPath: /usr/share/nginx/html
    volumes:
        - name: html
          nfs:
            server: 192.168.90.110
            path: /data/nfs/v1
            readOnly: false

部署

 kubectl apply -f demo2.yaml 

查看

kubernetes 存储卷与数据持久化

配置相关网页

kubernetes 存储卷与数据持久化

测试结果
kubernetes 存储卷与数据持久化

.

3 GlusterFS 存储卷

1 总述

GlusterFS (cluster filesystem)是一个开源的分布式文件系统,是水平扩展存储解决方案gluster的核心, glusterfs 通过扩展能够支持数PB存储容量和处理数千客户端,glusterfs 借助TCP/IP 或 infiniBand RDMA网络将物理分布式的存储资源聚集在一起,使用单一全局名称空间来管理数据,另外,glusterfs 基于可堆叠的用户空间设计,可为各种不同数据负载提供优异的性能,是另一种流行的分布式存储解决方案,要配置POD资源使用glusterfs存储卷,需满足:
1 存在某可用的glusterfs 存储集群
2 glusterfs 集群中创建一个能满足POD资源数据存储需要的卷
3 在k8S 集群内的各个节点上安装glusterfs客户端程序包


另外,若需要基于glusterfs使用存储卷的动态供给机制,还需要事先部署heketi,他用于为glusterfs集群提供restful 风格的管理接口,glusterfs 几圈及hekei 的配置包含

2 核心字段

Endpoints<string>: endpoints 资源的名称,此资源要事先存在,用于提供gluster集群的部分节点信息作为其访问入口,必选字段

Path <string>: 用于到glusterfs集群的卷路径,如kube-redis,必选字段
readOnly<boolean>: 是否为只读卷


注意
部署实例请参考https://blog.csdn.net/phn_csdn/article/details/75153913?utm_source=debugrun&utm_medium=referral
需在节点上安装
yum install -y glusterfs glusterfs-fuse

实例

[root@master all]# cat demo4.yaml 
apiVersion: v1
kind: Endpoints
metadata:
    name: gluster  #设置名称
subsets:   
    - addresses:  # 设置其相关主机名和端口号
        - ip: 192.168.90.120
      ports:
        - port: 24007
          name: glusterd
    - addresses:
        - ip: 192.168.90.110
      ports:
        - port: 24007
          name: glusterd
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: demo-gfs-dep
    namespace: default
spec:
    replicas: 3
    selector:
        matchLabels:
            app: gfs
    template:
        metadata:
            name: demo-gfs
            namespace: default
            labels:
                app: gfs
        spec:
            containers:
                - name: demo-gfs
                  image: nginx:1.14
                  ports:
                    - name: http
                      containerPort: 80
                  volumeMounts:
                    - name: html
                      mountPath: /usr/share/nginx/html
            volumes:
                - name: html
                  glusterfs:  # 配置挂载类型
                    endpoints: gluster  # endpoint 名称
                    path: models  # glusterfs 共享目录的块名称,不是其共享目录的目录结构
                    readOnly: false

部署

kubectl apply -f demo4.yaml 

查看
kubernetes 存储卷与数据持久化

一个节点创建一个文件夹,其他节点均可见
kubernetes 存储卷与数据持久化

在其中注入内容
kubernetes 存储卷与数据持久化

对象存储节点查看

kubernetes 存储卷与数据持久化

访问测试

kubernetes 存储卷与数据持久化

五 持久存储卷

1 概述

上述网络存储卷的缺点是:管理员用户必须清晰了解所用到的网络存储系统的访问细节才能完成存储卷相关的配置任务,这与kubernetes的向用户和开发隐藏底层架构的目标相背离,对于存储资源的好是能够像计算资源一样,用户和开发人员无需了解POD资源挂载情况,无需了解存储系统是什么设备以及位于何处,为此,kubernetes的PersistentVolume子系统在用户与管理员之间添加了一个抽象层,从而使得存储系统的使用和管理直接解耦

2 persistentVolume(PV)

1 总述

对底层共享存储的抽象,将共享存储作为一种可由用户申请使用的资源,实现了"存储消费"机制,通过存储插件,PV支持使用多种网络存储或云端存储等多种后端存储系统。如NFS、RBD和Cinder等。PV 是集群级别的资源,其不属于任何名称空间,用户对PV资源的使用需要PVC(persistendVolumeClaim)提出申请来完成绑定,是PV资源的消费者,其向PV申请特定大小的空间及相关的访问模式,从而创建出PVC存储卷,而后再由POD资源通过persistentVolumeClaim 存储卷关联使用。


尽管PVC使得用户可以以抽象的方式访问存储资源,但很多时候还是会涉及PV的不少属性,其两者衔接方面的偏差必然导致用户的需求无法及时得到有效满足。自kubernetes 1.4 版本来时引入了storageclass资源类型,其可用于将存储资源定义为具有显著特性的类别(class)而不是具体的PV,用户通过PVC 直接向意向的类别发出申请,匹配由管理员事先创建的PV,或者由其按需为用户动态创建的PV,这样做便免去了事先创建PV的过程。

2 创建PV

1 PV 组成部分

pv.spec.capacity  : 用于定义当前PV的容量,支持空间设定
pv.spec.accessModes: 访问模式,
ReadWriteOnce:  仅仅可被单节点读写挂载,命令行中简写为RWO ReadOnlyMany : 可被多个节点只读挂载,命令简写为ROX 
ReadWriteMany: 可被多个节点同时读写挂载,命令行中简写为RWX 

各存储卷支持的读写模式

kubernetes 存储卷与数据持久化

pv.spec.persistentVolumeReclaimPolicy: PV 空间被释放时的处理机制,可用类型为Retain(默认,保留)、recycle(回收)或 delete(删除)
Retain 保持不动,由管理员手动处理
recycle: 空间回收,及删除存储卷目录下的所有文件,目前仅NFS 和 hostPath 支持此操作
delete: 删除存储卷,仅部分云端存储系统支持,如AWS  GCE  Azure disk 和 cinder 
pv.spec.volumeMode:卷类型,用于指定此卷可被用作文件系统还是裸设备,默认为文件系统
pv.spec.storageClassName:当前PV所属的storageClass名称,默认为空
pv.spec.mountOptions :挂载选择组成的列表,如ro、soft或 hard 等

2 创建PV

[root@master1 pv]# cat demo.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv1
    labels:
        app: v1
spec:
    accessModes: ["ReadWriteMany"]  #设置访问模式,其可同时设置多个
    capacity:  #定义PV存储大小
        storage: 5Gi  
    nfs:   #设置NFS 参数
        path: /data/v1  # 设置NFS 挂载地址
        server: 192.168.1.100  # 设置NFS服务器地址,其可以是域名
        readOnly: false  #设置其可读写
---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv2
    labels:
        app: v2
spec:
    accessModes: ["ReadWriteOnce","ReadWriteMany"]  #设置访问模式,其可同时设置多个
    capacity:  #定义PV存储大小
        storage: 5Gi  
    nfs:   #设置NFS 参数
        path: /data/v2  # 设置NFS 挂载地址
        server: 192.168.1.100  # 设置NFS服务器地址,其可以是域名
        readOnly: false  #设置其可读写
---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv3
    labels:
        app: v3
spec:
    accessModes: ["ReadWriteMany","ReadOnlyMany"]  #设置访问模式,其可同时设置多个
    capacity:  #定义PV存储大小
        storage: 10Gi  
    nfs:   #设置NFS 参数
        path: /data/v3  # 设置NFS 挂载地址
        server: 192.168.1.100  # 设置NFS服务器地址,其可以是域名
        readOnly: false  #设置其可读写
---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv4
    labels:
        app: v4
spec:
    accessModes: ["ReadWriteOnce","ReadWriteMany","ReadOnlyMany"]  #设置访问模式,其可同时设置多个
    capacity:  #定义PV存储大小
        storage: 5Gi  
    nfs:   #设置NFS 参数
        path: /data/v4  # 设置NFS 挂载地址
        server: 192.168.1.100  # 设置NFS服务器地址,其可以是域名
        readOnly: false  #设置其可读

3 部署

kubectl apply -f demo.yaml

4 查看

kubernetes 存储卷与数据持久化

5 PV 资源状态

Available : 可用状态的自由资源,尚未被PVC绑定
Bound: 已经被绑定的PVC
released: 绑定的PVC已经被删除,但资源尚未被集群回收
Failed : 因自动回收资源失败而处于故障状态

3 创建PVC

1 总述

PersistentVolumeClaim 是存储卷类型资源,通过申请占用某个PV 而创建,其与PV是一对一的关系,用户无需关心底层实现细节,只需指定目标空间大小,访问模式、PV标签选择器和storageClass等相关信息即可。

2 PVC 核心字段

pv.spec.accessModes: PVC访问模式,与PV定义相同
        ReadWriteOnce:  仅仅可被单节点读写挂载,命令行中简写为RWO 
        ReadOnlyMany : 可被多个节点只读挂载,命令简写为ROX 
        ReadWriteMany: 可被多个节点同时读写挂载,命令行中简写为RWX 
pvc.spec.resources: 当前PVC 存储卷需要占用的资源量,目前仅支持空间大小,其包含limit 和 request
pvc.spec.selector: 定义PVC使用标签选择PV,只有满足此选择的PV才可能被关联至该PVC 
pvc.spec.storageClassName: 所依赖的存储类的名称
pvc.spec.volumeMode: 卷类型,用于指定此卷可被用于文件系统该是裸格式的块设备,默认是文件系统
pvc.spec.volumeName: 用于直接指定要绑定的PV的卷名 

3 创建PVC

[root@master1 pv]# cat demopvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc1
    labels:
        app: pvc1
spec:
    accessModes: ["ReadWriteMany"]
    resources:
        requests:
            storage: 5Gi
    selector:  #使用标签进行选择为PV2
        matchLabels:
            app: v2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc2
    labels:
        app: pvc2
spec:
    accessModes: ["ReadWriteOnce","ReadWriteMany","ReadOnlyMany"]   # 使用模式匹配只能是PV4
    resources:
        requests:
            storage: 5Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc3
    labels:
        app: pvc3
spec:
    accessModes: ["ReadWriteMany"]
    resources:  #使用大小匹配为PV3
        requests:
            storage: 8Gi

创建PVC

kubectl apply -f demopvc.yaml 

查看服务
kubernetes 存储卷与数据持久化

4 PVC 绑定POD

1 核心字段

pods.spec.volumes.persistentVolumeClaim.claimName
绑定的PVC的名称,必选字段

pods.spec.volumes.persistentVolumeClaim.readOnly
绑定的模式

2 实例

#[root@master1 pv]# cat pod.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: dem-po
    namespace: default
spec:
    selector:
        matchLabels:
            app: demo1
    replicas: 3
    template:
        metadata:
            name: dem-dem
            namespace: default
            labels:
                app: demo1
        spec:
            containers:
                - name: dem-po
                  image: nginx:1.14
                  volumeMounts:
                    - name: html
                      mountPath: /usr/share/nginx/html
            volumes:
                - name: html
                  persistentVolumeClaim:
                    claimName: pvc1

部署

kubectl apply -f pod.yaml 

查看

kubernetes 存储卷与数据持久化

测试
kubernetes 存储卷与数据持久化

kubernetes 存储卷与数据持久化

4 存储类

1 概念

存储类(StorageClass)简称sc,其是kubernetes资源类型中的一种,是由管理员为管理PV方便而按需创建的类别,其可理解为PV的特性描述

通过向后端存储传输信息而达到和前端匹配的效果

存储类的好处之一就是支持PV的动态创建,用于用到持久性存储时,需要通过创建PVC来绑定匹配的PV,此类操作需求量较大,或当管理员创建的PV无法满足PVC 需求时,系统按PVC 的需求标准动态创建适配的PV会为存储管理带来极大灵活性。
PVC 通过对存储类的申请而获取到PV


存储类对象的名称至关重要,是用户调用的标识,创建存储类,除了名称外,还需要为其定义三个关键字段 : provisioner(sc.provisioner 供给方)、parameter (参数 sc.provisioner)和 reclaimPolicy(回收策略sc.reclaimPolicy)

2 核心字段

1 storageClass  spec 
        storageClass  Spec 中的字段是定义存储类时最重要的字段,其包含五个可用字段
        provisioner(供给方): 即提供了存储资源的存储系统,存储类需要依赖provisioner 来判定要使用的存储插件以便适配到目标存储系统,K8S 内建有多种供给方,其都是以kubernetes.io 为前缀的,其也支持用户依据kubernetes规范自定义 provisioner。
2 parameters (参数): 存储类使用参数描述要关联的存储卷,不同的provisioner可用的参数各不相同 
3 reclaimPolicy : 定义回收策略。可为delete 和retain,
4 volumBindingMode : 定义如何为PVC 完成供给和绑定,默认为  "volumeBindin  immediate" 此选项仅在启动了存储卷调度功能时才能生效 
5 mountOptions:由当前类动态创建的PV的挂载选项列表 

注意
上述所需的环境请参考 :https://www.cnblogs.com/breezey/p/8849466.html

kubernetes 节点上须有heketi 的key,需要有heketi-client 软件,必须要加载内核模块modprobe dm_thin_pool

如果有密码认证,则编码之前hekei的密码
kubernetes 存储卷与数据持久化

下属实例中有密码认证

apiVersion: v1
kind: Secret
metadata:
    name: heketi-secret
    namespace: default
stringData:  # 设置其密码
    key: Admin
type: kubernetes.io/glusterfs
---
apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
    name: glusterfs
    namespace: default
provisioner: kubernetes.io/glusterfs
parameters:
    resturl: "http://192.168.90.110:8080"    # 调用其接口
    clusterid: "84d3dcbeb048089c18807b7be943d219"  #查询其ID并配置
    restauthenabled: "true"  # 认证模式为true
    restuser: "admin"  # 认证用户名
    secretNamespace: "default"  # 名称空间
    secretName: "heketi-secret"  # 认证调用secret名称
    #restuserkey: "adminkey" #此处可以以明文的形式写成密码
    gidMin: "40000"  
    gidMax: "50000"
    volumetype: "replicate:2"  #设置其类型

部署

kubectl apply -f sc.yaml

查看
kubernetes 存储卷与数据持久化

kubernetes 存储卷与数据持久化

2 动态PV供给

动态PV供给的启用,需要实现由管理员创建至少一个存储类,不同的provisoner 的创建方式各不相同。

支出存储类的存储资源

kubernetes 存储卷与数据持久化

目前,在PVC的定义中指定使用的存储类资源的方式有两种:一种是使用pvc.spec.storageClassName,另一种是使用"volume.beta.kubernetes.io/storage-class" 资源注解,建议使用第一种方式,以免出现设置不同导致的错误配置问题。
任何支持PV动态供给的存储系统都可以在定义为存储类后由PVC动态申请使用,存储卷是必备资源,随着规模的变化,其也会随之而变动

配置PVC

#[root@master all]# cat pvc1.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: glusterfs-nginx
  namespace: default
  annotations:
    volume.beta.kubernetes.io/storage-class: "glusterfs"  #此处指定为glusterfs模式获取
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 2Gi

部署

kubectl apply -f pvc1.yaml 

查看
kubernetes 存储卷与数据持久化

kubernetes 存储卷与数据持久化

5 PV 和PVC 生命周期

1总述

PV 是集群级别资源,而PVC则是资源需求,PVC发起对PV的申请,则两个绑定,其PV和PVC是一一对应的关系,可用于响应PVC的PV必须能够容纳PVC的请求条件

2 存储供给

1 静态供给

静态供给是由集群管理员手动创建的一定数量的PV的资源供给方式,这些PV负责处理存储系统的细节,并将由其抽象成易用的存储资源供用户使用,静态提供的PV可能属于某存储类,也可能没有存储类

2 动态供给

不存在某静态的PV匹配到用户的PVC申请时,kubernetes集群会尝试为PVC动态创建符合需求的PV,此即为动态供给,这种方式依赖于存储类的绑定,PVC必须向一个事先存在的存储类发起动态分配PV的请求,没有指定存储类的PVC请求将会被禁止使用动态创建PV的方式。

3 存储绑定

用户基于一系列存储需求和访问模式定义好PVC后,kubernetes系统的控制器即会为其查找匹配的PV,并于找到之后二者之间建立其关系,而后他们二者状态转换为绑定状态,若PV是为PVC而动态创建的,则该PV专用于其PVC。
若是无法为PVC找到可匹配的PV,则PVC将一直处于未绑定状态,直到符合条件的PV出现并完成绑定方才可用


1 存储使用
pod资源基于pod.spec.volumes.persistentVolumeClaim卷类型的定义,将选定的PVC关联为存储卷,而后即可为内部的容器使用,对于支持多中访问方式的存储卷来说,用户需要额外指定使用模式,一旦完成将存储卷挂载至POD对象内的容器中,其应用即可使用关联的PV提供存储空间


2 PVC 保护
为了避免使用中的存储卷被移除而导致数据丢失,自kubernetes 1.9 开始当POD资源占用此PVC时,其不能删除PVC。

4 存储回收

完成存储卷的使用目标之后,即可删除PVC对象以便进行资源回收,策略如下


1 留存

留存就是在删除PVC后,kubernetes不会自动删除PVm而仅仅是将其置于释放状态,不过,此状态的PV尚且不能被其他PVC申请绑定,因为之前绑定成功的数据来存在,需要由管理员手动决定其后续处理方案,这就意味着,如果想要再次使用此类PV资源,则需要由管理员进行下面操作
1 删除PV,这之后,此PV的数据仍然存在于外部存储
2 手工清理存储之上遗留的数据
3 手工删除存储系统级的存储卷释放空间,以便再次创建或直接重新创建PV


2 回收

如果可被底层存储插件支持,资源回收策略会在存储卷上执行数据删除操作并让PV资源再次变为可被claIm。另外,管理员可配置一个自定义的回收器POD模板,以便执行自定义回收操作


3 删除 delete

对于支持delete回收策略的存储插件来说,在PVC被删除后会直接移除PV对象,同时移除的还有PV相关的外部存储系统上的存储资产,支持这种操作的存储系统有AWS EBS、GCE PD、Azure Disk 或 Cinder,动态创建的PV资源的回收区别于相关存储类上的定义,存储类上相关的默认策略为Delete。


4 扩展PVC

kubernetes 从1.8版本开始增加了扩展PV空间的特定,目前其支持的扩展PVC 机制的存储卷有:
gcePersistentDisk
awsElasticBlockStore
Cinder
glusterfs
rbd

"PersistentVolumeClaimResize"准入插件负责对支持空间大小变动的存储卷执行更多的验证操作,管理员需要事先启用此插件才能使用PVC扩展机制,

对于包含文件系统的存储卷来说,只有在新的POD资源基于读写模式开始使用PVC时才会执行文件系统大小的调整工作,换句话说,如果某被扩展的存储卷已经由POD资源使用,则需要重新创建此POD对象才能出发文件系统大小的调整操作。支持空间调整的文件系统有XFS、EXT3和EXT4