Kubernetes:2个命名空间中的2个PVC绑定到同一个PV,一个成功,一个失败

Kubernetes: 2 PVCs in 2 namespaces binding to the same PV, one successful, one failed

所以我在 2 个命名空间中有 2 个 PVC 绑定到 1 个 PV:

以下是 PVC:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-git
  namespace: mlo-dev
  labels:
    type: local
spec:
  storageClassName: mlo-git
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-git
  namespace: mlo-stage
  labels:
    type: local
spec:
  storageClassName: mlo-git
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

和PV:

kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv-git
  labels:
    type: local
spec:
  storageClassName: mlo-git
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  hostPath:
    path: /git

在命名空间“mlo-dev”中,绑定成功:

$ kubectl describe pvc pvc-git -n mlo-dev
Name:          pvc-git
Namespace:     mlo-dev
StorageClass:  mlo-git
Status:        Bound
Volume:        pv-git
Labels:        type=local
Annotations:   pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      1Gi
Access Modes:  RWX
VolumeMode:    Filesystem
Mounted By:    
...
various different pods here...
...
Events:        <none>

而在命名空间“mlo-stage”中,绑定失败并显示错误消息:storageclass.storage。k8s.io“mlo-git”未找到

$ kubectl describe pvc pvc-git -n mlo-stage
Name:          pvc-git
Namespace:     mlo-stage
StorageClass:  mlo-git
Status:        Pending
Volume:        
Labels:        type=local
Annotations:   Finalizers:  [kubernetes.io/pvc-protection]
Capacity:      
Access Modes:  
VolumeMode:    Filesystem
Mounted By: 
...
various different pods here...
...
Events:
  Type     Reason              Age                   From                         Message
  ----     ------              ----                  ----                         -------
  Warning  ProvisioningFailed  3m4s (x302 over 78m)  persistentvolume-controller  storageclass.storage.k8s.io "mlo-git" not found

据我所知,PV 不在命名空间范围内,因此不同命名空间中的 PVC 应该可以绑定到同一个 PV?

++++++ 添加: +++++

当“kubectl describe pv pv-git”时,我得到以下信息:

$ kubectl describe pv pv-git
Name:            pv-git
Labels:          type=local
Annotations:     pv.kubernetes.io/bound-by-controller: yes
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    mlo-git
Status:          Bound
Claim:           mlo-dev/pvc-git
Reclaim Policy:  Retain
Access Modes:    RWX
VolumeMode:      Filesystem
Capacity:        1Gi
Node Affinity:   <none>
Message:         
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /git
    HostPathType:  
Events:            <none>

我已经尝试重现您的场景(但是,如果您提供 storageclass yaml 以进行精确重现,并更改 AccessMode 以进行测试),我认为这种行为是正确的(有效按照设计)。

当你想检查特定对象是否为 namespaced 时,你可以使用命令:

$ kubectl api-resources | grep pv
persistentvolumeclaims            pvc                                         true         PersistentVolumeClaim
persistentvolumes                 pv                                          false        PersistentVolume

因为 PVC 是真的,它的意思是 pvc 是命名空间的,而 PV 不是。

PersistentVolumeClain and PersistentVolume 的关系是 1:1。当你的第一个 PVC 绑定到 PV 时,这个 PV 是 taken 并且在那一刻不能再次使用。 您应该创建第二个 PV. 它可以更改取决于 reclaimPolicy 以及 pop/deployment[=43= 发生的情况]

我猜你正在使用 Static 配置。

A cluster administrator creates a number of PVs. They carry the details of the real storage, which is available for use by cluster users. They exist in the Kubernetes API and are available for consumption.

在这种情况下,您必须创建 1 PV 到 1 PVC

如果您要使用云环境,您将使用 Dynamic 配置。

When none of the static PVs the administrator created match a user's PersistentVolumeClaim, the cluster may try to dynamically provision a volume specially for the PVC. This provisioning is based on StorageClasses: the PVC must request a storage class and the administrator must have created and configured that class for dynamic provisioning to occur.

例如,在 GKE 上,我尝试复制它并将 1 PVC 绑定到 PV。由于 GKE 使用 Dynamic provisioning,当您仅定义 PVC 时,它使用 default storageclass 并自动创建 PV.

$ kubectl get pv,pvc -A
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
persistentvolume/pv-git                                     1Gi        RWO            Retain           Bound    mlo-dev/pvc-git     mlo-git                 15s
persistentvolume/pvc-e7a1e950-396b-40f6-b8d1-8dffc9a304d0   1Gi        RWO            Delete           Bound    mlo-stage/pvc-git   mlo-git                 6s

NAMESPACE   NAME                            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mlo-dev     persistentvolumeclaim/pvc-git   Bound    pv-git                                     1Gi        RWO            mlo-git        10s
mlo-stage   persistentvolumeclaim/pvc-git   Bound    pvc-e7a1e950-396b-40f6-b8d1-8dffc9a304d0   1Gi        RWO            mlo-git        9s

解决方案

要解决此问题,您应该创建另一个 PersistentVolume 来绑定第二个 PVC

有关边界的更多详细信息,您可以查看. If you would like more information about PVC check

如果第二个 PV 没有帮助,请提供有关您的环境的更多详细信息(Minikube/Kubeadm,K8s 版本,OS,等)和你的 storageclass YAML。