【问题标题】:How to map docker volume to EC2 host file system如何将 docker 卷映射到 EC2 主机文件系统
【发布时间】:2021-08-24 20:56:49
【问题描述】:

我们有一堆微服务在共享 AWS EC2 实例的自己的 Docker 容器中运行。 鉴于在本地运行时获得的出色结果,现在我们正在尝试使用 Chronicle 队列作为我们在 AWS 中的微服务之间进行通信的一种方式。

MS1 收到一个 API 请求并进行一些内部处理并向 CH2 Chronicle 队列发送一个事件。 MS2 正在侦听 CH2 编年史队列,当事件到达那里时,它会拾取它并进行一些内部处理并将事件发送到 CH3 编年史队列。

API --> MS1 --> CH2 --> MS2 --> CH3 --> ...

在每个容器中,我们都有/tmp/my_app_data 一个应用程序根文件夹和一个与微服务交互的每个 Chronicle 队列的子文件夹。 例如,在 MS1 容器中,我们有 /tmp/my_app_data/ch2,在 MS2 容器中,我们有 /tmp/my_app_data/ch2/tmp/my_app_data/ch3

所有这些文件夹都以类似的结构映射到 EC2 主机:

/tmp/my_app_data
    |_ch2
    |_ch3
    |_...

现在,在尝试运行我们的系统时,我们遇到了各种访问数据的问题,这些数据是由一个微服务编写的,旨在用于工作流程中的下一个微服务。在上面的示例中,我们可以进一步让 MS2 从 ch2 读取 MS1 发送给您的数据,但我们仍然无法将数据标记为已处理,这意味着 MS2 正在写入 ch2 文件夹下的文件。

我无法列出我们尝试过的全部排列组合,甚至试图破解容器内和 EC2 主机上的文件权限;看来我缺少一些特定于 Docker/AWS 的基本设置。

这是我们来自 MS1 Dockerfile 的 Docker 配置:

 RUN mkdir -p /tmp/my_app_data && chown nobody:nobody /tmp/my_app_data
 RUN mkdir -p /tmp/my_app_data/ch2 && chown nobody:nobody /tmp/my_app_data/ch2
 USER nobody
 VOLUME ["/tmp/my_app_data"]

类似地,我们在 MS1 Dockerfile 中拥有相同的 Docker 配置:

 RUN mkdir -p /tmp/my_app_data && chown nobody:nobody /tmp/my_app_data
 RUN mkdir -p /tmp/my_app_data/ch2 && chown nobody:nobody /tmp/my_app_data/ch2
 RUN mkdir -p /tmp/my_app_data/ch3 && chown nobody:nobody /tmp/my_app_data/ch3
 USER nobody
 VOLUME ["/tmp/my_app_data"]

在 AWS 方面,我们拥有 MS1 和 MS2 任务定义的部分:

    "mountPoints": [
      {
        "readOnly": null,
        "containerPath": "/tmp/my_app_data",
        "sourceVolume": "chronicle"
      }
    ],
    ....
    "volumes": [
      {
        "fsxWindowsFileServerVolumeConfiguration": null,
        "efsVolumeConfiguration": null,
        "name": "chronicle",
        "host": {
          "sourcePath": "/tmp/my_app_data"
         },
        "dockerVolumeConfiguration": null
      }
    ]

所以这是我的问题:我做错了什么,我该如何解决? 理想情况下,对于我们来说,这应该在以用户 nobody 运行时工作,但因为这是一个 POC,所以无论如何我都会很感激让它运行,包括 root。对我们来说,这个 POC 的目的是确认我们在云中使用 Chronicle 是否获得与在本地运行时相同的良好结果。

提前感谢您的意见。

【问题讨论】:

  • 您能否使用不依赖共享文件的不同排队解决方案(RabbitMQ 是一种流行的开源选项)?
  • 是的,我可以,而且我们已经使用 solace 和 IBM MQ 创建了 POC,而且性能也非常好。然而,Chronicle 有一个优势,即除了类路径中的 jar 之外,不需要任何基础设施设置。这表示尚未做出离开 Kafka 的决定。
  • 我正试图解决这个问题,我想知道问题是否在于尝试在不同的任务中绑定挂载相同的文件夹。看起来像single task you are doing the right thing
  • 话虽如此,您是否考虑过在您的设计中使用 EFS 来托管您的队列文件?我看到了一些优点:它允许将 EC2 的短暂性与队列的持久性分离,它允许使用超过 1 个 EC2(用于 HA 并在需要时进行扩展),它还可以绕过完成的 POSIX 混乱通过 IAM 通过任务角色将 r/w 权限分配给 EC2。如果您想更深入地了解这一点,请查看this blog series的第 1 部分和第 2 部分
  • EFS 是我尝试的第一件事。不幸的是,Chronicle-queue 开源不支持在不同主机之间移动数据。只要所有数据都移动到同一个硬盘上而不涉及任何网络,它就可以正常工作。看起来你需要chronicle-queue-enterprise,这对我们都有好处,只是为了一个POC,我想让它在单个EC2上工作

标签: java amazon-web-services docker amazon-ecs chronicle-queue


【解决方案1】:

Chronicle FAQ 中记录了如何设置 Chronicle Queue 以使用 Docker。您需要确保:

  • 容器共享 IPC 命名空间(使用 --ipc="host" 运行)

  • 队列从主机挂载到绑定挂载的文件夹上(即 -v /host/dir/1/:/container/dir)

【讨论】:

    猜你喜欢
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 2022-08-17
    • 2018-10-15
    • 2021-04-04
    • 1970-01-01
    相关资源
    最近更新 更多