在 AWS ECS 容器上挂载 S3 存储桶作为文件系统
Posted
技术标签:
【中文标题】在 AWS ECS 容器上挂载 S3 存储桶作为文件系统【英文标题】:Mount S3 bucket as filesystem on AWS ECS container 【发布时间】:2019-02-02 02:58:33 【问题描述】:我正在尝试使用 rexray/s3fs 驱动程序将 S3 作为卷安装在 AWS ECS docker 容器上。
我可以在我安装插件的本地机器上执行此操作
$docker plugin install rexray/s3fs
并将 S3 存储桶安装在 docker 容器上。
$docker plugin ls
ID NAME DESCRIPTION ENABLED
3a0e14cadc17 rexray/s3fs:latest REX-Ray FUSE Driver for Amazon Simple Storage true
$docker run -ti --volume-driver=rexray/s3fs -v s3-bucket:/data img
我正在尝试在 AWS ECS 上复制它。
尝试遵循以下文档: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/docker-volumes.html
如果我给 Driver 值,那么任务将无法运行并给出 “无法放置任务,因为没有容器实例满足其所有要求。”错误。
我正在使用 t2.medium 实例并为其提供任务要求,因此它不应该是硬件要求问题。
如果我从作业定义任务中删除驱动程序配置,则会执行。
我好像错过了配置的东西。
有没有人尝试/尝试过同样的事情,请分享知识。
谢谢!!
【问题讨论】:
AWS 已声明 AWS ECS 支持 Volume 插件,但我找不到太多配置文档。 aws.amazon.com/about-aws/whats-new/2018/08/… 这不是***.com/questions/44062196/mount-s3-bucket-on-aws-ecs的复制品吗? 【参考方案1】:你使用rexray/s3fs驱动的方法是正确的。
这些是我在 Amazon Linux 1 上运行的步骤。
首先你需要安装 s3fs。
yum install -y gcc libstdc+-devel gcc-c+ fuse fuse-devel curl-devel libxml2-devel mailcap automake openssl-devel git gcc-c++
git clone https://github.com/s3fs-fuse/s3fs-fuse
cd s3fs-fuse/
./autogen.sh
./configure --prefix=/usr --with-openssl
make
make install
现在安装驱动程序。您可能需要在此处修改一些选项,例如使用 IAM 角色而不是访问密钥和 AWS 区域。
docker plugin install rexray/s3fs:latest S3FS_REGION=ap-southeast-2 S3FS_OPTIONS="allow_other,iam_role=auto,umask=000" LIBSTORAGE_INTEGRATION_VOLUME_OPERATIONS_MOUNT_ROOTPATH=/ --grant-all-permissions
现在是重启 ECS 代理的非常重要的一步。我也更新了。
yum update -y ecs-init
service docker restart && start ecs
您现在应该可以创建任务定义了。重要的部分是您的音量配置,如下所示。
"volumes": [
"name": "name-of-your-s3-bucket",
"host": null,
"dockerVolumeConfiguration":
"autoprovision": false,
"labels": null,
"scope": "shared",
"driver": "rexray/s3fs",
"driverOpts": null
]
现在你只需要在容器定义中指定挂载点:
"mountPoints": [
"readOnly": null,
"containerPath": "/where/ever/you/want",
"sourceVolume": "name-of-your-s3-bucket"
]
现在,只要您具有访问 s3 存储桶的适当 IAM 权限,您的容器就应该启动,并且您可以继续使用 s3 作为卷。
如果您在运行“ATTRIBUTE”任务时遇到错误,请仔细检查插件是否已成功安装在 ec2 实例上并且 ecs 代理已重新启动。还要仔细检查您的驱动程序名称是“rexray/s3fs”。
【讨论】:
s3fs-fuse 不是一个可靠的解决方案,我已经尝试过,但在很多方面都失败了。 @RobinVarghese - 我想这取决于您对可靠的定义和您的用例。 s3fs-fuse 适用于我的用例,即提供一些 s3 文件以每小时读取一次或两次。 有没有办法可以为ecs fargate
做到这一点,而不是使用ecs ec2
?
没有。 Fargate 不支持 rexray/s3fs 驱动程序。
@RobinVarghese 如果您要评论它失败的方式可能会很有用。 “在很多方面都失败了”并不能真正帮助未来的读者。【参考方案2】:
ecs集群ec2实例需要安装rexray驱动。在这篇 aws 博客文章中,他们讨论了这一点。 https://aws.amazon.com/blogs/compute/amazon-ecs-and-docker-volume-drivers-amazon-ebs/
为了帮助您入门,我们创建了一个 AWS CloudFormation 模板,用于构建一个双节点 ECS 集群。该模板将 rexray/ebs 卷驱动程序引导到每个节点上,并为它们分配一个具有内联策略的 IAM 角色,允许它们调用 REX-Ray 所需的 API 操作。
同样适用于 s3 驱动程序
【讨论】:
【参考方案3】:我已经让s3fs
在我的ECS 容器中工作,只需直接运行s3fs
命令将存储桶安装到我的容器中。我不熟悉 rexray 驱动程序,它可能比仅使用 s3fs
提供一些好处,但对于很多用例来说,这可能工作得很好并且不需要任何 UserData
编辑。
通过将容器的入口点设置为以下内容,我使它变得更顺畅了:
#!/bin/bash
bucket=my-bucket
s3fs $bucket /data -o ecs
echo "Mounted $bucket to /data"
exec "$@"
-o ecs
选项对于承担 ECS 任务角色至关重要,如果您使用常规 -o iam_role=auto
s3fs
将承担运行 ECS 代理的 EC2 实例的 IAM 角色。
请注意,ECS 任务角色需要为您尝试挂载的存储桶提供s3:GetObject
、s3:PutObject
和s3:ListObjects
IAM 操作权限。如果您希望容器对存储桶具有只读访问权限,您可以通过取消 s3:PutObject
权限在 IAM 级别强制执行该权限。您还可以使用细粒度的 IAM 资源语句来禁止或允许仅写入某些 s3 前缀。如果您尝试将文件写入 s3fs 文件系统并且它无权实际进行底层 s3 api 调用,则会引发一些丑陋的错误,但通常一切正常。
注意:apt-get install s3fs
安装的s3fs
版本较旧,在撰写本文时没有此选项,这意味着您可能需要从源代码安装s3fs
。
另请注意:您需要在特权模式下运行容器才能使 s3fs 挂载工作。
【讨论】:
有没有办法可以为ecs fargate
做到这一点,而不是使用ecs ec2
?
我相信在 fargate 上的工作应该和在基于 ec2 的 ecs 上工作一样,两者都使用相同的 ecs 执行接口,不同之处只是它运行的基础设施。话虽如此,我还没有测试过
我认为您的解决方案和 Rexray 驱动程序之间的一个区别可能是 IAM 权限所在的位置。我不确定,但我怀疑使用 Rexray 需要获得“执行角色”的权限,而您的方法需要“任务角色”的权限。如果您有时间,您介意添加一条关于设置正确 IAM 权限的说明吗?
取决于您的设置,在原始问题中使用 docker volume mounts 描述的方式是,将使用“执行角色”或 docker 主机具有的任何 IAM 角色。但是我不确定您是否甚至可以以所描述的原始方式实现运行,因为您需要使用在主机上安装了 rexray 的自定义 AMI。我一般会添加一个关于 IAM 权限的注释。【参考方案4】:
感谢@wimnat 的指导。
关于通过 LaunchConfiguration UserData 在 ECS 集群中的 Ec2 实例上安装 rexray/s3fs 插件,这就是我最终得到的结果(对于 AMI 版本 amzn-ami-2018.03.o-amazon-ecs-optimized):
#install s3fs required by rexray/s3fs docker plugin
yum install -y gcc libstdc+-devel gcc-c+ fuse fuse-devel curl-devel libxml2-devel mailcap automake openssl-devel git gcc-c++
git clone https://github.com/s3fs-fuse/s3fs-fuse
cd s3fs-fuse/
./autogen.sh
./configure --prefix=/usr --with-openssl
make
make install
#install plugin to enable s3 volumes, using the task execution role to access s3.
docker plugin install rexray/s3fs:0.11.1 S3FS_REGION=us-east-1 S3FS_OPTIONS="allow_other,iam_role=auto,umask=000" LIBSTORAGE_INTEGRATION_VOLUME_OPERATIONS_MOUNT_ROOTPATH=/ --grant-all-permissions
注意事项:
-
使用 rexray/s3fs:latest 在执行 'docker volume ls' 时会显示卷,但在安装卷时出现错误 (https://github.com/rexray/rexray/issues/1187)。
如果使用版本化的 rexray/s3fs,您需要在定义挂载时在驱动程序名称中包含该版本,即
Driver: 'rexray/s3fs:0.11.1'
要检查容器实例是否具有所需的属性,您可以使用 aws-cli:aws ecs list-attributes --cluster my-cluster --target-type container-instance --profile myprofile --attribute-name ecs。能力.docker-plugin.rexray/s3fs.0.11.1
似乎 ecs 代理在 UserData 脚本完成后启动,因此无需重新启动代理,或等待代理启动。
-
安装适用于启用默认加密 (AES256) 的存储桶。如果您使用自己的 kmskey 加密存储桶,则需要提供正确的 s3fs 选项来处理加密/解密。我没有试过这个。
【讨论】:
以上是关于在 AWS ECS 容器上挂载 S3 存储桶作为文件系统的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 IAM 角色通过 aws sdk (java) 从 ECS 容器调用 s3 存储桶
使用s3fs-fuse在AWS Linux实例上挂载S3存储桶