← previous: Understanding Docker Container ecosystem next: Running Docker Containers on DigitalOcean →

Running Docker on Mac

Sachin Verma

in

Docker is currently amongst the most important projects on github. There is enthusiasm from both the enterprise and the developers. In my previous post, i described the container ecosystem from a top level view. In this post i would detail how Docker containers run on Mac. My goal is to help the readers understand what is happening behind the scenes when you run containers on Mac.

Mac is used heavily by developers and hence is an important platform when it comes to testing/running tools like containers. Setting up a Docker container environment on your local machine is extremely useful to play and understand the working of the technology without incurring cost of the cloud or another Linux machine.


Docker for Mac Internals


Setting up your Mac

Before i jump in to the details, i want to emphasize the fact that containers is a Linux technology and we can run it only on a Linux machine. Hence, if we want to run docker containers on a non-Linux platform like Mac or Windows, we need to install and run a virtual Linux machine. "Docker for Mac" is one such toolset which creates the required environment on a Mac Machine. You can install the toolset from the docker website.

When we install "Docker for Mac" Application for Mac, it broadly sets up the following:

  • Hyperkit: A lightweight Hypervisor optimized for Mac.
  • Docker Client utilities: A set of utilities which enables interaction with the Linux Hosts which are running the docker engine.

What are these docker client utilities?

  • When you install Docker for Mac, following client utility binaries are installed on your machine:
$ ls -1 /Applications/Docker.app/Contents/Resources/bin/
docker
docker-compose
docker-diagnose
docker-machine
notary
  • Lets briefly go through these:

    1. docker: This is the most used client utility when you are running single containers.It has feature rich command line options which encapsulates the underlying REST API communication with the Docker Engine via Unix/TCP sockets. Some of the most common tasks you would be performing with this utility is to create, start, stop, inspect or kill a container. For exploring the options see the output of docker --help
    2. docker-compose: This utility is used when you start building multi-container applications. You can specify the rules of how you want to build your container images via configuration files. You can specify dependencies between containers, setup network , storage and other important rules. Like docker utility, it allows you to communicate with your multi containers via Docker Engine using the REST APIS.
    3. docker-machine: This utility allows you to orchestrate the provisioning of the Linux machines which are running the docker engine. It manages all the details of the machine, helps set up communication links like ssh with the machine. It is quite sophisticated and can easily help deployment on swarm clusters.
    4. notary: It allows the creation and management of collections of signed targets, allowing the signing and validation of arbitrary content.

Start the "Docker for Mac" Application

  • when you start the Docker for Mac Application, it does following:
    • Starts a lightweight Hypervisor called Hyperkit.
    • Boots Moby Linux (a variant of Alpine Linux) on top of Hyperkit.
    • Starts Docker engine in Moby Linux which waits for commands coming through the REST interface.
    • Creates a unix socket /var/run/docker.sock which allows communication between docker engine running on Moby Linux and docker client utilities running natively on MAC.

Docker Application startup


Lets See what our docker engine running on Moby Linux tells us

$ docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 32
Server Version: 1.12.3
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 42
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge null host overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: seccomp
Kernel Version: 4.4.27-moby
Operating System: Alpine Linux v3.4
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.951 GiB
Name: moby
ID: IWVR:LSON:ALSQ:TC4Z:K5IG:22CR:EYPH:FBYP:XIC3:ETWM:V3JE:YORY
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): true
 File Descriptors: 15
 Goroutines: 27
 System Time: 2017-03-02T20:36:55.387642818Z
 EventsListeners: 1
No Proxy: *.local, 169.254/16
Registry: https://index.docker.io/v1/
WARNING: No kernel memory limit support
Insecure Registries:
 127.0.0.0/8

What if you want to use a different Hypervisor?

docker-machine allows you to make use of different hypervisors for provisioning a Linux machine. You could for instance easily make use of virtualbox as your hypervisor. By default it would boot a Linux image boot2docker which is small ~27 Mb image based on Tiny Core Linux.

docker-machine create --driver virtualbox dicomDev
  • Name 'dicomDev' would be assigned to the newly provisioned machine.
  • You can now start the machine 'dicomDev' using following command:
$ docker-machine start dicomDev
Starting "dicomDev"...
(dicomDev) Check network to re-create if needed...
(dicomDev) Waiting for an IP...
Machine "dicomDev" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

Set up the environment variables for the communication

$ eval $(docker-machine env dicomDev)

Lets see what environment variables have been set up

$ env | grep DOCKER
DOCKER_HOST=tcp://192.168.99.100:2376
DOCKER_MACHINE_NAME=dicomDev
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/Users/sachinv/.docker/machine/machines/dicomDev
  • Docker utilities for mac would now make use of these environment variables for selecting the right host and configuration to communicate with.

Lets see what does the docker engine running on this newly provisioned Linux machine (dicomDev) replies

$ docker info
Containers: 5
 Running: 2
 Paused: 0
 Stopped: 3
Images: 29
Server Version: 1.13.1
Storage Driver: aufs
 Root Dir: /mnt/sda1/var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 47
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: seccomp
Kernel Version: 4.4.47-boot2docker
Operating System: Boot2Docker 1.13.1 (TCL 7.2); HEAD : b7f6033 - Wed Feb  8 20:31:48 UTC 2017
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 995.8 MiB
Name: dicomDev
ID: HA3O:ATGR:5RHC:DAFQ:WZ7E:OFLC:IS42:MJXH:RYIC:AH4A:XEFG:FZAZ
Docker Root Dir: /mnt/sda1/var/lib/docker
Debug Mode (client): false
Debug Mode (server): true
 File Descriptors: 28
 Goroutines: 34
 System Time: 2017-03-28T04:18:49.155943822Z
 EventsListeners: 0
Registry: https://index.docker.io/v1/
Labels:
 provider=virtualbox
Insecure Registries:
 127.0.0.0/8
  • You can notice in the info provided by the newly provisioned machine is different from the default machine provisioned by docker using Hyperkit and mobylinux. In this case the provider is virtualbox
  • I have been experimenting with this configuration, so it shows few containers running.

Going Forward

With this article, we explored how Docker containers for Mac works. This is a very quick and cost-effective way to build your concepts on docker containers before jumping in to resource intensive deployments. In my upcoming article i would talk about how you can provision the containers on a cloud using docker for mac native utilities.

← previous: Understanding Docker Container ecosystem next: Running Docker Containers on DigitalOcean →