This repo is about Docker Containers. Notes and commands.
It is an isolated instance of user space
- Each container has its own copy of the root filesystem.
- Each container has a process tree.
- Each container of network stack.
But how can we achieve this? By Kernel namespaces Kernel Namespaces allow us to partition various different aspects of the operating system
- The PID Namespace (process tree)
- The net Namespace (networking)
- The mnt Namespace (filesystem and mount)
- The user Namespace (user)
The user namespace, allows us to have user accounts that have root priviledges inside the container, but not outside of the container.
From the point of view of the host, it is one process tree. But each container has its own kernel namespace that act like a walls. The walls shield each container from seeing another's container namespace.
For more info Kernel namespaces
Linux kernels have a feature called control groups (cgroups). It allows to group together resources and apply limits. We map each container to a cgroup and then we set limits on resources like CPU and memory.
For more info Control Groups
Another kernel feature for containers. At a high level, capabilitites gives us fine grain control over what priviliges a user or process gets. So, instead of the "all or nothing" approach of being root or not, we use capabilitites. With capabilitites, we take all those priviledged of the root user, and breaks them down into smaller priviledges.
Container root capabilities
- CAP_AUDIT_CONTROL
- CAP_CHOWN
- CAP_DAC_OVERRIDE
- CAP_KILL
- CAP_NET_BIND_SERVICE
- CAP_SETUID
For more info Kernel Capabilities
Docker is both as company and a container runtime. Docker leverages (bring together) Linux namespaces, cgroups and capabilities into a product. Docker is a software tool chain for managing LXC containers. Docker is written in the go programming language by Google.
What is the difference between Docker and Linux LXC?
- Docker used to reply on and depend on LXC versions.
- Docker does not control LXC development.
Docker decided to write an open-source execution driver called libcontainer.
So Docker sees libcontainer
as the LXC.
Furthermore, libcontainer
allows Docker to go cross-platform. Thus, libcontainer
is the default execution driver for Docker.
- Container Engine
- Registry
- Tools
The container will work on any cloud/laptop/VM that has the Docker Engine(runtime)
- Docker Engine (Docker daemon, Docker runtime) -> Shipping yard
- Docker Images -> Shipping container manifest
- Docker Container -> Shipping containers.
- Containers are to virtual machines as threads are to processes.
- Containers virtualize at the operating system level, Hypervisors virtualize at the hardware level.
- Hypervisors abstract the operating system from hardware, containers abstract the application from the operation system.
- Hypervisors consumes storage space for each instance. Containers use a single storage space plus smaller deltas for each layer and thus are much more efficient.
- Containers can boot and be application-ready in less than 500ms and creates new designs opportunities for rapid scaling. Hypervisors boot according to the OS typically 20 seconds, depending on storage speed.
- Containers have built-in and high value APIs for cloud orchestration. Hypervisors have lower quality APIs that have limited cloud orchestration value.
- Linux. Minimum kernel 3.10.x or newer. Easy install script by Docker
curl -sSL https://get.docker.com/ | sh
- OSX. Minimum OSX 10.8 "Mountain Lion" or newer.
There are two installations for OS X.
See comparison.
If using OS X, the recommendation is to use Docker for mac
To get started, visit Docker
series of tutorials
- Start the Docker Engine
$ service docker start
docker start/running process PID
docker create
creates a container but does not start the container.docker run
creates and starts a container in one operation.docker start
starts a container so it is running.docker restart
stops and starts a container.docker pause
pauses a running container, "freezing" it in place.docker unpause
will un-pause a running container.docker attach
will connect to a running container.docker stop
stops a running container.docker wait
blocks until running container stops.docker kill
sends a SIGKILL to a running container.docker rm
deletes a container.docker update
updates a container's resource limits.$ docker rmi
delete a container image.
docker ps
shows running containers.docker logs
get logs from container.docker inspect
looks at all the info on a container. Outputs a JSONdocker events
gets events from container.docker port
shows running processes in container.docker top
shows running processes in container.docker stats
shows containers' resource usage statistics.docker diff
shows changed files in the container's filesystem.$ docker stats --all
shows a running list of containers.$ docker ps -a
shows running and stopped containers.
$ docker cp
copies files or folders between a container and the local filesystem.$ docker export
turns container filesystem into a tarball archive stream to STDOUT
$ docker exec
to execute a command in container.
docker images
shows all docker images.docker import
creates an image from a tarball.docker build
creates image from Dockerfile.docker commit
creates image from a container, pausing it temporarily if it is running.docker rmi
removes an image.docker load
loads an image from a tar archive as STDIN, including images and tags (as of 0.7).docker save
saves an image to a tar archive stream to STDOUT with all parent layers, tags & versions (as of 0.7).
docker history
shows history of image.docker tag
tags an image to a name (local or registry).
Refer to Docker container networking
and
Docker networking commands
What is a volume?
- Special type of directory in a container typically referred to as "data volume"
- Can be shaped and reused among containers.
- Any updates to an image, does not affect the volume.
- Data volumes are persisted even after the container is deleted.
Create a data volume in a container
$ docker run -v /container/dir/path <image name>
Customizing the host location for the data volume
pwd => host location where the source code is
/var/www => location in the container
$ docker run -p 8080:3000 -v $(pwd):/var/www <image name>
w => working directory. Where the startup dir in the container.
$ docker run -p 8080:3000 -v $(pwd):/var/www -w "/var/www" node npm start
When removing a container, make sure to delete the volume as well when applicable
$ docker rm -v <container id>
Refer to Manage data in containers
While you can use the docker rmi
command to remove specific images, there's a tool called docker-gc that will clean up images that are no longer used by any containers in a safe manner.
Pull a docker image from docker repo.
docker pull helloworld
Load an image from a file.
docker load < img_file.tar.gz
Tag an image.
docker tag <image id> helloworld:0.1
Save an existing image.
docker save image:tag | gzip > my_image.tar.gz
Run an instance (container) of a Docker image.
docker run helloworld
Import a container as an image from an image.
cat my_container.tar.gz | docker import - my_image:my_tag
Export an existing container.
docker export my_container | gzip > my_container.tar.gz
Difference between loading a saved image and importing an exported container as an image?
Loading an image using the load
command creates a new image including its history. Importing a container as an image using the import
command creates a new image excluding the history which results in a smaller image size compared to loading an image.