Docker 101
PROPERTIES: :ID: 79ec0a7b-258d-49c6-b159-afcb2917e219
:END:
- tags
- Linux, Operating Systems
Why Containers
Containers are Cheap
Containers are Cheap
- Docker provides lightweight virtualization with almost zero overhead.
- Start and stop containers within seconds.
Containers are Portable
Containers contain all the required software dependencies to run your application.
Once a container is built, you can be sure it runs “the same way” on any host operating system with the same Linux kernel.
Containers in OSes
Year | |
---|---|
2006 | Process Containers, later renamed to cgroups |
2008 | LXC: implemented using cgroups and kernel namespaces |
2013 | Docker: initially built on LXC, but now runs on libcontainer |
2006: Process Containers
2008: LXC Containers, and 2013: Docker
What is Docker?
Docker is a toolchain for managing containers.
What You’ll Do Today
You’ll be packaging a simple application with Docker.
If time permits, we’ll cover additional things, such as passing environment variables.
Docker Basics
Pulling images
docker pull alpine
Alpine?
alpine
is an image for a tiny Linux distribution, used by Docker for
most of its official images.
A container image is a lightweight, stand-alone, executable package of a piece of software that includes everything needed to run it: code, runtime, system tools, system libraries, settings.
alpine
is pulled from the Docker Registry, where hundreds of
thousands of images are hosted.
Starting a container
docker run alpine
What is happening here?
Running a command
docker run alpine echo "Hello from alpine!"
Docker Status
List all docker images:
docker images
List all running docker containers:
docker ps
List all docker containers (including stopped containers):
docker ps -a
Entering a Container Interactively
docker run -it alpine sh
uname -r # 4.9.41-moby
hostname # container_id
whoami # root
id # uid=0(root) gid=0(root) groups=0(root),1(bin)...
Inside alpine
Docker images consist of multiple layers:
Layers for the ubuntu image
Observe the output for the following:
docker pull ubuntu:15.04
docker history ubuntu
Declare layers with a Dockerfile
FROM ubuntu
MAINTAINER Kimbro Staken
RUN apt-get install -y software-properties-common python
RUN add-apt-repository ppa:chris-lea/node.js
RUN echo "deb http://us.archive.ubuntu.com/ubuntu/ precise universe" >> /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y nodejs
#RUN apt-get install -y nodejs=0.6.12~dfsg1-1ubuntu1
RUN mkdir /var/www
ADD app.js /var/www/app.js
CMD ["/usr/bin/node", "/var/www/app.js"]
Dockerfile Cheatsheet
Command | Info |
---|---|
FROM | Sets the Base Image for subsequent instructions. |
RUN | execute any commands in a new layer on top of the current image and commit the results. |
CMD | provide defaults for an executing container. |
EXPOSE | informs Docker that the container listens on the specified network ports at runtime. |
ENV | sets environment variable. |
COPY | copies new files or directories to container. |
ENTRYPOINT | configures a container that will run as an executable. |
VOLUME | creates a mount point for externally mounted volumes or other containers. |
WORKDIR | sets the working directory. |
ARG | defines a build-time variable. |
LABEL | apply key/value metadata to your images, containers, or daemons. |
Docker Networking
Docker creates three networks by default. We’re mostly concerned with
bridge
.
$ docker network ls
NETWORK ID NAME DRIVER
7fca4eb8c647 bridge bridge
9f904ee27bf5 none null
cf03ee007fb4 host host
How bridge
works
Unless specified otherwise, the docker container will connect to this
default bridge
network. This provides a means of Docker containers
to access the outside world. This is achieved through rules on the
kernel’s iptable
.
By default, none of the ports are published and the outside world has no access to the docker containers.
Running a Simple Webserver
nc -ll -p 8080 -e /bin/echo -e "HTTP/1.1 200 OK\n\n$(date)\n"
Allowing Ingress
docker run -p 5001:8080 alpine \
nc -ll -p 8080 -e /bin/echo -e "HTTP/1.1 200 OK\n\n$(date)\n"
As a daemon:
docker run -p 5001:8080 -d alpine \
nc -ll -p 8080 -e /bin/echo -e "HTTP/1.1 200 OK\n\n$(date)\n"
Exercise: package a Node.js Server with Docker
curl -i http://localhost:5001/
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 14
ETag: W/"e-ZohVPp9YwmNT/yh3111KJ3ZG6Uk"
Date: Fri, 13 Oct 2017 18:34:46 GMT
Connection: keep-alive
Hello world!!
Server code
https://git.io/vdXLC
General Instructions
- Install the Node.js runtime (use Ubuntu)
- Copy the files into the container
- Get the node package manager
npm
- Run
npm install
- Run
npm start
to start server
But… I want to change my files!
docker run -d my/webserver
# Create file locally
docker exec -it container_name sh
ls #WAT
Mounting Volumes
There are three types of mounts:
- Volumes are managed by docker. Volumes also support the use of volume drivers, which allow you to store your data on remote hosts or cloud providers, among other possibilities.
- Bind Mounts may be stored anywhere on the host filesystem.
- tmpfs mounts are stored in the host system’s memory only.
Mounting the /src
directory
docker run -p 5000:8080 -v ~/path/to/directory:/usr/src/app/src my/webserver
Beyond Docker
Docker is the building block for many devops solutions.
- Container Orchestration: Kubernetes, Cloud Foundry etc.
- Monitoring: cAdvisor, InfluxDB etc.
- Reverse Proxies and Load Balancers: fabio etc.
Docker makes microservices manageable and scalable.