kubernetes-handbook/concepts/volume.md

5.5 KiB
Raw Blame History

Kubernetes存储卷

我们知道默认情况下容器的数据都是非持久化的在容器消亡以后数据也跟着丢失所以Docker提供了Volume机制以便将数据持久化存储。类似的Kubernetes提供了更强大的Volume机制和丰富的插件解决了容器数据持久化和容器间共享数据的问题。

Volume

目前Kubernetes支持以下Volume类型

  • emptyDir
  • hostPath
  • gcePersistentDisk
  • awsElasticBlockStore
  • nfs
  • iscsi
  • flocker
  • glusterfs
  • rbd
  • cephfs
  • gitRepo
  • secret
  • persistentVolumeClaim
  • downwardAPI
  • azureFileVolume
  • vsphereVolume
  • flexvolume

注意这些volume并非全部都是持久化的比如emptyDir、secret、gitRepo等这些volume会随着Pod的消亡而消失。

PersistentVolume

对于持久化的VolumePersistentVolume (PV)和PersistentVolumeClaim (PVC)提供了更方便的管理卷的方法PV提供网络存储资源而PVC请求存储资源。这样设置持久化的工作流包括配置底层文件系统或者云数据卷、创建持久性数据卷、最后创建claim来将pod跟数据卷关联起来。PV和PVC可以将pod和数据卷解耦pod不需要知道确切的文件系统或者支持它的持久化引擎。

PV

PersistentVolumePV是集群之中的一块网络存储。跟 Node 一样也是集群的资源。PV 跟 Volume (卷) 类似,不过会有独立于 Pod 的生命周期。比如一个NFS的PV可以定义为

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /tmp
    server: 172.17.0.2

PV的访问模式有三种

  • 第一种ReadWriteOnce是最基本的方式可读可写但只支持被单个Pod挂载。
  • 第二种ReadOnlyMany可以以只读的方式被多个Pod挂载。
  • 第三种ReadWriteMany这种存储可以以读写的方式被多个Pod共享。不是每一种存储都支持这三种方式像共享方式目前支持的还比较少比较常用的是NFS。在PVC绑定PV时通常根据两个条件来绑定一个是存储的大小另一个就是访问模式。

StorageClass

上面通过手动的方式创建了一个NFS Volume这在管理很多Volume的时候不太方便。Kubernetes还提供了StorageClass来动态创建PV不仅节省了管理员的时间还可以封装不同类型的存储供PVC选用。

GCE的例子

kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
  name: slow
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-standard
  zone: us-central1-a

Ceph RBD的例子

apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/rbd
parameters:
  monitors: 10.16.153.105:6789
  adminId: kube
  adminSecretName: ceph-secret
  adminSecretNamespace: kube-system
  pool: kube
  userId: kube
  userSecretName: ceph-secret-user

PVC

PV是存储资源而PersistentVolumeClaim (PVC) 是对PV的请求。PVC跟Pod类似Pod消费Node的源而PVC消费PV资源Pod能够请求CPU和内存资源而PVC请求特定大小和访问模式的数据卷。

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

PVC可以直接挂载到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:
        claimName: myclaim

emptyDir

如果Pod配置了emptyDir类型Volume Pod 被分配到Node上时候会创建emptyDir只要Pod运行在Node上emptyDir都会存在容器挂掉不会导致emptyDir丢失数据但是如果Pod从Node上被删除Pod被删除或者Pod发生迁移emptyDir也会被删除并且永久丢失。

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data

其他Volume说明

hostPath

hostPath允许挂载Node上的文件系统到Pod里面去。如果Pod有需要使用Node上的文件可以使用hostPath。

- hostPath:
    path: /tmp/data
    name: data

NFS

NFS 是Network File System的缩写即网络文件系统。Kubernetes中通过简单地配置就可以挂载NFS到Pod中而NFS中的数据是可以永久保存的同时NFS支持同时写操作。

volumes:
- name: nfs
  nfs:
    # FIXME: use the right hostname
    server: 10.254.234.223
    path: "/"

FlexVolume

注意要把volume plugin放到/usr/libexec/kubernetes/kubelet-plugins/volume/exec/<vendor~driver>/<driver>plugin要实现init/attach/detach/mount/umount等命令可参考lvm的示例)。

  - name: test
    flexVolume:
      driver: "kubernetes.io/lvm"
      fsType: "ext4"
      options:
        volumeID: "vol1"
        size: "1000m"
        volumegroup: "kube_vg"