Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
ehough committed Jan 31, 2019
2 parents b94f257 + 148363c commit 3919a98
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [2.1.0] - 2019-10-31
### Added
* Ability to automatically load kernel modules. ([#18](https://github.com/ehough/docker-nfs-server/issues/18)). Credit to [@andyneff](https://github.com/andyneff).
### Fixed
* Minor bugs in `entrypoint.sh`

## [2.0.0] - 2019-01-31

### Changed
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This is the only containerized NFS server that offers **all** of the following f
* [NFSv4 user ID mapping](doc/feature/nfsv4-user-id-mapping.md)
* [AppArmor integration](doc/feature/apparmor.md)
* Advanced
* [automatically load required kernel modules](doc/feature/auto-load-kernel-modules.md)
* [custom server ports](doc/advanced/ports.md)
* [custom NFS versions offered](doc/advanced/nfs-versions.md)
* [performance tuning](doc/advanced/performance-tuning.md)
Expand All @@ -42,7 +43,11 @@ This is the only containerized NFS server that offers **all** of the following f
- `nfsd`
- `rpcsec_gss_krb5` (*only if Kerberos is used*)

Usually you can enable these modules with: `modprobe {nfs,nfsd,rpcsec_gss_krb5}`
You can manually enable these modules on the Docker host with:

`modprobe {nfs,nfsd,rpcsec_gss_krb5}`

or you can just allow the container to [load them automatically](doc/feature/auto-load-kernel-modules.md).
1. The container will need to run with `CAP_SYS_ADMIN` (or `--privileged`). This is necessary as the server needs to mount several filesystems *inside* the container to support its operation, and performing mounts from inside a container is impossible without these capabilities.
1. The container will need local access to the files you'd like to serve via NFS. You can use Docker volumes, bind mounts, files baked into a custom image, or virtually any other means of supplying files to a Docker container.

Expand Down Expand Up @@ -145,6 +150,7 @@ If you pay close attention to each of the items in this section, the server shou

## Advanced

* [automatically load required kernel modules](doc/feature/auto-load-kernel-modules.md)
* [customizing which ports are used](doc/advanced/ports.md)
* [customizing NFS versions offered](doc/advanced/nfs-versions.md)
* [performance tuning](doc/advanced/performance-tuning.md)
Expand Down
26 changes: 26 additions & 0 deletions doc/feature/auto-load-kernel-modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Automatically load required kernel modules

*Credit to Andy Neff [@andyneff](https://github.com/andyneff) for this idea.*

As noted in the `README`, the Docker host kernel needs a few modules for proper operation of an NFS server. You can manually enable these on the host - i.e. with `modprobe` - or you can allow the container to do this on your behalf. Here's how:

1. Add `--cap-add SYS_MODULE` to your Docker run command to allow the container to load/unload kernel modules.
1. Bind-mount the Docker host's `/lib/modules` directory into the container. e.g. `-v /lib/modules:/lib/modules:ro`

Here's an example `docker-compose.yml`:

```YAML
version: 3
services:
nfs:
image: erichough/nfs-server
volumes:
- /path/to/share:/nfs
- /path/to/exports.txt:/etc/exports:ro
- /lib/modules:/lib/modules:ro
cap_add:
- SYS_ADMIN
- SYS_MODULE
ports:
- 2049:2049
```
50 changes: 41 additions & 9 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,27 @@ is_idmapd_enabled() {
return 1
}

is_kernel_module_loaded() {

local -r module=$1

if lsmod | grep -Eq "^$module\\s+" || [[ -d "/sys/module/$module" ]]; then
log "kernel module $module is loaded"
return 0
fi

log "kernel module $module is missing"
return 1
}

has_linux_capability() {

if capsh --print | grep -Eq "^Current: = .*,?${1}(,|$)"; then
return 0
fi

return 1
}

######################################################################################
### runtime configuration assertions
Expand All @@ -279,11 +300,21 @@ assert_kernel_mod() {

local -r module=$1

log "checking for presence of kernel module: $module"
if is_kernel_module_loaded "$module"; then
return
fi

if [[ ! -d /lib/modules ]] || ! has_linux_capability 'sys_module'; then
bail "$module module is not loaded in the Docker host's kernel (try: modprobe $module)"
fi

lsmod | grep -Eq "^$module\\s+" || [ -d "/sys/module/$module" ]
log "attempting to load kernel module $module"
modprobe -v "$module"
on_failure bail "unable to dynamically load kernel module $module. try modproble $module on the Docker host"

on_failure bail "$module module is not loaded in the Docker host's kernel (try: modprobe $module)"
if ! is_kernel_module_loaded "$module"; then
bail "modprobe claims that it loaded kernel module $module, but it still appears to be missing"
fi
}

assert_port() {
Expand All @@ -303,7 +334,7 @@ assert_nfs_version() {
echo "$requested_version" | grep -Eq '^3|4(\.[1-2])?$'
on_failure bail "please set $ENV_VAR_NFS_VERSION to one of: 4.2, 4.1, 4, 3"

if [[ ( ! is_nfs3_enabled ) && "$requested_version" = '3' ]]; then
if ! is_nfs3_enabled && [[ "$requested_version" = '3' ]]; then
bail 'you cannot simultaneously enable and disable NFS version 3'
fi
}
Expand All @@ -322,10 +353,11 @@ assert_at_least_one_export() {
on_failure bail "$PATH_FILE_ETC_EXPORTS has no exports"
}

assert_linux_capabilities() {
assert_cap_sysadmin() {

capsh --print | grep -Eq "^Current: = .*,?cap_sys_admin(,|$)"
on_failure bail 'missing CAP_SYS_ADMIN. be sure to run this image with --cap-add SYS_ADMIN or --privileged'
if ! has_linux_capability 'cap_sys_admin'; then
bail 'missing CAP_SYS_ADMIN. be sure to run this image with --cap-add SYS_ADMIN or --privileged'
fi
}


Expand Down Expand Up @@ -424,7 +456,7 @@ init_assertions() {
assert_at_least_one_export

# ensure we have CAP_SYS_ADMIN
assert_linux_capabilities
assert_cap_sysadmin

# perform Kerberos assertions
if is_kerberos_enabled; then
Expand Down Expand Up @@ -588,7 +620,7 @@ summarize_nfs_versions() {
;;
esac

if [[ is_nfs3_enabled && "$reqd_version" =~ ^4 ]]; then
if is_nfs3_enabled && [[ "$reqd_version" =~ ^4 ]]; then
versions="$versions, 3"
fi

Expand Down

0 comments on commit 3919a98

Please sign in to comment.