Skip to content

Instantly share code, notes, and snippets.

@pedroamador
Forked from rwenz3l/proxmox_lxc_nfs_server.md
Created October 13, 2019 18:03
Show Gist options
  • Save pedroamador/dec94897537ef025945f1b96c97fcf59 to your computer and use it in GitHub Desktop.
Save pedroamador/dec94897537ef025945f1b96c97fcf59 to your computer and use it in GitHub Desktop.
Install a NFS Server inside a LXC Container on Proxmox 5.1

Installing NFS inside LXC Container on Proxmox 5.1

Host Setup:

Create LXC Container as usual, but do not start it yet.

# Install NFS-Kernel on Host
apt install nfs-kernel-server

# Create a new AppArmor file: 
touch /etc/apparmor.d/lxc/lxc-default-with-nfsd

# Write Profile:
cat > /etc/apparmor.d/lxc/lxc-default-with-nfsd << 'EOF'
# Do not load this file.  Rather, load /etc/apparmor.d/lxc-containers, which
# will source all profiles under /etc/apparmor.d/lxc

profile lxc-container-default-with-nfsd flags=(attach_disconnected,mediate_deleted) {
  #include <abstractions/lxc/container-base>

  # the container may never be allowed to mount devpts.  If it does, it
  # will remount the host's devpts.  We could allow it to do it with
  # the newinstance option (but, right now, we don't).
  deny mount fstype=devpts,
  mount fstype=nfsd,
  mount fstype=rpc_pipefs,
  mount fstype=cgroup -> /sys/fs/cgroup/**,
}
EOF

# Activate the new Profile:
apparmor_parser -r /etc/apparmor.d/lxc-containers

# Add Profile to Container:
# (in this case: id = 200)
echo 'lxc.apparmor.profile = lxc-container-default-with-nfsd' \
  >> /etc/pve/nodes/sniebel/lxc/200.conf

# As well as to it's config:
echo 'lxc.apparmor.profile = lxc-container-default-with-nfsd' \
  >> /var/lib/lxc/200/config
  
# Also add your mountpoint to the container:
# If you have a cluster setup:
echo 'mp0: /mnt/host_storage,mp=/mnt/container_storage' \
  >> /etc/pve/nodes/cluster_node/lxc/200.conf

# If you have a single node setup:
echo 'mp0: /mnt/host_storage,mp=/mnt/container_storage' \
  >> /etc/pve/lxc/200.conf

# Finall start the container:
lxc-start -n 200

Container Setup:

ssh into the container or do a simple lxc-attach -n 200 on your host (where 200 is the id).

# Install nfs
apt update
apt install nfs-kernel-server

# Edit Exports
nano /etc/exports

# or append like so (example):
echo '/mnt/container_storage 192.168.0.0/16(rw,async,insecure,no_subtree_check,all_squash,anonuid=501,anongid=100,fsid=1)' \
  >> /etc/exports

# disconnect from the container

# Restart it:

Host again:

Back on the Host restart the container:

lxc-stop -n 200
lxc-start -n 200

Because the nfs-kernel is on the host, the container cannot access it's status. service nfsd status therefore shows as 'not running' inside the container. .. this seems to be normal (?)


Further useful commands:

nfsstat # list NFS statistics
@pedroamador
Copy link
Author

I have the NFS over LXC running in a pve 7 server, based on a new created lxc instance

Here's my config:

# cat 10020.conf 
arch: amd64
cores: 4
features: fuse=1,nesting=1
hostname: file
memory: 2048
nameserver: 10.0.0.1
net0: name=eth0,bridge=vmbr1,firewall=1,gw=10.0.0.1,hwaddr=******,ip=10.0.0.20/24,type=veth
ostype: ubuntu
rootfs: data:subvol-10020-disk-0,size=100G
searchdomain: local
swap: 2048

You can't use "unprivileged container" for this, so uncheck the option (or do a "vzdump" and "pct restore -unprivileged 0"). The rest of the config is the same, installing "nfs-kernel-server" on the LXC instance and... it's all :)

In the LXC instance:

root@file:~# lsmod|grep nfs
nfsd                  405504  13
auth_rpcgss            94208  2 nfsd,rpcsec_gss_krb5
nfs_acl                16384  1 nfsd
lockd                 102400  1 nfsd
grace                  16384  2 nfsd,lockd
sunrpc                393216  20 nfsd,auth_rpcgss,lockd,rpcsec_gss_krb5,nfs_acl
root@file:~# cat /etc/exports 
# /etc/exports: the access control list for filesystems which may be exported
#		to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)
#
/mnt/container_storage 10.0.0.0/24(rw,async,insecure,no_subtree_check,no_root_squash)
root@file:~# rpcinfo | egrep "service|nfs"
   program version netid     address                service    owner
    100003    3    tcp       0.0.0.0.8.1            nfs        superuser
    100003    4    tcp       0.0.0.0.8.1            nfs        superuser
    100003    3    udp       0.0.0.0.8.1            nfs        superuser
    100003    3    tcp6      ::.8.1                 nfs        superuser
    100003    4    tcp6      ::.8.1                 nfs        superuser
    100003    3    udp6      ::.8.1                 nfs        superuser

In a KVM instance client with this directory mounted:

root@client:~# mount -t nfs file:/mnt/container_storage /mnt/container_storage/
root@client:~# df -h /mnt/container_storage/
Filesystem                        Size  Used Avail Use% Mounted on
file:/mnt/container_storage  100G  831M  100G   1% /mnt/container_storage

@MrColumbo
Copy link

thanks a lot - i thought with the options it will work on an unprivileged container as well but I was obviously wrong. Now it works for me as well.

@pedroamador
Copy link
Author

Great :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment