第 11 / 18 篇

第 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 为什么不能代替备份?