在Elastic Beanstalk上挂载Docker nfs4

我被困在一个Docker容器中,在Elastic Beanstalk上运行,访问一个nfs4共享。

Netshare在运行Docker容器的EC2实例上运行。 在实例上手动安装nfs共享,我可以毫无问题地访问EC2实例上的共享。

但是,当我运行一个容器,试图挂载nfs4卷时,这些文件不会出现在容器内。

我这样做 首先,启动Docker主机上的netshare守护进程:

sudo ./docker-volume-netshare nfs INFO[0000] == docker-volume-netshare :: Version: 0.18 - Built: 2016-05-27T20:14:07-07:00 == INFO[0000] Starting NFS Version 4 :: options: '' 

然后,在Docker主机上,启动Docker容器。 使用-v创build挂载nfs4共享的卷:

 sudo docker run --volume-driver=nfs -v ec2-xxx-xxx-xxx-xxx.us-west-2.compute.amazonaws.com/home/ec2-user/nfs-share/templates:/home/ec2-user/xxx -ti aws_beanstalk/current-app /bin/bash root@0a0c3de8a97e:/usr/src/app# 

根据netshare守护进程,这有效:

 INFO[0353] Mounting NFS volume ec2-xxx-xxx-xxx-xxx.us-west-2.compute.amazonaws.com:/home/ec2-user/nfs-share/templates on /var/lib/docker-volumes/netshare/nfs/ec2-xxx-xxx-xxx-xxx.us-west-2.compute.amazonaws.com/home/ec2-user/nfs-share/templates 

因此,我尝试在新启动的容器中列出/home/ec2-user/xxx的内容 – 但它是空的?

 root@0a0c3de8a97e:/usr/src/app# ls /home/ec2-user/xxx/ root@0a0c3de8a97e:/usr/src/app# 

奇怪的是,nfs卷已经正确地安装在主机上:

 [ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo ls -lh /var/lib/docker-volumes/netshare/nfs/ec2-xxx-xxx-xxx-xxx.us-west-2.compute.amazonaws.com/home/ec2-user/nfs-share/templates | head -3 total 924K drwxr-xr-x 5 ec2-user ec2-user 4,0K 29. Dez 14:12 file1 drwxr-xr-x 4 ec2-user ec2-user 4,0K 9. Mai 17:20 file2 

这可能是一个权限问题? nfs服务器和客户端都使用ec2-user用户/组。 docker容器以root身份运行。

我错过了什么?

UPDATE

如果我以 – --privileged模式启动容器,直接在容器中安装nfs共享成为可能:

 sudo docker run --privileged -it aws_beanstalk/current-app /bin/bash mount -t nfs4 ec2-xxxx-xxxx-xxxx-xxxx.us-west-2.compute.amazonaws.com:/home/ec2-user/nfs-share/templates /mnt/ ls -lh /mnt | head -3 total 924K drwxr-xr-x 5 500 500 4.0K Dec 29 14:12 file1 drwxr-xr-x 4 500 500 4.0K May 9 17:20 file2 

不幸的是,这并不能解决问题,因为Elastic Beanstalk不允许特权容器(不像ECS)。

更新2

这是另一个解决方法:

  1. 将主机上的nfs共享挂载到/target
  2. 重启主机上的docker
  3. 运行容器docker run -it -v /target:/mnt image /bin/bash

/mnt现在按预期填充。

@塞巴斯蒂安的“更新2”让我在正确的轨道(谢谢@塞巴斯蒂安)。

但对于像我这样可能通过Google来解决这个问题的其他人来说,我正是如何在Elastic Beanstalk上自动挂载一个EFS(NFSv4)文件系统并将其提供给容器。

添加这个.config文件:

 # .ebextensions/01-efs-mount.config commands: 01umount: command: umount /mnt/efs ignoreErrors: true 02mkdir: command: mkdir /mnt/efs ignoreErrors: true 03mount: command: mount -t nfs4 -o vers=4.1 $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).EFS_FILE_SYSTEM_ID.efs.AWS_REGION.amazonaws.com:/ /mnt/efs 04restart-docker: command: service docker stop && service docker start 05restart-ecs: command: docker start ecs-agent 

然后eb deploy 。 部署完成后,将SSH连接到您的EB EC2实例并validation它是否有效:

 ssh ec2-user@YOUR_INSTANCE_IP ls -la /mnt/efs 

你应该看到你的EFS文件系统中的文件。 但是,您仍然需要validation装载在容器中是可读写的。

 sudo docker run -v /mnt/efs:/nfs debian:jessie ls -la /nfs 

你应该看到相同的文件列表。

 sudo docker run -v /mnt/efs:/nfs debian:jessie touch /nfs/hello sudo docker run -v /mnt/efs:/nfs debian:jessie ls -la /nfs 

你应该看到文件列表加上新的hello文件。

 ls -la /mnt/efs 

你也应该在容器外看到hello文件。

最后,在Dockerrun.aws.json使用-v /mnt/efs:/nfs

 { "AWSEBDockerrunVersion": 2, "containerDefinitions": [ { "image": "AWS_ID.dkr.ecr.AWS_REGION.amazonaws.com/myimage:latest", "memory": 128, "mountPoints": [ { "containerPath": "/nfs", "sourceVolume": "efs" } ], "name": "myimage" } ], "volumes": [ { "host": { "sourcePath": "/mnt/efs" }, "name": "efs" } ] }