DockerCon EU 2017: day two
Table of Contents
These are my notes of my second day at DockerCon.
Just as with yesterday’s notes, these are just notes and not summaries.
General session
The general session was mostly devoted to modernizing traditional applications, saving costs and customer success stories.
Tips and Tricks of the Docker Captains — Adrian Mouat (Container Solutions)
Several small tips and tricks.
Daily development
You can configure the output of the “docker ps
” or “docker container ls
” commands with the “--format
” argument. You can also
put your preference for the formatting in your ~/.docker/config.json
file under the psFormat
property (see the documentation on
configuration files. Warning,
this file also contains your passwords to Docker registries so do not
put it online.
Cleaning up:
- Remove dangling images:
docker image prune
- Remove stopped containers:
docker container prune
- Remove unused volumes:
docker volume prune
- Remove unused networks:
docker network prune
- Remove all of the above:
docker system prune
Building images
The “.
” at the end of a Docker build
command means that the target
(the current directory in this case) is sent to the Docker Daemon as a
tarball. Use the .dockerignore
file to exclude large directories.
Alpine is pretty small (5MB). Couple of gotchas though, like:
- uses
musl
instead ofglibc
- uses its own package manager
If you are looking for an alternative, have a look at the Debian Slim
images like debian:stretch-slim
. They are (at the moment) 30MB or
smaller.
If you build static binaries, you can put the binary in the scratch
image. Since there is no operating system on top of the kernel, you
cannot use user names. You can use IDs, USER 65534
maps to the the
“nobody” user.
Container lifecycle
Do not require containers to start in sequence. Instead have a container wait for a service it depends on (including backoff) and include this in the application itself or in a startup script.
When Docker stops a container, it sends a SIGTERM
signal, waits for
10 seconds and then hard kills the container with a SIGKILL
. If the
latter happens, you cannot tidy up properly (e.g. close network
connections, write a final log entry, etc). So try to prevent this.
Tini, used for signal forwarding, is integrated in Docker now.
A benefit of healthchecks is that Swarm will only route to healthy
containers. Note that healthchecks are run inside the container
itself, not on the host. This might mean you will have to install more
software in your image (e.g. curl
).
Security
To improve security, use a read-only file system by adding
--read-only
to the run
command. Use a
tmpfs mount to
create writeable locations where applications can write e.g. pid
files. The data written to the tmpfs mounts is kept in memory and not
stored persistently on the host.
Users are not namespaced (by default). If an attacker breaks out of
the container via service running as root, the attacker is also root
on the host. So do not run as root! Create and set a USER
in your
Dockerfile
or use the nobody
user.
To prevent using sudo
, use gosu
instead.
It’s nearly always a bad idea to run Docker in Docker (issues with
file systems and caching, image stores). Instead, mount the Docker
socket with “-v /var/run/docker.sock:/var/run/docker.sock
”. Be
aware: this is a security problem because there is less isolation
between the container and the host.
Alpine Linux under the microscope — Natanael Copa (Docker)
Alpine Linux uses the MIT licensed musl libc which has a clean, modern codebase and is lightweight. It’s small, so what is missing?
- Some GNU extensions
- Lots of localization data
- GNU bloat
- Name Service Switch (NSS)
- Network Services Library (libnsl)
- 80+ CVEs ;-)
Busybox is also part of Alpine Linux. It includes most of POSIX’s shells and utilities. It’s pretty impressive how many tools are squeezed into ~800KB.
Alpine created apk-tools because the traditional package managers were not fast enough. It is faster than other package managers because it is designed to read once and write once (compared to minimal 3 reads and 2 writes).
The --no-cache
option was added to the package manager specifically
for Docker. It does not store cache information on disk. If you use
this flag, you do not need a cleanup step (in contrast to when you are
using apt
).
With regards to security:
- Alpine uses secure defaults
- Has a smaller attack surface
- Uses more secure components (musl, libressl)
- Has a hardened kernel (unofficial fork of grsecurity)
When not to use Alpine? If you:
- Depend on precompiled (closed source) binaries
- Need good localization
- Want commercial support
- Need glibc/GNU specific behaviour
Practical design patterns in Docker networking — Dan Finneran (Docker)
Several types of network drivers:
-
Null: you can use this to black hole your container.
-
Host: simplest, come out of the box (use
--net=host
). The container will connect its ports to the host. -
Bridge: no flags needed (the default), connect to the internal bridge network. Containers can speak with each other, but nothing can speak with them or the other way around.
Using the
-p
flag you can expose ports. Only expose services that need to be exposed. -
Swarm overlay networking: using VXLAN to create overlay network over the underlying network. The network is encrypted by default.
A relatively new addition is the macvlan driver. It provides a hardware address to each container. You’ll want this if you need to connect to a VLAN network or have to deal with IPAM. It requires promiscuous mode.
The macvlan driver essentially makes a Docker container a first class citizen on the network.
You can have a separate data and control plane in your network on hosts with multiple NICs. This provides physical and logical separation of traffic.