在Kubernetes/OpenShift中,如何在容器之间共享持久卷索赔?

31
这可能是一个愚蠢的问题,但我在网上没有找到太多信息,想要澄清一下。
给定两个部署 A 和 B,它们都具有不同的容器镜像:
它们在 K8/OpenShift 集群中的两个不同 pod(不同的 rc、svc 等)中部署。
它们都需要访问同一个卷来读取文件(现在先不考虑锁定),或者至少需要访问该卷中相同的目录结构。
使用由 NFS 共享配置的 PV(持久卷)支持的 PVC(持久卷声明)挂载该卷。
我可以确认上述情况实际上是可能的吗?即两个不同的 pod 连接到具有相同 PVC 的同一卷。这样它们就可以从同一卷中进行读取。
希望这样说有意义...
3个回答

43

TL;DR 如果使用共享卷(nfs、gluster等)可以在同一项目/命名空间内共享PV和PVC,但是如果要从多个项目/命名空间访问共享卷,则需要专门为项目创建PV和PVC。因为PV绑定到单个项目/命名空间,而PVC是项目/命名空间范围的。

下面我尝试说明当前行为以及如何在OpenShift中对PV和PVC进行作用域约束。这些都是使用NFS作为持久存储层的简单示例。

目前,accessModes只是标签,在控制对PV访问权限方面没有实际功能。以下是一些示例,以显示这一点。

PV是全局的,意味着任何项目/命名空间都可以看到/访问它,但是一旦绑定到项目中,它就只能被来自相同项目/命名空间的容器访问。

PVC是项目/命名空间特定的(因此,如果您有多个项目,则需要为每个项目创建新的PV和PVC以连接到共享的NFS卷-不能重复使用第一个项目中的PV)。

示例1:
我在“默认”项目/命名空间中运行两个不同的pod,两者都访问相同的PV和NFS导出共享。两者都可以成功挂载和运行。

[root@k8dev nfs_error]# oc get pv
NAME      LABELS    CAPACITY   ACCESSMODES   STATUS    CLAIM  REASON    AGE
pv-nfs    <none>    1Gi        RWO           Bound default/nfs-claim             3m


[root@k8dev nfs_error]# oc get pods    <--- running from DEFAULT project, no issues connecting to PV
NAME              READY     STATUS    RESTARTS   AGE
nfs-bb-pod2-pvc   1/1       Running   0          11m
nfs-bb-pod3-pvc   1/1       Running   0          10m

例子2:
我有两个不同的pod运行在“default”项目/命名空间中,并尝试使用相同的PV创建另一个pod,但来自新项目testproject以访问相同的NFS导出。新的testproject中的第三个pod将无法绑定到PV,因为它已经被default 项目绑定。

[root@k8dev nfs_error]# oc get pv
NAME      LABELS    CAPACITY   ACCESSMODES   STATUS    CLAIM  REASON    AGE
pv-nfs    <none>    1Gi        RWO           Bound default/nfs-claim             3m


[root@k8dev nfs_error]# oc get pods    <--- running from DEFAULT project, no issues connecting to PV
NAME              READY     STATUS    RESTARTS   AGE
nfs-bb-pod2-pvc   1/1       Running   0          11m
nfs-bb-pod3-pvc   1/1       Running   0          10m

** 创建一个针对另一个项目(testproject)中现有 PV 的新索赔将导致 PVC 失败。

[root@k8dev nfs_error]# oc get pvc 
NAME        LABELS    STATUS    VOLUME    CAPACITY   ACCESSMODES   AGE
nfs-claim   <none>    Pending                                      2s

由于 nfs-claim 无法从其当前项目范围中看到 pv-nfs PV,它永远不会绑定到该 PV。

示例3:

我在“default”项目中运行了2个不同的pod,然后从testproject创建了另一个PV、PVC和Pod。两个项目都能够访问相同的NFS共享,但我需要在每个项目中都有一个PV和PVC。

[root@k8dev nfs_error]# oc get pv
NAME      LABELS    CAPACITY   ACCESSMODES   STATUS     CLAIM                    REASON    AGE
pv-nfs    <none>    1Gi        RWX           Bound     default/nfs-claim                  14m
pv-nfs2   <none>    1Gi        RWX           Bound     testproject/nfs-claim2             9m



[root@k8dev nfs_error]# oc get pods --all-namespaces
NAMESPACE     NAME              READY     STATUS    RESTARTS   AGE
default       nfs-bb-pod2-pvc   1/1       Running   0          11m
default       nfs-bb-pod3-pvc   1/1       Running   0          11m
testproject   nfs-bb-pod4-pvc   1/1       Running   0          15s

注意,我现在有三个Pod运行到同一个NFS共享卷上,跨越两个项目,但是我需要两个PV,因为它们绑定到单个项目,还需要两个PVC,每个项目一个和我正在尝试访问的NFS PV

示例4:

如果我绕过PV和PVC,我可以直接使用nfs插件从任何项目连接到共享的NFS卷

volumes:
- name: nfsvol
  nfs:
    path: /opt/data5
    server: nfs1.rhs

现在,卷安全性是建立在此之上的另一层,使用supplementalGroups(用于共享存储,即nfs、gluster等),管理员和开发人员应该进一步能够管理和控制访问共享NFS系统。

希望这有所帮助。


@DonovanMuller:我也试图为多个Pod使用相同的PV,它可以正常工作,但是我认为在这种情况下数据也在Pod之间共享。我的主要关注点是,如果PV包含2 GB的数据,那么所有使用此PV的Pod都将可用于数据,这不是我们想要的。Pod应该只有自己的数据,而不是其他人的数据。我在这里也提出了这个问题http://stackoverflow.com/questions/36624034/openshift-persistent-volumes,但没有回应。如果您能解决这个问题,那将非常有帮助。谢谢! - priyank
@screenlay:非常感谢您对我上面的问题提出的看法。非常感谢! - priyank
@priyank - 我认为如果你想限制共享存储上的数据/目录,你可以从securityContext中传递supplementalGroups,然后在NFS服务器上设置所有权和组,即dir1开放给A和B组,然后dir1/dirA仅对podA开放,dir1/dirB仅对podB开放 - 这样所有pod都可以访问dir1,但只有podA可以访问dirA,podB可以访问dirB。 - screeley
在同一项目中,两个不同的应用程序之间是否可以共享单个PVC? - hamster on wheels
2
例子4正是我需要的,可以避免在许多命名空间中创建多个PersistentVolumes和Claims。 - Daniel Watrous
显示剩余2条评论

0

我看到了这篇文章学习如何在新的命名空间中重新创建现有的PVC,重用相同的PV而不会丢失数据。虽然我还没有测试过,但值得一试。然而,k8s文档指出PV-to-PVC关系是一对一的。

关于命名空间的说明 PersistentVolumes绑定是独占的,由于PersistentVolumeClaims是命名空间对象,因此使用“Many”模式(ROX,RWX)挂载声明仅在一个命名空间内可能。 参考:https://kubernetes.io/docs/concepts/storage/persistent-volumes/#a-note-on-namespaces


-3
据我所知,不支持多次绑定 PV。您可以直接使用卷源(在您的情况下为 NFS)来满足您的需求。

根据这个(http://kubernetes.io/v1.1/examples/nfs/),看起来是可能的?在示例中,有两个使用相同pvc的rc。 - Donovan Muller
您可以在任何地方绑定 PV,但是卷提供程序本身可以拒绝同时访问的附加请求(对于 Ceph、EBS 或 GCE)。NFS 没有保证 - 如果您想防止两个 Pod 同时使用 NFS,则需要自己进行隔离/锁定。 - Clayton
@Clayton: 我也试图为多个Pod使用相同的PV,它运行正常,但我认为数据在这种情况下也被共享。我的主要关注点是,如果PV包含2 GB的数据,那么所有使用此PV的Pod都将有可用的数据,这不是我们想要的。Pod应该只有自己的数据,而不是其他人的。我在这里stackoverflow.com/questions/36624034/…提出了这个问题,但没有回应。如果您能澄清这一点,将非常有帮助。先谢谢! - priyank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接