NFS in Docker: exportfs: <path> does not support NFS export

Viewed 10106

I'm working on a docker NFS container, but running into trouble mounting the exported directories (even on localhost).

The problem

exportfs: <path> does not support NFS export

The setup

My container uses an entrypoint script to

  • write directories (provided via command-line arguments) into /etc/exports,
  • invokes rpcbind and service nfs-kernel-server start, and
  • defers to inotifywait to remain running.

The Dockerfile is nothing special. I install inotify-tools and nfs-kernel-server, expose port 2049, and copy over the entrypoint script.

I'm using docker-machine on an El Capitan Macbook.

I map volumes from the host into the container to give the nfs server access to directories that I want to export.

Entrypoint script

modprobe nfs
modprobe nfsd

for x in ${@}; do
   echo -e "$x\t*(rw,sync,no_subtree_check,crossmnt,fsid=root,no_root_squash)" >> /etc/exports
done

source /etc/default/nfs-kernel-server
source /etc/default/nfs-common

rpcbind
service nfs-kernel-server start

exec inotifywait --monitor /exports

Debugging

Here's the setup for what I am trying to export.

%> ls $HOME/mounts
a
%> ls $HOME/mounts/a
asdf

Here's how I start the server.

%> docker run --privileged --rm --name=nfs-server --volume=$HOME/mounts/a/:/exports/a docker-nfs-server /exports/a
Exporting directories for NFS kernel daemon...exportfs: /exports/a does not support NFS export
.
Starting NFS kernel daemon: nfsd mountd.
Setting up watches.
Watches established.

And here's the debugging I've been doing while the container is running.

%> docker exec -it nfs-server bash
root@6056a33f061e:/# ls /exports
a
root@6056a33f061e:/# ls /exports/a
asdf
root@6056a33f061e:/# showmount -a
All mount points on 6056a33f061e:
root@6056a33f061e:/# exportfs -a
exportfs: /exports/a does not support NFS export
root@8ad67c951ecd:/# mount
none on / type aufs (rw,relatime,si=3ca85db062268b32,dio,dirperm1)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev type tmpfs (rw,nosuid,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,mode=755)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu type cgroup (rw,nosuid,nodev,noexec,relatime,cpu)
cgroup on /sys/fs/cgroup/cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
/dev/sda1 on /exports type ext4 (rw,relatime,data=ordered)
Users on /exports/a type vboxsf (rw,nodev,relatime)
/dev/sda1 on /etc/resolv.conf type ext4 (rw,relatime,data=ordered)
/dev/sda1 on /etc/hostname type ext4 (rw,relatime,data=ordered)
/dev/sda1 on /etc/hosts type ext4 (rw,relatime,data=ordered)
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)
nfsd on /proc/fs/nfsd type nfsd (rw,relatime)

What I know

Less than Jon Snow. I can identify a few variables that might each be responsible for my problem, but I don't know how to verify any of them:

  • $HOME/mounts/a is on an OSX filesystem
  • That filesystem is encrypted
  • /exports/a is being mounted into the docker-machine VM

I don't have enough experience with NFS to know how to debug this effectively. Any assistance or information would be appreciated.

Update

It works in Parallels!

%> docker run --privileged --rm --name=nfs-server --volume=$HOME/mounts/a/:/exports/a docker-nfs-server /exports/a
%> docker exec -it nfs-server bash
root@3786d888f039:/# mkdir --parents /imports/a
root@3786d888f039:/# mount --types nfs --options nolock,proto=tcp,port=2049 localhost:/exports/a /imports/a
root@3786d888f039:/# ls /imports
a
root@3786d888f039:/# ls /imports/a
root@3786d888f039:/# ls /exports
a
root@3786d888f039:/# ls /exports/a
root@3786d888f039:/# touch /exports/a/asdf
root@3786d888f039:/# ls /exports/a
asdf
root@3786d888f039:/# ls /imports/a/
asdf

So that narrows down the problem to OSX/docker-machine or maybe even the encrypted filesystem on OSX.

2 Answers

the problem is in the docker-machine. If you want to use nfs mounts you need to run modprobe nfs in the machine itself, not in container. Container uses kernel of the machine. Same with modprobe nfs and nfs server.

In my case it worked when the exported path was a volume specified in the dockerfile. Here is the repo where I got it working (with the replaced volume definition).

Related