将 PersistentVolume 的访问模式更改为 ReadWriteOncePod
本页展示了如何更改现有 PersistentVolume 的访问模式,使其使用 ReadWriteOncePod。
开始之前
你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具已配置为与你的集群通信。建议在至少有两个非控制平面主机的节点集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者使用以下 Kubernetes 练兵场之一
你的 Kubernetes 服务器版本必须是 v1.22 或更高版本。要检查版本,输入 kubectl version。
注意
ReadWriteOncePod 访问模式在 Kubernetes v1.29 版本中已转为稳定。如果你运行的 Kubernetes 版本低于 v1.29,你可能需要启用一个特性门控。请查看你所用 Kubernetes 版本的文档。注意
ReadWriteOncePod 访问模式仅支持 CSI 卷。要使用此卷访问模式,你需要将以下 CSI sidecar 容器 更新到这些版本或更高版本
为什么要使用 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-picutres-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 并启动你的工作负载。
# IMPORTANT: Make sure to edit your PVC in cat-pictures-pvc.yaml before applying. You need to:
# - Set ReadWriteOncePod as the only access mode
# - Set spec.volumeName to "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 以用作存储 的信息。