Docker for MacOS optimization

By Meabed on 2018-08-19 #docker #docker-machine #mac #nfs #ntp

Introduction

From docs.docker.com

Docker for Mac uses HyperKit, a lightweight macOS virtualization solution built on top of the Hypervisor.framework. Currently, there is no docker-machine create driver for HyperKit, so use the virtualbox driver to create local machines

Working with docker on MacOS is frustrating, especially for large projects with a lot of folders and files. Because docker does nor run natively on MacOS, you get some problems with docker-machine, like NFS Volume mounting, UTC time - ntp, file permissions.

During my last 6 years working with docker on MacOS, I have developed the script below tackles few of this issues and solve them.

Solution

Several fixes on docker-machine for MacOS

  • NFS Mount file permission mapping in /etc/exports
  • Tweaked MacOS nfsd in /etc/nfs.conf
  • Tweaked NFS Mount options for docker-machine rw,noacl,nocto,noatime,nodiratime,soft,nolock,rsize=32768,wsize=32768,intr,tcp,nfsvers=3,actimeo=2
  • NFS Remount /Users/${USERNAME} dir for MacOS
  • NTPD Update to UTC
  • sysctl tweaks vm.max_map_count=262144 fs.file-max=801896 net.core.somaxconn=65535

Changes

Mac OS nfs server nfsd /etc/nfs.conf:

# This option controls whether the NFS service is advertised via Bonjour.
# The default value is 1 (on).
nfs.server.bonjour = 0

# This option controls whether MOUNT requests for non-directory objects
# will be allowed.  The default value is 0 (off).
nfs.server.mount.regular_files = 1

# This option controls whether MOUNT requests are required to originate
# from a reserved port (port < 1024).  The default value is 1 (yes).
# Many NFS server implementations require this because of the false
# belief that this requirement increases security.
nfs.server.mount.require_resv_port = 0

# This option controls how many NFS server (nfsd) threads are made
# available to service NFS requests.  The default value is 8.
nfs.server.nfsd_threads = 9

# This option specifies that the NFS server should report unstable writes
# as stable writes.  The default is 0 (off).  While enabling this option
# can improve write performance, it will also put data integrity at risk
# because the NFS client will be told that data is on stable storage
# before it actually is.  The data may be lost if the NFS server crashes.
nfs.server.async = 1

NFS mounting client options from inside the docker-machine

# noacl: Disables Access Control List (ACL) processing.
noacl

# nocto: Suppress the retrieval of new attributes when creating a file
nocto

# noatime: Setting this value disables the NFS server from updating the inodes access time.
# As most applications do not necessarily need this value, you can safely disable this updating.
noatime

# nodiratime: Setting this value disables the NFS server from updating the directory access time.
# This is the directory equivalent setting of noatime.
nodiratime

# Specify soft if the server is unreliable and you want to prevent systems from hanging when the server is down. When NFS tries to access a soft-mounted directory,
# it gives up and returns an error message after trying retrans times (see the retrans option, later).
# Any processes using the mounted directory will return errors if the server goes down.
soft

#nolock — Disables file locking. This setting is occasionally required when connecting to older NFS servers.
nolock

# rsize: The number of bytes NFS uses when reading files from an NFS server.
# The rsize is negotiated between the server and client to determine the largest block size that both can support.
# The value specified by this option is the maximum size that could be used; however, the actual size used may be smaller.
# Note: Setting this size to a value less than the largest supported block size will adversely affect performance.
rsize=32768

# wsize: The number of bytes NFS uses when writing files to an NFS server.
# The wsize is negotiated between the server and client to determine the largest block size that both can support.
# The value specified by this option is the maximum size that could be used; however, the actual size used may be smaller.
# Note: Setting this size to a value less than the largest supported block size will adversely affect performance.
wsize=32768

# intr — Allows NFS requests to be interrupted if the server goes down or cannot be reached.
intr

# tcp — Specifies for the NFS mount to use the TCP protocol.
tcp

# Specifies which version of the NFS protocol to use
nfsvers=3

# attribute caches will time out in 1 seconds
actimeo=2

Sysctl options

# This file contains the maximum number of memory map areas a process may have.
# Memory map areas are used as a side-effect of calling malloc,
# directly by mmap and mprotect, and also when loading shared libraries.
vm.max_map_count=262144

# Increase size of file handles and inode cache
fs.file-max=801896

# Increase number of incoming connections
net.core.somaxconn=65535

NTP settings

ntpd -p pool.ntp.org > /dev/null

putting it all together in bootlocal.sh which is file that execute every time docker-machine starts in the path /var/lib/boot2docker/bootlocal.sh

sudo sysctl -w vm.max_map_count=262144
sudo sysctl -w fs.file-max=801896
sudo sysctl -w net.core.somaxconn=65535
echo 'Un-mounting ${WKSDIR}'
sudo umount -f ${WKSDIR} 2> /dev/null
echo 'Starting docker-machine nfs-client'
sudo /usr/local/etc/init.d/nfs-client start 2> /dev/null
echo 'Mounting ${WKSDIR}'
sudo mkdir -p ${WKSDIR}
sudo mount -t nfs -o rw,noacl,nocto,noatime,nodiratime,soft,nolock,rsize=32768,wsize=32768,intr,tcp,nfsvers=3,actimeo=2 $B2D_NET:${WKSDIR} ${WKSDIR}
echo 'Mounted ${WKSDIR}'
sudo killall -9 ntpd
sudo ntpclient -s -h pool.ntp.org > /dev/null
sudo ntpd -p pool.ntp.org > /dev/null
echo docker-machine-date is: `date`

How to use

wget:

wget -O docker_machine_mount_nfs.sh https://raw.githubusercontent.com/me-io/docker-machine-mac-nfs-mount/master/docker_machine_mount_nfs.sh
sudo bash ./docker_machine_mount_nfs.sh default

curl:

curl -o docker_machine_mount_nfs.sh https://raw.githubusercontent.com/me-io/docker-machine-mac-nfs-mount/master/docker_machine_mount_nfs.sh
sudo bash ./docker_machine_mount_nfs.sh default

Check Github Repo Here

Please feel free to contribute and discuss issues and fixes

...