一、定义
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的生命周期一致。
下面是一个简单的例子:
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
修改如下:
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:
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:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc0001
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-storage
resources:
requests:
storage: 1Gi
pod.yml
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
执行
$ kubectl apply -f pv.yml
$ kubectl apply -f pvc.yml
$ kubectl apply -f pod.yml
这将会在对应的主机目录下生成hello文件。