You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes Pod无法挂载已使用PVC卷问题求助

问题:Deployment扩容/更新时PV挂载失败

我有一个2副本的Deployment,日志写入通过PVC申请的存储卷。扩容副本或更新Deployment时,Pod出现挂载卷失败的错误:

0s          Warning   FailedAttachVolume       pod/POD_NAME
AttachVolume.Attach failed for volume "pvc-XXXXXX" : rpc error: code =
Internal desc = [ControllerPublishVolume] Attach Volume failed with error
failed to attach XXXXXX volume to XXXXXXXX compute: Bad request with: [POST
https://SOME_URL], error message: {"badRequest": {"code": 400, "message":
"Invalid input received: Invalid volume: Volume XXXXXXXX status must be
available or downloading to reserve, but the current status is in-use.
(HTTP 400) (Request-ID: XXXXXXX)"}}

PVC配置:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: "my-pvc"
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 50Gi
  storageClassName: "csi-cinder-tiefighter"

Deployment配置(简化后):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: "my-deployment"
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: "topology.kubernetes.io/zone"
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              "app.kubernetes.io/name": "my-label"
        - maxSkew: 1
          topologyKey: "kubernetes.io/hostname"
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              "app.kubernetes.io/name": "my-label"
      shareProcessNamespace: true
      initContainers:
        - name: "add-volume-log-permissions"
          image: "my-busybox-iamge"
          command: [ "/bin/sh" ]
          args: [ "-c", "chown 1000:1000 MY_PATH" ]
          securityContext:
            runAsUser: 0
          volumeMounts:
            - mountPath: "MY_PATH"
              name: "volume-logs"
          resources:
            limits:
              memory: 100Mi
              cpu: 100m
      containers:
      - name: "my-container"
        image: "MY_IMAGE"
        imagePullPolicy: Always
        volumeMounts:
          - mountPath: "MY_PATH"
            name: "volume-logs"
      volumes:
        - name: "volume-logs"
          persistentVolumeClaim:
            claimName: "myPvc"

需求:用该存储卷保存日志,Deployment需至少保持2个副本,如何解决?


解决方案

1. 修正PVC名称引用错误

Deployment中volumes.persistentVolumeClaim.claimName写的是myPvc,但实际PVC名称是my-pvc,Kubernetes资源名称严格匹配,先修正这个拼写错误:

volumes:
  - name: "volume-logs"
    persistentVolumeClaim:
      claimName: "my-pvc"

2. 验证存储类的RWX实际支持能力

虽然PVC声明了ReadWriteMany(RWX),但Cinder块存储默认仅支持ReadWriteOnce(RWO),即一个卷只能挂载到一个节点。你的存储类csi-cinder-tiefighter可能并未真正实现RWX能力,导致第二个Pod尝试挂载时卷处于in-use状态而失败。

  • 执行以下命令检查绑定的PV的访问模式:
kubectl get pv -o jsonpath='{.items[?(.spec.claimRef.name=="my-pvc")].spec.accessModes}'

如果输出是["ReadWriteOnce"],说明存储后端不支持RWX,必须更换存储方案。

3. 更换为支持RWX的存储后端

要让多个Pod同时挂载同一个卷写入日志,必须使用原生支持RWX的存储:

  • 云厂商共享存储:比如AWS EFS、Azure Files、阿里云NAS等,创建对应存储类后重新申请PVC。
  • 开源共享存储:部署NFS、GlusterFS、Longhorn(需配置RWX)等,配置对应的存储类。

示例:NFS类型的PVC配置

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: "my-pvc"
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 50Gi
  storageClassName: "nfs-storageclass" # 替换为你的NFS存储类名称

4. 临时Workaround(不推荐长期使用)

如果暂时无法更换存储,可调整Deployment滚动更新策略,避免同时存在两个Pod挂载同一个卷:

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 0
    maxUnavailable: 1

该配置会先销毁一个旧Pod,再创建新Pod,确保同一时间只有一个Pod挂载卷。但缺点是更新期间副本数会短暂降到1,不符合“至少保持2个副本”的长期需求,仅作为临时应急方案。


内容的提问来源于stack exchange,提问作者Andrei Manolache

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 03:35:03