概述

PersistentVolume

  1. Pod 里的容器由镜像产生,镜像文件本身是只读的,进程要读写磁盘需要一个临时的存储空间
    • 一旦 Pod 销毁,临时存储会被立即释放,数据也就丢失了
  2. PersistentVolume
    • 用来表示持久存储设备,隐藏了存储的底层实现
    • PersistentVolume 实际是一些存储设备文件系统,如 Ceph、GlusterFS、NFS、本地磁盘
    • PersistentVolume 是属于集群的系统资源,是和 Node 平级的对象,Pod 只有使用权

PersistentVolumeClaim + StorageClass

PersistentVolumeClaim 和 StorageClass 是 Pod 与 PersistentVolume 之间的中间层

  1. PodPersistentVolumeClaim 来向 Kubernetes 申请存储资源
  2. bind:一旦资源申请成功,Kubernetes 会把 PVPVC 关联在一起
  3. StorageClass 类似于 IngressClass,抽象了特定类型的存储系统
    • 在 PVC 和 PV 之间充当协调人的角色,帮助 PVC 找到合适的 PV

image-20230625212036873

HostPath

HostPath 一般用于 DaemonSet,如 Fluentd 等

1
2
3
4
5
6
$ k api-resources --api-group=""
NAME SHORTNAMES APIVERSION NAMESPACED KIND
...
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
...

PersistentVolume

访问模式:由于存储系统级别的概念,被限制的对象为 Node,而非 Pod

Mode Desc
ReadWriteOnce 存储卷可读可写,但只能被一个 Node 上的 Pod 挂载
ReadOnlyMany 存储卷只读不可写,可以被任意 Node 上的 Pod 多次挂载
ReadWriteMany 存储卷可读可写,可以被任意 Node 上的 Pod 多次挂载
ReadWriteOncePod Kubernetes 1.27
存储卷可读可写,但只能被一个 Pod 上的 Pod 挂载
pv.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: PersistentVolume
metadata:
name: host-10m-pv

spec:
storageClassName: host-test
accessModes:
- ReadWriteOnce
capacity:
storage: 10Mi
hostPath:
path: /tmp/host-10m-pv
1
2
3
4
5
6
$ k apply -f pv.yaml
persistentvolume/host-10m-pv created

$ k get pv -owide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
host-10m-pv 10Mi RWO Retain Available host-test 40s Filesystem

PersistentVolumeClaim

Kubernetes 会根据 PVC 的描述,去找能够匹配 StorageClassCapacity 等条件的 PV

pvc.yaml
1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: host-5m-pvc

spec:
storageClassName: host-test
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Mi

PVC 对象一旦创建成功,Kubernetes 会立即通过 StorageClass、resources 等条件在集群内寻找并绑定匹配的 PV

1
2
3
4
5
6
7
8
9
10
$ k apply -f pvc.yaml
persistentvolumeclaim/host-5m-pvc created

$ k get pvc -owide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
host-5m-pvc Bound host-10m-pv 10Mi RWO host-test 70s Filesystem

$ k get pv -owide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
host-10m-pv 10Mi RWO Retain Bound default/host-5m-pvc host-test 4m58s Filesystem

修改 PVC 的预期为 100Mi,PVC 会一直处于 Pending 状态(因为没有找到符合要求的 PV)

1
2
3
4
5
6
7
$ k get pvc -owide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
host-100m-pvc Pending host-test 4s Filesystem

$ k get pv -owide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
host-10m-pv 10Mi RWO Retain Available host-test 22s Filesystem

Pod

nginx.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Pod
metadata:
name: host-pvc-pod

spec:
volumes:
- name: host-pvc-vol
persistentVolumeClaim:
claimName: host-5m-pvc
containers:
- name: nginx-pvc-pod
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: host-pvc-vol
mountPath: /tmp

image-20230626175201216

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ k apply -f nginx.yaml
pod/host-pvc-pod created

$ k get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
host-pvc-pod 1/1 Running 0 33s 10.10.1.55 mac-worker <none> <none>

$ k exec -it host-pvc-pod -- sh
/ # cd /tmp/
/tmp # echo zhongmingmao > name.txt
/tmp # cat name.txt
zhongmingmao
/tmp # exit

$ k get no -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
mac-master Ready control-plane,master 9d v1.23.3 192.168.191.144 <none> Ubuntu 22.04.2 LTS 5.15.0-75-generic docker://24.0.2
mac-worker Ready <none> 8d v1.23.3 192.168.191.146 <none> Ubuntu 22.04.2 LTS 5.15.0-75-generic docker://20.10.24

登录 mac-worker

1
2
$ cat /tmp/host-10m-pv/name.txt
zhongmingmao

重建 Pod,当前集群只有一个 Worker 节点,能重新获取到之前的数据,实现了简单的数据持久化

1
2
3
4
5
6
7
8
$ k delete -f nginx.yaml
pod "host-pvc-pod" deleted

$ k apply -f nginx.yaml
pod/host-pvc-pod created

$ k exec -it host-pvc-pod -- cat /tmp/name.txt
zhongmingmao

emptyDir 的生命周期与 Pod 相同(比容器长),非持久化存储,可以用作缓存