关于amazon web services:Docker nfs4 mount on Elastic Beanstalk

Docker nfs4 mount on Elastic Beanstalk

我无法访问在 Elastic Beanstalk 上运行的 docker 容器内的 nfs4 共享。

Netshare 在运行 Docker 容器的 EC2 实例上启动并运行。在实例上手动挂载 nfs 共享有效,我可以毫无问题地访问 EC2 实例上的共享。

但是,当我运行一个容器,尝试挂载一个 nfs4 卷时,文件没有出现在容器内。

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

1
2
3
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 创建挂载 nfs4 共享的卷:

1
2
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 守护进程,这很有效:

1
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 的内容 - 但它是空的?!

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

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

1
2
3
4
[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.

运行

我错过了什么?

更新

如果我以 --privileged 模式启动容器,则可以直接在容器内安装 nfs 共享:

1
2
3
4
5
6
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

这是另一种解决方法:

  • 将主机上的 nfs 共享挂载到 /target
  • 在主机上重启 docker
  • 运行容器 docker run -it -v /target:/mnt image /bin/bash
  • /mnt 现在按预期填充。


    @sebastian\\'s "UPDATE 2" 让我走上了正轨(感谢@sebastian)。

    但是对于其他可能像我一样通过 Google 解决这个问题的人,这正是我能够在 Elastic Beanstalk 上自动挂载 EFS (NFSv4) 文件系统并使其可用于容器的方法。

    添加这个 .config 文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # .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 实例并验证它是否工作:

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

    您应该会在您的 EFS 文件系统中看到这些文件。但是,您仍然需要验证挂载在容器内是否可读写。

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

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

    1
    2
    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 文件。

    1
    ls -la /mnt/efs

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

    最后,这是您在 Dockerrun.aws.json 中使用 -v /mnt/efs:/nfs 的方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    {
     "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"
        }
      ]
    }