Docker 在 Elastic Beanstalk 上挂载 nfs4
Docker nfs4 mount on Elastic Beanstalk
我无法访问 docker 容器内的 nfs4 共享,运行ing 在 Elastic Beanstalk 上。
Netshare 已启动并且 运行 在 EC2 实例上 运行 正在 Docker 容器上。在实例上手动挂载 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
user/group。 docker 容器 运行ning 为 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
这是另一个解决方法:
- 将主机上的 nfs 共享挂载到
/target
- 在主机上重新启动 docker
- 运行 容器
docker run -it -v /target:/mnt image /bin/bash
/mnt
现在已按预期填充。
@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"
}
]
}
我无法访问 docker 容器内的 nfs4 共享,运行ing 在 Elastic Beanstalk 上。
Netshare 已启动并且 运行 在 EC2 实例上 运行 正在 Docker 容器上。在实例上手动挂载 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
user/group。 docker 容器 运行ning 为 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
这是另一个解决方法:
- 将主机上的 nfs 共享挂载到
/target
- 在主机上重新启动 docker
- 运行 容器
docker run -it -v /target:/mnt image /bin/bash
/mnt
现在已按预期填充。
@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"
}
]
}