简介

Kubermetes对于有状态的容器应用或者对数据需要持久化的应用,不仅需要将容器内的目录挂载到宿主机的目录或者emptyDir临时存储卷,而且需要更加可靠的存储来保存应用产生的重要数据,以便容器应用在重建之后,仍然可以使用之前的数据。不过,存储资源和计算资源(CPU/内存)的管理方式完全不同。为了能够屏蔽底层存储实现的细节,让用户方便使用,同时能让管理员方便管理, Kubernetes从v1.0版本就引入PersistentVolumePersistentVolumeClaim两个资源对象来实现对存储的管理子系统。

PersistentVolume (PV)是对底层网络共享存储的抽象,将共享存储定义为一种“资源”,比如节点(Node) 也是一种容 器应用可以“消费”的资源。PV由管理员进行创建和配置,它与共享存储的具体实现直接相关,例如GlusterFS、iSCSI、 RBD或GCB/AWS公有云提供的共享存储,通过插件式的机制完成与共享存储的对接,以供应用访问和使用。

PersistentVolumeClaim (PVC)则是用户对于存储资源的一个“申请”。就像Pod“消费”Node的资源一-样, PVC会“消费”PV资源。PVC 可以申请特定的存储空间和访问模式。

StorageClass,使用PVC“申请”到一定的存储空间仍然不足以满足应用对于存储设备的各种需求。通常应用程序都会对存储设备的特性和性能有不同的要求,包括读写速度、并发性能、数据冗余等更高的要求,Kubernetes 从v1.4版本开始引入了-一个新的资源对象StorageClass,用于标记存储资源的特性和性能。到v1.6版本时,StorageClass动态资源供应的机制得到了完善,实现了存储卷的按需创建,在共享存储的自动化管理进程中实现了重要的一步。

通过StorageClass的定义,管理员可以将存储资源定义为某种类别(Class), 正如存储设备对于自身的配置描述(Profile),例如“快速存储”“慢速存储”“有数据冗余”“无数据冗余”等。用户根据StorageClas的描述就能够直观得知各种存储资源的特性,就可以根据应用对存储资源的需求去申请存储资源了。

文档地址: https://kubernetes.io/docs/concepts/storage/persistent-volumes/

PersistentVolume支持的持久化存储的插件

Volume Plugin ReadWriteOnce ReadOnlyMany ReadWriteMany
AWSElasticBlockStore - -
AzureFile
AzureDisk - -
CephFS
Cinder - -
CSI depends on the driver depends on the driver depends on the driver
FC -
FlexVolume depends on the driver
Flocker - -
GCEPersistentDisk -
Glusterfs
HostPath - -
iSCSI -
Quobyte
NFS
RBD -
VsphereVolume - - (works when Pods are collocated)
PortworxVolume -
ScaleIO -
StorageOS - -

访问模式(accessModes)

  • ReadWriteOnce——该卷可以被单个节点以读/写模式挂载
  • ReadOnlyMany——该卷可以被多个节点以只读模式挂载
  • ReadWriteMany——该卷可以被多个节点以读/写模式挂载

在命令行中,访问模式缩写为

  • RWO - ReadWriteOnce
  • ROX - ReadOnlyMany
  • RWX - ReadWriteMany

回收策略(ReclaimPolicy)

  • Retain(保留)——手动回收
  • Recycle(回收)——基本擦除( rm -rf /myvolume/*
  • Delete(删除)——关联的存储资产(例如 AWS EBS、GCE PD、Azure Disk 和 OpenStack Cinder 卷)
    将被删除
    当前,只有 NFS 和 HostPath 支持回收策略。AWS EBS、GCE PD、Azure Disk 和 Cinder 卷支持删除策略

卷的状态

卷可以处于以下状态:

  • Available(可用)——一块空闲资源还没有被任何声明绑定
  • Bound(已绑定)——卷已经被声明绑定
  • Released(已释放)——声明被删除,但是资源还未被集群重新声明
  • Failed(失败)——该卷的自动回收失败

使用nfs来实现共享存储

环境

主机 角色
10.0.0.201 Master
10.0.0.202 Master
10.0.0.203 Node

安装nfs

  • 安装nfs服务端

    1
    2
    # 10.0.0.201
    yum install nfs-utils rpcbind
  • 用于nfs服务的存储文件夹

    1
    2
    # 10.0.0.201
    mkdir -p /data/nfs
  • /etc/exports文件

    1
    2
    vi /etc/exports
    /data/nfs 10.0.0.0/24(rw,sync)
  • 开启nfs服务,更改文件夹权限

    1
    2
    3
    4
    5
    6
    7
    systemctl enable nfs-server.service && systemctl start nfs-server.service

    sudo chown nfsnobody /data/nfs
    # 检验是否开启成功
    showmount -e
    Export list for vmware-1:
    /data/nfs 10.0.0.0/24
  • nfs客户端安装

    1
    2
    # 所有节点都要安装
    yum install nfs-utils -y

添加StorageClass动态存储插件

文档地址:https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client

配置文件地址:https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client/deploy

  • rbac.yaml

    无需更改文件内容直接加载配置文件

  • nfs_deployment.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    apiVersion: v1
    kind: ServiceAccount
    metadata:
    name: nfs-client-provisioner
    ---
    kind: Deployment
    apiVersion: apps/v1
    metadata:
    name: nfs-client-provisioner
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: nfs-client-provisioner
    strategy:
    type: Recreate
    template:
    metadata:
    labels:
    app: nfs-client-provisioner
    spec:
    serviceAccountName: nfs-client-provisioner #这个要和ServiceAccount的metadata.name的名字一致
    containers:
    - name: nfs-client-provisioner
    image: quay.io/external_storage/nfs-client-provisioner:latest
    volumeMounts:
    - name: nfs-client-root
    mountPath: /persistentvolumes
    env:
    - name: PROVISIONER_NAME
    value: fuseim.pri/ifs # 自定义名称,storageclass后面要用到
    - name: NFS_SERVER
    value: 10.0.0.201 # nfs服务器地址
    - name: NFS_PATH
    value: /data/nfs # nfs系统的挂载路径
    volumes:
    - name: nfs-client-root
    nfs:
    server: 10.0.0.201 # nfs服务器地址
    path: /data/nfs # nfs系统的挂载路径
  • nfs_storageclass.yaml也就是class.yaml

    1
    2
    3
    4
    5
    6
    7
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
    name: managed-nfs-storage
    provisioner: fuseim.pri/ifs # nfs_deployment.yaml的PROVISIONER_NAME的名字一样
    parameters:
    archiveOnDelete: "false" # 当设置为“false”时,你的pv将不会被存档,在删除PVC时执行。
  • nfs_storageclass_pvc.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
    name: nfs-pvc
    # annotations:
    # volume.beta.kubernetes.io/storage-class: "managed-nfs-storage" # nfs_storageclass.yaml的name一样
    spec:
    storageClassName: "managed-nfs-storage" # nfs_storageclass.yaml的name一样
    accessModes:
    - ReadWriteOnce
    resources:
    requests:
    storage: 10Mi
  • 测试demo,web-deploy.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #deploy
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: web-deploy
    spec:
    strategy:
    rollingUpdate:
    maxSurge: 25%
    maxUnavailable: 25%
    type: RollingUpdate
    selector:
    matchLabels:
    app: web-deploy
    replicas: 2
    template:
    metadata:
    labels:
    app: web-deploy
    spec:
    containers:
    - name: web-deploy
    image: tomcat:8-slim
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: nfs-volume
    mountPath: "/tomcat-data"
    readOnly: false
    volumes:
    - name: nfs-volume
    persistentVolumeClaim:
    claimName: nfs-pvc # pvc的名称

    然后exec进去一个pod到/tomcat-data目录下添加编辑文件,然后去另一个pod/data/nfs下查看

添加静态的pv&pvc

  • nfs_pv.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    apiVersion: v1
    kind: PersistentVolume
    metadata:
    name: nfspv1
    spec:
    #指定pv的容量为1Gi
    capacity:
    storage: 1Gi
    #指定访问模式
    accessModes:
    #pv能以readwrite模式mount到单个节点
    - ReadWriteOnce
    #指定pv的回收策略,即pvc资源释放后的事件.recycle(不建议,使用动态供给代替)删除pvc的所有文件
    persistentVolumeReclaimPolicy: Recycle
    #指定pv的class为nfs,相当于为pv分类,pvc将指定class申请pv
    storageClassName: mynfs
    #指定pv为nfs服务器上对应的目录
    nfs:
    path: /data/nfs
    server: 10.0.0.201
  • nfs_pvc.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
    name: nfspvc1
    spec:
    accessModes:
    - ReadWriteOnce
    resources:
    requests:
    storage: 1Gi
    storageClassName: mynfs