Skip to content
On this page

k8s学习笔记(5)——Volume

一、定义

Pod的生命周期是短暂的,会被销毁和创建,当Pod被销毁的时候,其相关容器内部的文件也会消失。如果需要持久化保存一些数据,就需要使用Volume。

Kubernetes对Volume做了抽象,事实上的Volume存储后端可以是主机上的一个目录,Ceph存储,公有云等(具体可参考 Types of Volumes)。但是对于Pod来说,Volume就是一个目录,当挂在了一个Volume之后,Pod内的所有容器都能使用。

Pod的.spec.volumes定义了Volume,.spec.containers.volumeMounts定义了Volume的挂载路径。

二、empytDir

emptyDir是最基础的一种Volume,伴随着Pod的创建而创建,当Pod被删除的时候,emptyDir也会被删除。也就是说,emptyDir与Pod的生命周期一致。

下面是一个简单的例子:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: producer-consumer
spec:
  containers:
  - image: busybox
    name: producer
    volumeMounts:
    - mountPath: /producer_dir
      name: shared-volume
    args:
    - /bin/sh
    - -c
    - echo "hello world" > /producer_dir/hello; sleep 30000

  - image: busybox
    name: consumer
    volumeMounts:
    - mountPath: /consumer_dir
      name: shared-volume
    args:
    - /bin/sh
    - -c
    - cat /consumer_dir/hello; sleep 30000

  volumes:
  - name: shared-volume
  	emptyDir: {}

三、hostPath

hostPath是将主机上的一个目录作为Volume挂载到Pod上。例如上面的例子中,将.spec.volumes修改如下:

yaml
spec:
  volumes:
  - name: shared-volume
    hostPath:
      path: /Users/xxx/Desktop/data

重新apply后,即可在主机对应的目录下看到创建的文件。

四、PV和PVC

通常情况下,系统管理员负责存储的创建,而应用开发人员不关心存储的创建和管理,只关心如何使用存储空间。PV(Persistent Volume)和PVC(Persistent Volume Claim)很好地将存储的分配和使用进行了解耦。

PV定义了一块外部的存储空间,它的生命周期独立于Pod的生命周期。PVC是对PV的申请,当一个Pod需要使用存储的时候,会创建一个PVC。

k8s支持多种类型的PV,具体可以参考 Types of Persistent Volumes

下面是一个使用本地存储的例子:

pv.yml:

yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-storage
  local:
    path: /Users/xxx/Desktop/data
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - docker-for-desktop

pvc.yml:

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc0001
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: local-storage
  resources:
    requests:
      storage: 1Gi

pod.yml

yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod0001
spec:
  containers:
  - image: busybox
    name: busybox
    volumeMounts:
    - mountPath: /data
      name: data-volume
    args:
    - /bin/sh
    - -c
    - echo "hello world" > /data/hello; sleep 30000

  volumes:
  - name: data-volume
    persistentVolumeClaim:
      claimName: pvc0001

执行

sh
$ kubectl apply -f pv.yml
$ kubectl apply -f pvc.yml
$ kubectl apply -f pod.yml

这将会在对应的主机目录下生成hello文件。