将 PersistentVolume 的访问模式更改为 ReadWriteOncePod

本页展示了如何更改现有 PersistentVolume 的访问模式,使其使用 ReadWriteOncePod

开始之前

你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具已配置为与你的集群通信。建议在至少有两个非控制平面主机的节点集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者使用以下 Kubernetes 练兵场之一

你的 Kubernetes 服务器版本必须是 v1.22 或更高版本。

要检查版本,输入 kubectl version

为什么要使用 ReadWriteOncePod

在 Kubernetes v1.22 之前,ReadWriteOnce 访问模式通常用于限制需要单写入访问存储的工作负载对 PersistentVolume 的访问。但是,此访问模式存在一个限制:它将卷访问限制到单个 节点,允许同一节点上的多个 Pod 同时读写同一卷。这对于要求严格单写入访问以确保数据安全的应用来说可能构成风险。

如果确保单写入访问对你的工作负载至关重要,考虑将卷迁移到 ReadWriteOncePod

迁移现有 PersistentVolume

如果你有现有的 PersistentVolume,可以将它们迁移以使用 ReadWriteOncePod。仅支持从 ReadWriteOnceReadWriteOncePod 的迁移。

在此示例中,已存在一个 ReadWriteOnce "cat-pictures-pvc" PersistentVolumeClaim,它绑定到 "cat-pictures-pv" PersistentVolume,还有一个使用此 PersistentVolumeClaim 的 "cat-pictures-writer" Deployment。

在进行更改之前,你可以查看 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"]}}'

接下来,你需要修改 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"}}'

接下来

最后修改时间 2023 年 10 月 10 日 太平洋标准时间 上午 7:55: ReadWriteOncePod 提升为 GA (c07ce392e4)