文章目录
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
原因分析
- 你的 PVC 使用了
ReadWriteOnce
(RWO) 访问模式 - RWO 模式的卷只能被单个节点上的 Pod 挂载
- 现在有多个 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
- 有短暂的服务中断