如何在 Kubernetes pod 之间共享存储?

新手上路,请多包涵

我正在评估 Kubernetes 作为我们新应用程序的平台。现在,看起来一切都非常令人兴奋!但是,我遇到了一个问题:我在 GCE 上托管我的集群,我需要一些机制来在两个 pod 之间共享存储 - 持续集成服务器和我的应用程序服务器。使用 kubernetes 执行此操作的最佳方法是什么?似乎没有一种卷类型适合我的需求,因为如果一个 pod 需要写入磁盘,则无法共享 GCE 磁盘。 NFS 将是完美的,但似乎需要 kubernetes 集群的特殊构建选项?

编辑:共享存储似乎是我现在使用 Kubernetes 多次遇到的问题。有多个用例,我只想拥有一个卷并将其连接到多个 pod(具有写访问权限)。我只能假设这将是一个常见的用例,不是吗?

EDIT2:例如, 此页面 描述了如何设置 Elasticsearch 集群,但是不可能将其与持久存储连接起来( 如此处所述),这使得它毫无意义:(

原文由 Marco Lamina 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.8k
2 个回答

首先,你 真的 需要多个读者/作者吗?

根据我对 Kubernetes / 微服务架构 (MSA) 的经验,这个问题通常与您的设计模式更相关。 MSA 的基本设计模式之一是对服务的适当封装,这包括每个服务拥有的数据。

与 OOP 大致相同,您的服务应处理与其关注领域相关的数据,并应允许通过接口访问其他服务的数据。这个接口可以是一个 API、直接或通过代理服务处理的消息,或者使用协议缓冲区和 gRPC。通常,对数据的多服务访问是一种反模式,类似于 OOP 和大多数编程语言中的全局变量。

举个例子,如果你想写日志,你应该有一个日志服务,每个服务都可以调用它需要记录的相关数据。直接写入共享磁盘意味着如果您更改日志目录结构,或者决定添加额外功能(例如针对某些类型的错误发送电子邮件),则需要更新每个容器。

在大多数情况下,您应该在使用文件系统之前使用某种形式的最小接口,以避免在使用文件系统时遇到的 Hyrum 定律 的意外副作用。如果您的服务之间没有适当的接口/合同,您将大大降低构建可维护和弹性服务的能力。

好的,您的情况最好使用文件系统来解决。有很多选择…

显然,有时可以处理多个并发写入者的文件系统提供了优于更“传统”的 MSA 通信形式的解决方案。 Kubernetes 支持大量的卷类型,可以在 这里 找到。虽然这个列表很长,但其中许多卷类型不支持多个写入器(在 Kubernetes 中也称为 ReadWriteMany )。

那些支持 ReadWriteMany 的卷类型可以在 此表 中找到,在撰写本文时是 AzureFile、CephFS、Glusterfs、Quobyte、NFS 和 PortworxVolume。

还有一些运营商,例如流行的 rook.io ,它们功能强大并提供了一些很棒的功能,但是当您只想要一个简单的解决方案并继续前进时,此类系统的学习曲线可能会很困难。

最简单的方法。

根据我的经验,最好的初始选项是 NFS。这是了解 ReadWriteMany Kubernetes 存储的基本思想的好方法,将服务于大多数用例并且最容易实现。在您建立了多服务持久性的工作知识之后,您可以做出更明智的决定来使用功能更丰富的产品,而这些产品通常需要更多的工作来实现。

设置 NFS 的细节因集群的运行方式和位置以及 NFS 服务的细节而异,我之前写过两篇关于如何为 本地集群 设置 NFS 和 在 EKS 上使用 AWS NFS 等效 EFS 的文章集群。这两篇文章很好地对比了如何根据您的特定情况执行不同的实现。

举个最简单的例子,您首先需要一个 NFS 服务。如果您希望进行快速测试或者您的 SLO 要求较低,那么按照 这篇 DO 文章 是在 Ubuntu 上设置 NFS 的快速入门指南。如果您有一个现有的 NAS,它提供 NFS 并且可以从您的集群访问,这也可以。

拥有 NFS 服务后,您可以创建类似于以下内容的持久卷:

 ---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-name
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  nfs:
    server: 255.0.255.0 # IP address of your NFS service
    path: "/desired/path/in/nfs"

这里需要注意的是,您的节点需要安装二进制文件才能使用 NFS,我在我 的本地集群 文章中对此进行了更多讨论。这也是您在 EKS 上运行时 需要 使用 EFS 的原因,因为您的节点无法连接到 NFS。

一旦设置了持久卷,就可以像使用任何其他卷一样使用它。

 ---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-name
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
        - name: p-name
          volumeMounts:
            - mountPath: /data
              name: v-name
      volumes:
        - name: v-name
          persistentVolumeClaim:
            claimName: pvc-name

原文由 Ian Belcher 发布,翻译遵循 CC BY-SA 4.0 许可协议

首先。 Kubernetes 没有在主机之间共享存储的集成功能。下面有几个选项。但首先如果您已经设置了一些卷,如何共享存储。

要在多个 pod 之间共享一个卷,您需要创建一个访问模式为 ReadWriteMany 的 PVC

 kind: PersistentVolumeClaim
apiVersion: v1
metadata:
    name: my-pvc
spec:
    accessModes:
      - ReadWriteMany
    storageClassName: myvolume
    resources:
        requests:
            storage: 1Gi

之后,您可以将其挂载到多个 pod:

 apiVersion: v1
kind: Pod
metadata:
  name: myapp1
spec:
  containers:
...
      volumeMounts:
        - mountPath: /data
          name: data
          subPath: app1
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: 'my-pvc'
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp2
spec:
  containers:
...
      volumeMounts:
        - mountPath: /data
          name: data
          subPath: app2
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: 'my-pvc'

当然,持久卷必须可以通过网络访问。否则,您需要确保将所有 pod 安排到具有该卷的节点。

有几种卷类型适用于此,并且不依赖于任何云提供商:

  • NFS
  • RBD(Ceph 块设备)
  • CephFS
  • Glusterfs
  • Portworx 卷

当然,要使用卷,您需要先拥有它。也就是说,如果要使用 NFS,则需要在 K8s 集群中的所有节点上设置 NFS。如果要消费 Ceph,则需要设置 Ceph 集群等。

开箱即用支持 Kubernetes 的唯一卷类型是 Portworks。有关于 如何在 GKE 中设置它 的说明。

要在 K8s 中设置 Ceph 集群,有一个名为 Rook 的开发项目。

但是,如果您只想让一个节点中的文件夹在另一个节点中可用,那么这一切都是多余的。在这种情况下,只需设置 NFS 服务器。它不会比配置其他卷类型更难,并且会消耗更少的 CPU/内存/磁盘资源。

原文由 Vanuan 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题