kubernetes存储详解

1. Volumes

1.1. volume概述

  • 容器上的文件生命周期同容器的生命周期一致,即容器挂掉之后,容器将会以最初镜像中的文件系统内容启动,之前容器运行时产生的文件将会丢失。
  • Pod的volume的生命周期同Pod的生命周期一致,当Pod被删除的时候,对应的volume才会被删除。即Pod中的容器重启时,之前的文件仍可以保存。

容器中的进程看到的是由其 Docker 镜像和卷组成的文件系统视图。

Pod volume的使用方式

Pod 中的每个容器都必须独立指定每个卷的挂载位置,需要给Pod配置volume相关参数。

Pod的volume关键字段如下:

  • spec.volumes:提供怎样的数据卷
  • spec.containers.volumeMounts:挂载到容器的什么路径

1.2. volume类型

1.2.1. emptyDir

1、特点

  • 会创建emptyDir对应的目录,默认为空(如果该目录原来有文件也会被重置为空)
  • Pod中的不同容器可以在目录中读写相同文件(即Pod中的不同容器可以通过该方式来共享文件)
  • 当Pod被删除,emptyDir 中的数据将被永久删除,如果只是Pod挂掉该数据还会保留

2、使用场景

  • 不同容器之间共享文件(例如日志采集等)
  • 暂存空间,例如用于基于磁盘的合并排序
  • 用作长时间计算崩溃恢复时的检查点

    3、示例

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
1.2.2. hostPath

1、特点

  • 会将宿主机的目录或文件挂载到Pod中

2、使用场景

  • 运行需要访问 Docker 内部的容器;使用 /var/lib/dockerhostPath

  • 在容器中运行 cAdvisor;使用 /dev/cgroupshostPath

  • 其他使用到宿主机文件的场景

hostPathtype字段

行为
空字符串(默认)用于向后兼容,这意味着在挂载 hostPath 卷之前不会执行任何检查。
DirectoryOrCreate如果在给定的路径上没有任何东西存在,那么将根据需要在那里创建一个空目录,权限设置为 0755,与 Kubelet 具有相同的组和所有权。
Directory给定的路径下必须存在目录
FileOrCreate如果在给定的路径上没有任何东西存在,那么会根据需要创建一个空文件,权限设置为 0644,与 Kubelet 具有相同的组和所有权。
File给定的路径下必须存在文件
Socket给定的路径下必须存在 UNIX 套接字
CharDevice给定的路径下必须存在字符设备
BlockDevice给定的路径下必须存在块设备

注意事项

  • 由于每个节点上的文件都不同,具有相同配置的 pod 在不同节点上的行为可能会有所不同
  • 当 Kubernetes 按照计划添加资源感知调度时,将无法考虑 hostPath 使用的资源
  • 在底层主机上创建的文件或目录只能由 root 写入。您需要在特权容器中以 root 身份运行进程,或修改主机上的文件权限以便写入 hostPath

3、示例

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory
1.2.3. configMap

configMap提供了一种给Pod注入配置文件的方式,配置文件内容存储在configMap对象中,如果Pod使用configMap作为volume的类型,需要先创建configMap的对象。

示例

apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: busybox
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: log-config
        items:
          - key: log_level
            path: log_level
1.2.4. cephfs

cephfs的方式将Pod的存储挂载到ceph集群中,通过外部存储的方式持久化Pod的数据(即当Pod被删除数据仍可以存储在ceph集群中),前提是先部署和维护好一个ceph集群。

示例

apiVersion: v1
kind: Pod
metadata:
  name: cephfs
spec:
  containers:
  - name: cephfs-rw
    image: kubernetes/pause
    volumeMounts:
    - mountPath: "/mnt/cephfs"
      name: cephfs
  volumes:
  - name: cephfs
    cephfs:
      monitors:
      - 10.16.154.78:6789
      - 10.16.154.82:6789
      - 10.16.154.83:6789
      # by default the path is /, but you can override and mount a specific path of the filesystem by using the path attribute
      # path: /some/path/in/side/cephfs 
      user: admin
      secretFile: "/etc/ceph/admin.secret"
      readOnly: true

更多可参考 CephFS 示例

1.2.5. nfs

nfs的方式类似cephfs,即将Pod数据存储到NFS集群中,具体可参考NFS示例

1.2.6. persistentVolumeClaim

persistentVolumeClaim 卷用于将PersistentVolume挂载到容器中。PersistentVolumes 是在用户不知道特定云环境的细节的情况下“声明”持久化存储(例如 GCE PersistentDisk 或 iSCSI 卷)的一种方式。

2. PersistentVolume

2.1. PV概述

PersistentVolume(简称PV) 是 Volume 之类的卷插件,也是集群中的资源,但独立于Pod的生命周期(即不会因Pod删除而被删除),不归属于某个Namespace。

2.2. PV和PVC的生命周期

2.2.1. 配置(Provision)

有两种方式来配置 PV:静态或动态。

1、静态

手动创建PV,可供k8s集群中的对象消费。

2、动态

可以通过StorageClass和具体的Provisioner(例如nfs-client-provisioner)来动态地创建和删除PV。

2.2.2. 绑定

在动态配置的情况下,用户创建了特定的PVC,k8s会监听新的PVC,并寻找匹配的PV绑定。一旦绑定后,这种绑定是排他性的,PVC和PV的绑定是一对一的映射。

2.2.3. 使用

Pod 使用PVC作为卷。集群检查PVC以查找绑定的卷并为集群挂载该卷。用户通过在 Pod 的 volume 配置中包含 persistentVolumeClaim 来调度 Pod 并访问用户声明的 PV。

2.2.4. 回收

PV的回收策略可以设定PVC在释放后如何处理对应的Volume,目前有 RetainedRecycledDeleted三种策略。

1、保留(Retain)

保留策略允许手动回收资源,当删除PVC的时候,PV仍然存在,可以通过以下步骤回收卷:

  1. 删除PV
  2. 手动清理外部存储的数据资源
  3. 手动删除或重新使用关联的存储资产

2、回收(Resycle)

该策略已废弃,推荐使用dynamic provisioning

回收策略会在 volume上执行基本擦除(rm -rf / thevolume / *),可被再次声明使用。

3、删除(Delete)

删除策略,当发生删除操作的时候,会从k8s集群中删除PV对象,并执行外部存储资源的删除操作(根据不同的provisioner定义的删除逻辑不同,有的是重命名)。

动态配置的卷继承其StorageClass的回收策略,默认为Delete,即当用户删除PVC的时候,会自动执行PV的删除策略。

如果要修改PV的回收策略,可执行以下命令:

# Get pv 
kubectl get pv
# Change policy to Retaion
kubectl patch pv <pv_name> -p ‘{“spec”:{“persistentVolumeReclaimPolicy”:“Retain”}}’

2.3. PV的类型

PersistentVolume 类型以插件形式实现。以下仅列部分常用类型:

  • GCEPersistentDisk
  • AWSElasticBlockStore

  • NFS

  • RBD (Ceph Block Device)
  • CephFS
  • Glusterfs

2.4. PV的属性

每个PV 配置中都包含一个 sepc规格字段和一个 status 卷状态字段。

apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: fuseim.pri/ifs
  creationTimestamp: 2018-07-12T06:46:48Z
  name: default-test-web-0-pvc-58cf5ec1-859f-11e8-bb61-005056b83985
  resourceVersion: "100163256"
  selfLink: /api/v1/persistentvolumes/default-test-web-0-pvc-58cf5ec1-859f-11e8-bb61-005056b83985
  uid: 59796ba3-859f-11e8-9c50-c81f66bcff65
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 2Gi
  volumeMode: Filesystem  
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: test-web-0
    namespace: default
    resourceVersion: "100163248"
    uid: 58cf5ec1-859f-11e8-bb61-005056b83985
  nfs:
    path: /data/nfs-storage/default-test-web-0-pvc-58cf5ec1-859f-11e8-bb61-005056b83985
    server: 172.16.201.54
  persistentVolumeReclaimPolicy: Delete
  storageClassName: managed-nfs-storage
  mountOptions:
    - hard
    - nfsvers=4.1
status:
  phase: Bound
2.4.1. Capacity

给PV设置特定的存储容量,更多 capacity 可参考Kubernetes 资源模型 。

2.4.2. Volume Mode

 volumeMode 的有效值可以是FilesystemBlock。如果未指定,volumeMode 将默认为Filesystem

2.4.3. Access Modes

访问模式包括:

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

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

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

一个卷一次只能使用一种访问模式挂载,即使它支持很多访问模式。

以下只列举部分常用插件:

Volume 插件ReadWriteOnceReadOnlyManyReadWriteMany
AWSElasticBlockStore--
CephFS
GCEPersistentDisk-
Glusterfs
HostPath--
NFS
RBD-
2.4.4. Class

PV可以指定一个StorageClass来动态绑定PV和PVC,其中通过 storageClassName 属性来指定具体的StorageClass,如果没有指定该属性的PV,它只能绑定到不需要特定类的 PVC。

2.4.5. Reclaim Policy

回收策略包括:

  • Retain(保留)——手动回收
  • Recycle(回收)——基本擦除(rm -rf /thevolume/*
  • Delete(删除)——关联的存储资产(例如 AWS EBS、GCE PD、Azure Disk 和 OpenStack Cinder 卷)将被删除

当前,只有 NFS 和 HostPath 支持回收策略。AWS EBS、GCE PD、Azure Disk 和 Cinder 卷支持删除策略。

2.4.6. Mount Options

Kubernetes 管理员可以指定在节点上为挂载持久卷指定挂载选项。

注意:不是所有的持久化卷类型都支持挂载选项。

支持挂载选项常用的类型有:

  • GCEPersistentDisk
  • AWSElasticBlockStore
  • AzureFile
  • AzureDisk
  • NFS
  • RBD (Ceph Block Device)
  • CephFS
  • Cinder (OpenStack 卷存储)
  • Glusterfs
2.4.7. Phase

PV可以处于以下的某种状态:

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

命令行会显示绑定到 PV 的 PVC 的名称。

3. PersistentVolumeClaim

3.1. PVC概述

PersistentVolumeClaim(简称PVC)是用户存储的请求,PVC消耗PV的资源,可以请求特定的大小和访问模式,需要指定归属于某个Namespace,在同一个Namespace的Pod才可以指定对应的PVC。

当需要不同性质的PV来满足存储需求时,可以使用StorageClass来实现。

每个 PVC 中都包含一个 spec 规格字段和一个 status 声明状态字段。

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

3.1. PVC的属性

3.1.1. accessModes

对应存储的访问模式,例如:ReadWriteOnce

3.1.2. volumeMode

对应存储的数据卷模式,例如:Filesystem

3.1.3. resources

声明可以请求特定数量的资源。相同的资源模型适用于Volume和PVC。

3.1.4. selector

声明label selector,只有标签与选择器匹配的卷可以绑定到声明。

  • matchLabels:volume 必须有具有该值的标签
  • matchExpressions:条件列表,通过条件表达式筛选匹配的卷。有效的运算符包括 In、NotIn、Exists 和 DoesNotExist。
3.1.5. storageClassName

通过storageClassName参数来指定使用对应名字的StorageClass,只有所请求的类与 PVC 具有相同 storageClassName 的 PV 才能绑定到 PVC。

PVC可以不指定storageClassName,或者将该值设置为空,如果打开了准入控制插件,并且指定一个默认的 StorageClass,则PVC会使用默认的StorageClass,否则就绑定到没有StorageClass的 PV上。

之前使用注解 volume.beta.kubernetes.io/storage-class 而不是 storageClassName 属性。这个注解仍然有效,但是在未来的 Kubernetes 版本中不会支持。

3.2. 将PVC作为Volume

将PVC作为Pod的Volume,PVC与Pod需要在同一个命名空间下,其实Pod的声明如下:

kind: Pod
apiVersion: v1
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: dockerfile/nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:    # 使用PVC
        claimName: myclaim

PersistentVolumes 绑定是唯一的,并且由于 PersistentVolumeClaims 是命名空间对象,因此只能在一个命名空间内挂载具有“多个”模式(ROXRWX)的PVC。

4. StorageClass

4.1. StorageClass概述

StorageClass提供了一种描述存储类(class)的方法,不同的class可能会映射到不同的服务质量等级和备份策略或其他策略等。

StorageClass 对象中包含 provisionerparameters 和 reclaimPolicy 字段,当需要动态分配 PersistentVolume 时会使用到。当创建 StorageClass 对象时,设置名称和其他参数,一旦创建了对象就不能再对其更新。也可以为没有申请绑定到特定 class 的 PVC 指定一个默认的 StorageClass 。

StorageClass对象文件

kind: StorageClass
apiVersion: storage.k8s.io/v3
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Retain
mountOptions:
  - debug

4.2. StorageClass的属性

4.2.1. Provisioner(存储分配器)

Storage class 有一个分配器(provisioner),用来决定使用哪个卷插件分配 PV,该字段必须指定。可以指定内部分配器,也可以指定外部分配器。外部分配器的代码地址为: kubernetes-incubator/external-storage,其中包括NFSCeph等。

4.2.2. Reclaim Policy(回收策略)

可以通过reclaimPolicy字段指定创建的Persistent Volume的回收策略,回收策略包括:Delete 或者 Retain,没有指定默认为Delete

4.2.3. Mount Options(挂载选项)

由 storage class 动态创建的 Persistent Volume 将使用 class 中 mountOptions 字段指定的挂载选项。

4.2.4. 参数

Storage class 具有描述属于 storage class 卷的参数。取决于分配器,可以接受不同的参数。 当参数被省略时,会使用默认值。

例如以下使用Ceph RBD

kind: StorageClass
apiVersion: storage.k8s.io/v3
metadata:
  name: fast
provisioner: kubernetes.io/rbd
parameters:
  monitors: 30.36.353.305:6789
  adminId: kube
  adminSecretName: ceph-secret
  adminSecretNamespace: kube-system
  pool: kube
  userId: kube
  userSecretName: ceph-secret-user
  fsType: ext4
  imageFormat: "2"
  imageFeatures: "layering"

对应的参数说明

  • monitors:Ceph monitor,逗号分隔。该参数是必需的。

  • adminId:Ceph 客户端 ID,用于在池(ceph pool)中创建映像。 默认是 “admin”。

  • adminSecretNamespace:adminSecret 的 namespace。默认是 “default”。

  • adminSecret:adminId 的 Secret 名称。该参数是必需的。 提供的 secret 必须有值为 “kubernetes.io/rbd” 的 type 参数。

  • pool: Ceph RBD 池. 默认是 “rbd”。

  • userId:Ceph 客户端 ID,用于映射 RBD 镜像(RBD image)。默认与 adminId 相同。

  • userSecretName:用于映射 RBD 镜像的 userId 的 Ceph Secret 的名字。 它必须与 PVC 存在于相同的 namespace 中。该参数是必需的。 提供的 secret 必须具有值为 “kubernetes.io/rbd” 的 type 参数,例如以这样的方式创建:

    kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \
    --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \
    --namespace=kube-system
  • fsType:Kubernetes 支持的 fsType。默认:”ext4”。

  • imageFormat:Ceph RBD 镜像格式,”1” 或者 “2”。默认值是 “1”。

  • imageFeatures:这个参数是可选的,只能在你将 imageFormat 设置为 “2” 才使用。 目前支持的功能只是 layering。 默认是 ““,没有功能打开。

5. Dynamic Volume Provisioning

Dynamic volume provisioning允许用户按需自动创建存储卷,这种方式可以让用户不需要关心存储的复杂性和差别,又可以选择不同的存储类型。

5.1. 开启Dynamic Provisioning

需要先提前创建StorageClass对象,StorageClass中定义了使用哪个provisioner,并且在provisioner被调用时传入哪些参数,具体可参考StorageClass介绍。

例如:

  • 磁盘类存储
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-standard
  • SSD类存储
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd

5.2. 使用Dynamic Provisioning

创建一个PVC对象,并且在其中storageClassName字段指明需要用到的StorageClass的名称,例如:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim1
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast
  resources:
    requests:
      storage: 30Gi

当使用到PVC的时候会自动创建对应的外部存储,当PVC被删除的时候,会自动销毁(或备份)外部存储。

5.3. 默认的StorageClass

当没有对应的StorageClass配置时,可以设定默认的StorageClass,需要执行以下操作:

可以通过添加storageclass.kubernetes.io/is-default-class注解的方式设置某个StorageClass为默认的StorageClass。当用户创建了一个PersistentVolumeClaim,但没有指定storageClassName的时候,会自动将该PVC的storageClassName指向默认的StorageClass

参考文章:

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值