PVC 可以绑定到特定的 PV 上吗?

这是由 k8s 维护人员在 https://github.com/kubernetes/kubernetes/issues/7438#issuecomment-97148195中讨论的:

允许用户要求一个特定的 PV 打破了他们之间的分离

我不相信,我们允许用户选择节点,这不常见 但它的存在是有原因的。

它是如何结束的? 什么是预期的方式有 > 1 PV 和 PVC 的一样在 https://github.com/kubernetes/kubernetes/tree/master/examples/nfs

我们使用的是 NFS,而 Perst 卷是一个方便的抽象,因为我们可以将 server IP 和 path保留在那里。但是持久容量索赔获得了足够大的 任何 PV,从而阻止了 path的重用。

可以设置 volumeName在 PVC spec块(见 https://github.com/kubernetes/kubernetes/pull/7529) ,但它没有什么区别。

63386 次浏览

现在有一种方法可以将 PV 预绑定到 PVC,下面的例子展示了如何:

  1. 创建一个 PV 对象,其中包含一个牵引 PVC 的 ClaimRef 字段,然后创建:
     $ kubectl create -f pv.yaml
    persistentvolume "pv0003" created
    
    其中 pv.yaml包含:
     apiVersion: v1
    kind: PersistentVolume
    metadata:
    name: pv0003
    spec:
    storageClassName: ""
    capacity:
    storage: 5Gi
    accessModes:
    - ReadWriteOnce
    persistentVolumeReclaimPolicy: Retain
    claimRef:
    namespace: default
    name: myclaim
    nfs:
    path: /tmp
    server: 172.17.0.2
    
  2. 然后创建同名的 PVC:
     kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
    name: myclaim
    spec:
    storageClassName: ""
    accessModes:
    - ReadWriteOnce
    resources:
    requests:
    storage: 5Gi
    
  3. 光伏和聚氯乙烯应立即绑定:
     $ kubectl get pvc
    NAME      STATUS    VOLUME    CAPACITY   ACCESSMODES   AGE
    myclaim   Bound     pv0003    5Gi        RWO           4s
    $ ./cluster/kubectl.sh get pv
    NAME      CAPACITY   ACCESSMODES   STATUS    CLAIM             REASON    AGE
    pv0003    5Gi        RWO           Bound     default/myclaim             57s
    

我不认为@Jayme 对原始答案的编辑是向前兼容的。

虽然只记录为 建议书,但 PVC 中的 标签选择器似乎可以与 Kubernetes1.3.0一起工作。

我已经编写了一个 例子,它定义了除 labels之外完全相同的两个卷。两者都可以满足任何索赔要求,但是当索赔要求指定

selector:
matchLabels:
id: test2

很明显,其中一个依赖的吊舱不会启动,test1 PV 保持未绑定状态。

可以通过以下方式在例如 Minikube中进行测试:

$ kubectl create -f volumetest.yml
$ sleep 5
$ kubectl get pods
NAME                              READY     STATUS    RESTARTS   AGE
volumetest1                       1/1       Running   0          8m
volumetest1-conflict              0/1       Pending   0          8m
$ kubectl get pv
NAME      CAPACITY   ACCESSMODES   STATUS      CLAIM          REASON    AGE
pv1       1Gi        RWO           Available                            8m
pv2       1Gi        RWO           Bound       default/test             8m

现在我们可以使用 storageClassName(至少从 kubernetes 1.7.x 开始)

详见 https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage

这里也复制了样本代码

kind: PersistentVolume
apiVersion: v1
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/tmp/data"
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi

这可以使用关键字 名称:来完成

比如说

apiVersion: "v1"
kind: "PersistentVolumeClaim"
metadata:
name: "claimapp80"
spec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: "10Gi"
volumeName: "app080"

将声称具体的 PV app080

是的,你实际上可以在 PVC 中提供 volumeName。它将精确地绑定到 volumeName 中提供的 PV 名称(还应该同步 spec)

最好在 pvc中同时指定 volumeNamepvc中的 claimRef

通过在 pvpvc中都使用 storageClassName: manual,我们可以彼此绑定,但它不能保证是否有很多 manual pv 和 pvc 的。

在 PVC 中指定 volumeName 不会阻止不同的 PVC 从绑定到指定的 PV 之前,你的索赔将 保持等待,直到 PV 可用。

在 PV 中指定 solamRef 并不能防止指定的 PVC 从 被绑定到一个不同的 PV。 PVC 可以自由选择另一个 PV 按照正常的装订过程装订。因此,要避免 并确保您的索赔与您的卷绑定在一起 如果需要,则必须确保同时指定 volumeName 和  。

您可以看出,您对 volumeName 和/或 actilaRef 的设置 通过检查束缚 PV 影响匹配和结合过程 和聚氯乙烯对的 pv.kubernetes.io/bound-by-controller 注释。 您自己设置 volumeName 和/或敏捷索取引用的 PV 和 PVC 将没有这样的注释,但是普通的 PV 和 PVC 将有它 设置为“是”。

当一个 PV 将它的 lockRef 设置为某个 PVC 名称和命名空间时,并且 根据保留回收政策,其索偿要求 保持设置为相同的 PVC 名称和名称空间,即使 PVC 或 整个命名空间不再存在。

来源: https://docs.openshift.com/container-platform/3.11/dev_guide/persistent_volumes.html

PV 和 PVC 中的 storageClassName 应该相同。在 PVC 中添加持久卷名称 volumeName,以将 PVC 绑定到特定的 PV。

例如:

apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-name
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 40Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-name
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
volumeName: pv-name

根据 文件:


控制平面可以将持久性卷声明绑定到集群中匹配的持久性卷,但是,如果你想要一个聚氯乙烯绑定到一个特定的 PV需要对它们进行预绑定。

通过在 PersisentVolumeClaim 中指定 Perst 卷,可以声明该特定 PV 和 PVC 之间的绑定。如果持久卷存在并且没有通过其声明 Ref 字段保留持久卷声明,那么将绑定持久卷和持久卷声明。

无论某些卷匹配条件(包括节点关联)如何,都会发生绑定。控制平面仍然检查存储类、访问模式和请求的存储大小是否有效。


即使是 状态集是用于管理有状态应用程序的资源,我已经将它们提供的 pv/pvc 示例修改为 Deployment 示例(使用 nginx,至少与 minikube 兼容,请注释/编辑与云提供商的兼容性) :

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-pvc
spec:
volumeName: foo-pv
storageClassName: "standard"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "1Gi"
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: foo-pv
#  name: bar-pv
spec:
storageClassName: "standard"
capacity:
storage: "1Gi"
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/test/"
#  claimRef:
#    name: foo-pvc
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: foo-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- name: nginx-storage
mountPath: /test/
volumes:
- name: nginx-storage
persistentVolumeClaim:
claimName: foo-pvc

因此,为了详细说明文档,如果 填写了 PV 的 spec.claimref.name (foo-PVC 或任何东西) ,你的 PVC 将处于待定状态,不会绑定。(我把它注释掉了。)然而,您会注意到,如果您像上面那样使用 kubectl edit pv foo-pv在创建 PV 之后编辑它,那么它就被设置为 在控制飞机旁边

另外,我留下了一个替代的 PV metadata.name (注释掉了) ,您可以切换注释行,还可以看到,如果值与 spec.volumeName 指定的 PVC 值不匹配,它也不会绑定。

附加说明: 我发现,如果在部署上面的代码之前没有创建/mnt/test,那么当您从容器内部向它写入代码时,它将创建该文件夹。

标签选择器怎么样,正如 kubernetes 文档中所描述的:

声明可以指定一个标签选择器来进一步筛选 只能绑定标签与选择器匹配的卷 选择器可以由两个字段组成:

Match 标签-卷必须有一个具有此值的标签
Match Expressions-通过指定 key,list 而产生的需求列表 值,以及关联键和值的操作符 运算符包括 In、 NotIn、 Exists 和 DoesNotExist。