Jos*_*aro 6 amazon-web-services docker amazon-ecs
我正在将现有应用程序从在裸 EC2 实例上运行迁移到使用 ECS 的容器化设置。我有两种情况需要在容器之间共享数据。一个是存储一些静态和媒体文件的 EFS 共享,另一个是日志目录,以便我可以使用 sidecar 容器中的 Cloudwatch Logs 代理将日志推送到 Cloudwatch。
网络服务器需要能够将数据写入这两个位置,但到目前为止我还无法实现。日志目录是本地卷,归root:root. 我按照这些说明设置的 EFS 共享归1000:xfs(无用户名)所有。在这两种情况下,我的网络用户 ( www-data) 都不能写入这些位置。
如何告诉 ECS 在具有给定所有者和/或组的容器内安装卷?
编辑:事实证明这比我做的要简单得多。
当您在 ECS 上创建卷时,它会要求您提供卷的名称和“源路径”。当要求解释时,它将指定源路径是“主机容器实例上呈现给该卷的容器的路径。如果省略,则 Docker 守护程序会为您分配一个主机路径。”
一切都很好,但事实证明,区别不仅仅是“指定一个目录”与“Docker 为您选择一个目录”。这是docker 卷和绑定挂载之间的区别,事实上,如果您是docker inspect容器,您将看到为 ECS 提供“源路径” get 的卷"Type": "bind",而未指定 get 的卷"Type": "volume"。
绑定挂载和卷之间的一个主要区别是,绑定挂载从主机文件系统继承其所有权,而卷从容器文件系统继承其所有权。因此,解决我的问题的简单得令人难以置信、令人沮丧的方法是确保该目录存在于映像中并具有正确的所有权,然后在 ECS 中创建该卷而不指定源路径。
顺便说一句,如果您的应用程序涉及共享同一卷的多个容器,则该卷将从先启动并运行的容器的现有目录结构中获取其权限。因此,您需要确保 a) 该目录存在于将安装该卷的所有容器上,或者 b) 具有相关目录的容器始终首先启动。
我将在下面留下我原来的解决方案,以防它对任何人有用。
原方案一:tmpfs挂载
Docker 卷接受一个driver_opts参数,其工作方式与 Linux 系统上的命令类似mount。因此,一种选择是使用挂载tmpfs,它允许设置结果文件的所有者和组的选项。在 ECS 上,可以这样完成:
{
"name": "myvolume",
"dockerVolumeConfiguration": {
"scope": "task",
"driver": "local",
"driverOpts": {
"type": "tmpfs",
"device": "tmpfs",
"o": "uid=1000,gid=1000"
}
}
}
Run Code Online (Sandbox Code Playgroud)
这将在容器内创建一个由用户和组 1000 拥有的卷。
这种方法的缺点是,tmpfs它将文件存储在主机内存中。根据您的用例,这可能会也可能不会被接受 - 对我来说这并不理想,因为我需要存储可能会变得非常大的日志文件。
(请注意,此处的type和device参数driverOpts相当于Linux命令的type和参数。这花了我相当多的时间和挫败感才弄清楚。)devicemount
原方案2:通过NFS匹配UID
NFS 只是将文件的所有者/组存储为数字 ID。该小组出现在xfs我身上的原因是,作为我重新部署的一部分,我将从 Ubuntu 迁移到 Alpine。在这两种情况下,我都想使用www-data组,但www-data在 Ubuntu 上是用户/组 33,在 Alpine 上是 82。在 Alpine 上,33 已经作为“X 字体服务器”用户存在,因此xfs.
对于非持久性、共享的“临时工作”目录,我仍然没有一个完美的解决方案,我可以在日志等待发送到 Cloudwatch 时转储日志。我最终可能只是使用 tmpfs 解决方案,然后使用一组非常激进的参数运行 logrotate,这样日志文件就不会消耗超过几 MB 的内存。
| 归档时间: |
|
| 查看次数: |
2860 次 |
| 最近记录: |