k8s PersistentVolumeClaim (PVC) 报错:Multi-Attach error for volume “pvc-3413512-1-4909-a111-4412351“

k8s PersistentVolumeClaim (PVC) 报错:Multi-Attach error for volume “pvc-3413512-1-4909-a111-4412351” Volume is already used by pod(s) pod-ewrfd86549-bv5522

问题

pod启动报错:报错:Multi-Attach error for volume “pvc-3413512-1-4909-a111-4412351” Volume is already used by pod(s) pod-ewrfd86549-bv5522

原因分析

  1. 你的 PVC 使用了 ReadWriteOnce (RWO) 访问模式
  2. RWO 模式的卷只能被单个节点上的 Pod 挂载
  3. 现在有多个 Pod 或者 Pod 在不同节点上尝试挂载同一个卷
storageClassName: cbs      # 腾讯云块存储

storageClassName: cbs 就是告诉 Kubernetes:“我要使用腾讯云的块存储服务来创建这个存储卷”。不同的存储类提供不同的性能、价格和功能特性。

storageClassName 是 Kubernetes 中定义存储类型和配置的重要概念,StorageClass 是 Kubernetes 中的一个资源对象,它定义了:

  • 存储的类型(如 SSD、HDD、网络存储等)
  • 存储的提供商(如腾讯云CBS、阿里云盘、AWS EBS等)
  • 存储的参数配置(如副本数、加密、性能等)
cbs      # 普通云硬盘,性价比高
cfs      # 使用文件存储支持多节点
cbs-ssd  # 使用SSD获得更好性能	

CBS (Cloud Block Storage) 的特点:

  • 只支持 ReadWriteOnce 模式
  • 一个 CBS 卷只能挂载到一个节点上
  • 不支持 ReadWriteMany 多节点共享

这里报错的原因同时和我k8s RollingUpdate(滚动更新)也有关系,k8s deployment没有特别配置情况下,默认是滚动更新,虽然我的pod副本个数配置的是1,但是因为默认滚动更新,所以它会新启动一个pod,启动正常才会停止旧的pod。因为RWO 模式的卷只能被单个节点上的 Pod 挂载,所以旧的pod已经占用了这个卷,所以新的pod就会报错:Multi-Attach error for volume “pvc-3413512-1-4909-a111-4412351” Volume is already used by pod(s) pod-ewrfd86549-b

解决方案

方法1:缩放到0再扩容

# 缩放到0个副本
kubectl scale deployment local-object-storage --replicas=0 -n your-namespace

# 等待Pod完全删除
kubectl get pods -n your-namespace

# 扩容回1个副本
kubectl scale deployment local-object-storage --replicas=1 -n your-namespace

方法2:修改k8s升级策略为 Recreate(重建)
可以持久化解决PVC Multi-Attach问题

什么是PV、PVC和StorageClass、 PersistentVolumeClaim?

网络存储的类型多种多样,云服务提供商通常提供块存储、文件存储、对象存储三种以上的底层存储类型。为了屏蔽这些底层存储差异,Kubernetes提供了PV(PersistentVolume)和PVC(PersistentVolumeClaim) 的抽象机制。通过这套模型,开发者不需要关心存储系统的具体类型和实现细节,只需像申请CPU和内存一样,声明所需的存储容量和访问模式,Kubernetes会自动完成与底层存储的对接与挂载。这种设计实现了存储资源的“解耦”——使用者只负责提出需求,平台自动完成资源的匹配和调配,极大提升了部署的灵活性和可移植性。

PersistentVolumeClaim (PVC) 是 Kubernetes 中用于请求存储资源的对象。它是 Pod 和 PersistentVolume (PV) 之间的桥梁:

  • PV (PersistentVolume): 集群中的实际存储资源,PV描述的是持久化存储卷,主要定义的是一个持久化存储在宿主机上的目录,比如一个NFS的挂载目录
  • PVC (PersistentVolumeClaim): Pod 对存储的请求声明。PVC描述的是Pod所希望使用的持久化存储的属性,比如,Volume存储的大小、可读写权限等等
  • StorageClass: 定义存储的类型和配置

在这里插入图片描述

PV是集群级别的资源,并不属于某个命名空间,而PVC是命名空间级别的资源,PV可以与任何命名空间的PVC资源绑定。

PersistentVolume(PV)是集群中一块存储资源,由管理员主动创建提供或使用 StorageClass 动态提供。它与节点资源一样,不属于任何命名空间,有着自己独立的生命周期。而用户则通过 PersistentVolumeClaim (PVC) 来申请所需的存储资源。

# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce  # RWO: 单节点读写
    # - ReadOnlyMany   # ROX: 多节点只读
    # - ReadWriteMany  # RWX: 多节点读写
  resources:
    requests:
      storage: 10Gi
  storageClassName: standard

查看集群中的 StorageClass

# 查看所有可用的存储类
kubectl get storageclass
# 或简写
kubectl get sc

# 查看详细信息
kubectl describe storageclass cbs

Kubernetes Deployment 重建升级

升级策略类型

Kubernetes Deployment 有两种主要的升级策略:

1. RollingUpdate(滚动更新)- 默认策略
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1      # 最多1个Pod不可用
      maxSurge: 1           # 最多额外创建1个Pod
  template:
    # ... Pod模板

特点:

  • 逐步替换旧Pod
  • 保证服务连续性
  • 升级过程中新旧版本可能同时存在
2. Recreate(重建)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: local-object-storage
spec:
  replicas: 1
  strategy:
    type: Recreate  # 先删除所有Pod,再创建新Pod
  template:
    # ... Pod模板

特点:

  • 先删除所有旧Pod
  • 再创建新Pod
  • 有短暂的服务中断
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西京刀客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值