【问题标题】:Docker nfs4 mount on Elastic BeanstalkDocker nfs4 挂载在 Elastic Beanstalk 上
【发布时间】:2016-10-16 07:38:12
【问题描述】:

我无法访问在 Elastic Beanstalk 上运行的 docker 容器内的 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 创建一个挂载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 运行。

我错过了什么?

更新

如果我以--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 现在已按预期填充。

【问题讨论】:

    标签: amazon-web-services amazon-ec2 docker amazon-elastic-beanstalk nfs


    【解决方案1】:

    @sebastian 的“UPDATE 2”让我走上了正轨(感谢@sebastian)。

    但对于其他可能像我一样通过 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 实例并验证它是否正常工作:

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

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

    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"
        }
      ]
    }
    

    【讨论】:

    • 谢谢,这对我很有用。我唯一不明白的是你的 .config: 05restart-ecs: command: docker start ecs-agent 什么是“ecs-agent”
    • 来自github.com/aws/amazon-ecs-agent:“Amazon ECS 容器代理是为 Amazon EC2 容器服务 (Amazon ECS) 开发的软件。它在容器实例上运行并代表 Amazon ECS 启动容器。”
    • 感谢 markplindsay 添加详细信息,我没有花时间写下所有内容。
    猜你喜欢
    • 2020-11-25
    • 2020-11-14
    • 2017-07-02
    • 2014-09-08
    • 2014-12-22
    • 2015-10-23
    • 2018-06-20
    • 2017-10-14
    • 2014-12-13
    相关资源
    最近更新 更多