第 10 章 存储:为什么文件会消失
三种生命周期
容器可写层里的文件依附于该容器实例。容器重建时,不应指望这些修改保留。emptyDir 卷跟随 Pod 生命周期,在同一 Pod 内的容器重启后可继续使用,但 Pod 删除后数据通常就消失。持久卷则用来把数据生命周期与单个 Pod 分离。
PersistentVolume(PV)代表集群中的一份存储资源。PersistentVolumeClaim(PVC)代表应用申请存储的请求。StorageClass 描述动态供应存储的类别和参数。你可以把它们理解为仓库空间、租用申请和租赁规格。
PVC 不是备份。存储所在磁盘、节点或整个本地集群被删除时,数据仍可能丢失。尤其在 kind 中,即使 PVC 叫“持久”,删除节点容器也可能让底层数据一并消失。
一个独立的存储实验
先检查是否有默认 StorageClass:
kubectl get storageclass如果没有标为默认的 StorageClass,下面省略 storageClassName 的申请可能一直 Pending。此时先了解所用环境的存储供应方式,不要为了让状态变绿随便填写一个名字。kind 常提供本地存储供应,但应以实际输出为准。
保存为 storage.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: notes
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: notes-writer
spec:
containers:
- name: tools
image: busybox:1.37
command: ["sh", "-c", "sleep 86400"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: notes一个文件中可以用 --- 分隔多个对象。ReadWriteOnce 通常表示卷可被单个节点以读写方式挂载,不代表永远只允许一个 Pod 访问,具体还取决于存储实现。
kubectl apply -n k8s-book -f storage.yaml
kubectl wait -n k8s-book --for=condition=Ready pod/notes-writer --timeout=120s
kubectl exec -n k8s-book notes-writer -- sh -c 'echo hello-storage > /data/note.txt'
kubectl exec -n k8s-book notes-writer -- cat /data/note.txt
kubectl delete pod notes-writer -n k8s-book
kubectl apply -n k8s-book -f storage.yaml
kubectl wait -n k8s-book --for=condition=Ready pod/notes-writer --timeout=120s
kubectl exec -n k8s-book notes-writer -- cat /data/note.txt最后应仍能读到 hello-storage,因为你删除的是 Pod,PVC 还在。本轮 CI 用相同 PVC UID、不同 Pod UID 和实际读回文件验证这一点;没有删除 kind 节点或恢复整个集群,因此不能据此推断节点丢失后的数据恢复能力。动态供应使用 WaitForFirstConsumer 时,PVC 在使用它的 Pod 创建前保持 Pending 也可能正常。
若没有按预期启动,查看 kubectl describe pvc notes -n k8s-book 与 Pod 事件。清理时 kubectl delete -n k8s-book -f storage.yaml 会同时删除 Pod 和 PVC;回收策略为 Delete 时,底层卷也可能被删除,请先确认不需要数据。
数据库应该怎样学
StatefulSet 为有状态工作负载提供稳定身份、顺序和卷关联,但不会自动替你完成数据库复制、故障恢复和备份。新手先把网站应用作为无状态服务,把数据库可靠性作为单独专题学习。
本章自测:容器重启和 Pod 删除对 emptyDir 的影响相同吗?PVC 为什么不能代替备份?