将 PersistentVolume 的访问模式更改为 ReadWriteOncePod
本文演示了如何将现有 PersistentVolume 的访问模式更改为使用 ReadWriteOncePod
。
准备开始
你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:
你的 Kubernetes 服务器版本必须不低于版本 v1.22. 要获知版本信息,请输入 kubectl version
.
说明:
ReadWriteOncePod
访问模式在 Kubernetes v1.29 版本中已进阶至 Stable。 如果你运行的 Kubernetes 版本早于 v1.29,你可能需要启用一个特性门控。 请查阅你所用 Kubernetes 版本的文档。
说明:
ReadWriteOncePod
访问模式仅支持 CSI 卷。 要使用这种卷访问模式,你需要更新以下 CSI 边车至下述版本或更高版本:
我为什么要使用 ReadWriteOncePod
?
在 Kubernetes v1.22 之前,ReadWriteOnce
访问模式通常用于限制需要单个写者存储访问模式的工作负载对 PersistentVolume 的访问。 然而,这种访问模式有一个限制:它要求只能从单个节点上访问卷,但允许同一节点上的多个 Pod 同时读写同一个卷。 对于需要严格遵循单个写者访问模式以确保数据安全的应用,这种模式可能形成风险。
如果确保单个写者访问模式对于你的工作负载至关重要,请考虑将你的卷迁移到 ReadWriteOncePod
。
迁移现有 PersistentVolume
如果你有一些 PersistentVolume,可以将它们迁移为使用 ReadWriteOncePod
。 系统仅支持从 ReadWriteOnce
迁移到 ReadWriteOncePod
。
在此示例中,已经有一个 ReadWriteOnce
的 “cat-pictures-pvc” PersistentVolumeClaim 被绑定到了 “cat-pictures-pv” PersistentVolume,还有一个使用此 PersistentVolumeClaim 的 “cat-pictures-writer” Deployment。
说明:
如果你的存储插件支持动态制备, 系统将为你创建 “cat-pictures-pv”,但其名称可能不同。 要获取你的 PersistentVolume 的名称,请运行以下命令:
kubectl get pvc cat-pictures-pvc -o jsonpath='{.spec.volumeName}'
你可以在进行更改之前查看 PVC。你可以在本地查看清单, 或运行 kubectl get pvc <PVC 名称> -o yaml
。这条命令的输出类似于:
# cat-pictures-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: cat-pictures-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
以下是一个依赖于此 PersistentVolumeClaim 的 Deployment 示例:
# cat-pictures-writer-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: cat-pictures-writer
spec:
replicas: 3
selector:
matchLabels:
app: cat-pictures-writer
template:
metadata:
labels:
app: cat-pictures-writer
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- name: cat-pictures
mountPath: /mnt
volumes:
- name: cat-pictures
persistentVolumeClaim:
claimName: cat-pictures-pvc
readOnly: false
第一步,你需要编辑 PersistentVolume 的 spec.persistentVolumeReclaimPolicy
并将其设置为 Retain
。此字段确保你在删除相应的 PersistentVolumeClaim 时不会删除 PersistentVolume:
kubectl patch pv cat-pictures-pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
接下来,你需要停止正在使用绑定到你要迁移的这个 PersistentVolume 上的 PersistentVolumeClaim 的所有工作负载,然后删除该 PersistentVolumeClaim。 在迁移完成之前,不要对 PersistentVolumeClaim 进行任何其他更改,例如调整卷的大小。
完成后,你需要清除 PersistentVolume 的 spec.claimRef.uid
以确保在重新创建时 PersistentVolumeClaim 能够绑定到它:
kubectl scale --replicas=0 deployment cat-pictures-writer
kubectl delete pvc cat-pictures-pvc
kubectl patch pv cat-pictures-pv -p '{"spec":{"claimRef":{"uid":""}}}'
之后,将 PersistentVolume 的有效访问模式列表替换为(仅)ReadWriteOncePod
:
kubectl patch pv cat-pictures-pv -p '{"spec":{"accessModes":["ReadWriteOncePod"]}}'
说明:
ReadWriteOncePod
访问模式不能与其他访问模式结合使用。 你要确保在更新时 ReadWriteOncePod
是 PersistentVolume 上的唯一访问模式,否则请求将失败。
接下来,你需要修改 PersistentVolumeClaim,将 ReadWriteOncePod
设置为唯一的访问模式。 你还应将 PersistentVolumeClaim 的 spec.volumeName
设置为 PersistentVolume 的名称, 以确保其绑定到特定的 PersistentVolume。
完成后,你可以重新创建你的 PersistentVolumeClaim 并启动你的工作负载:
# 重要提示:在 apply 操作之前必须编辑在 cat-pictures-pvc.yaml 中的 PVC。你需要:
# - 将 ReadWriteOncePod 设置为唯一的访问模式
# - 将 spec.volumeName 设置为 "cat-pictures-pv"
kubectl apply -f cat-pictures-pvc.yaml
kubectl apply -f cat-pictures-writer-deployment.yaml
最后,你可以编辑 PersistentVolume 的 spec.persistentVolumeReclaimPolicy
并将其设置回 Delete
, 如果你之前更改了这个字段的话。
kubectl patch pv cat-pictures-pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Delete"}}'
接下来
- 进一步了解 PersistentVolume。
- 进一步了解 PersistentVolumeClaim。
- 进一步了解配置 Pod 以使用 PersistentVolume 作为存储。