将 PersistentVolume 的访问模式更改为 ReadWriteOncePod

本文演示了如何将现有 PersistentVolume 的访问模式更改为使用 ReadWriteOncePod

准备开始

你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:

你的 Kubernetes 服务器版本必须不低于版本 v1.22. 要获知版本信息,请输入 kubectl version.

我为什么要使用 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。

你可以在进行更改之前查看 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 并启动你的工作负载:

# 重要提示:在 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"}}'

接下来

最后修改 July 17, 2024 at 9:24 AM PST: [zh] Add change-pv-access-mode-readwriteoncepod.md (2b5dee6088)