docker-workshop



docker-workshop

4 1


docker-workshop


On Github giantswarm / docker-workshop

Docker Getting Started 1 & 2

Agenda

Installation Working with containers Working with images Building images Working with volumes Linking containers

1) Installation

Virtualbox image

  • Have https://www.virtualbox.org/ installed
  • Install and start the workshop VM:

    docker-workshop_docker-workshop-vm_*.ova

  • Double Click or Virtual Box > File > Import Appliance ...
  • Login: ssh -p 2222 demo@localhost Password: demo
    $ ssh -p 2222 demo@localhost
    demo@localhost's password:
    Welcome to Ubuntu 14.04 LTS (GNU/Linux 3.13.0-24-generic x86_64)
    ...

docker version

  $ docker version
  Client version: 1.3.0
  Client API version: 1.15
  Go version (client): go1.3.3
  Git commit (client): c78088f
  OS/Arch (client): linux/amd64
  Server version: 1.3.0
  Server API version: 1.15
  Go version (server): go1.3.3
  Git commit (server): c78088f

docker info

  $ docker info
  Containers: 1
  Images: 49
  Storage Driver: devicemapper
   Pool Name: docker-8:1-262794-pool
   Pool Blocksize: 65.54 kB
   Data file: /var/lib/docker/devicemapper/devicemapper/data
   Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
   Data Space Used: 1.485 GB
   Data Space Total: 107.4 GB
   Metadata Space Used: 2.306 MB
   Metadata Space Total: 2.147 GB
   Library Version: 1.02.82-git (2013-10-04)
  Execution Driver: native-0.2
  Kernel Version: 3.13.0-24-generic
  Operating System: Ubuntu 14.04 LTS
  WARNING: No swap limit support

docker help

$ docker help
Usage: docker [OPTIONS] COMMAND [arg...]

A self-sufficient runtime for linux containers.

Options:
  --api-enable-cors=false                    Enable CORS headers in the remote API
  -b, --bridge=""                            Attach containers to a pre-existing network bridge
                                               use 'none' to disable container networking
...
Commands:
    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders from a container's filesystem to the host path
    create    Create a new container
...

Local Docker registry

# start a local registry
$ /usr/local/bin/start_registry.sh
# check local registry
$ docker ps -a
CONTAINER ID        IMAGE                         COMMAND                CREATED             STATUS                       PORTS                      NAMES
5bb7620b2b47        registry:latest               "/bin/sh -c 'exec do   14 minutes ago      Up 14 minutes                127.0.0.1:5000->5000/tcp   registry

Excercise 1

Check your Docker installation. Examine available Docker commands.

More Information

2) Working with containers

docker run

# run a command in a container
$ docker run ubuntu echo helloworld
helloworld

docker run again

# run an interactive command
$ docker run -it ubuntu /bin/bash
root@be9db7f93391:/# hostname
be9db7f93391
# run a while loop in a deamonized container
$ docker run -d ubuntu /bin/bash -c "while true; do echo hello; sleep 1; done"
cf1417763edad98420e2b26fd1a55fec0ea88c6c404449eb647322f6fa9c364b
$ docker ps
CONTAINER ID        IMAGE                         COMMAND                CREATED             STATUS              PORTS               NAMES
cf1417763eda        127.0.0.1:5000/ubuntu:14.04   "/bin/bash -c 'while   4 seconds ago       Up 4 seconds                            cocky_wilson
# name a cointainer
$ docker run --name mycontainer -i -t ubuntu /bin/bash

docker ps

# List running container
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

# List all container
$ docker ps -a
CONTAINER ID        IMAGE                         COMMAND                CREATED             STATUS                         PORTS               NAMES
cf1417763eda        127.0.0.1:5000/ubuntu:14.04   "/bin/bash -c 'while   29 seconds ago      Up 29 seconds                                      cocky_wilson
be9db7f93391        127.0.0.1:5000/ubuntu:14.04   "/bin/bash"            23 minutes ago      Exited (130) 17 minutes ago                        desperate_goldstine

docker {kill, stop, start}

# Kill a container (SIGKILL)
$ docker kill 8003a50512e9
8003a50512e9
# Stop a container (SIGTERM)
$ docker stop mycontainer
# Start a container
$ docker start mycontainer

docker rm

# Remove a container
$ docker rm mycontainer
# Remove all containers
$ docker rm $(docker ps -a -q)

docker {logs, top, inspect}

# Show and follow STDOUT and STDERR
$ docker logs --follow mycontainer
# Show running processes
$ docker top mycontainer
# More information about a container
$ docker inspect mycontainer

Excercise 2a

Print `hello-wjax with a Docker container Start a bash in a container and remove the ls command Start a background container with a while loop {Examine, stop, start} that container Enter that container with docker exec

Excercise 2b

Start the nginx container and publish the port 80 to 8000. Verify it in you browser.

3) Working with images

docker images

# Available images on the host
$ docker images
REPOSITORY                            TAG                   IMAGE ID            CREATED             VIRTUAL SIZE
127.0.0.1:5000/dockerfile/nginx       latest                52cea49d86cf        5 days ago          435.2 MB
nginx                                 latest                52cea49d86cf        5 days ago          435.2 MB
registry                              latest                8e9a29f977a7        6 days ago          427.9 MB
127.0.0.1:5000/ubuntu                 14.04                 5506de2b643b        6 days ago          197.8 MB

docker tag

# Tag an image
$ docker tag 127.0.0.1:5000/ubuntu myubuntu

docker rmi

# Delete an image
$ docker rmi nginx

docker pull

# Pull an image from an repository
$ docker pull 127.0.0.1:5000/ubuntu
Pulling repository 127.0.0.1:5000/ubuntu
5506de2b643b: Download complete
511136ea3c5a: Download complete
d497ad3926c8: Download complete
ccb62158e970: Download complete
e791be0477f2: Download complete
3680052c0f5c: Download complete
22093c35d77b: Download complete
Status: Image is up to date for 127.0.0.1:5000/ubuntu:latest

docker history

# Show the history of an image
$ docker history 127.0.0.1:5000/ubuntu
IMAGE               CREATED             CREATED BY                                      SIZE
5506de2b643b        6 days ago          /bin/sh -c #(nop) CMD [/bin/bash]               0 B
22093c35d77b        6 days ago          /bin/sh -c apt-get update && apt-get dist-upg   5.067 MB
3680052c0f5c        6 days ago          /bin/sh -c sed -i s/^#\s*\(deb.*universe\)$/   1.895 kB
e791be0477f2        6 days ago          /bin/sh -c rm -rf /var/lib/apt/lists/*          0 B
ccb62158e970        6 days ago          /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
d497ad3926c8        9 days ago          /bin/sh -c #(nop) ADD file:3996e886f2aa934dda   192.5 MB
511136ea3c5a        16 months ago

docker diff

#  Inspect changes on a container's filesystem
$ docker diff 371e7819491f
A /data
C /tmp
A /tmp/docker-registry.db

docker commit

#  Create a new image from a container's changes
$ docker commit 371e7819491f myimage
e412662cb4d8376b3d78a202f78ff3b42980041fc067b6c1c12d67163b1e5435

Excercise 3

Running containers

Start the nginx container with a bash Check by browsing to localhost:8000 Add an index.html to /usr/share/nginx/html Run the container and publish container port 80 to 8000

Excercise 3b

Save containers changes

Submit the changes to a new image and start it

Excercise 3c

Pull new images

remove java images$ docker rmi 127.0.0.1:5000/dockerfile/java:oracle-java8$ docker rmi 127.0.0.1:5000/dockerfile/java

pull docker image$ docker pull 127.0.0.1:5000/dockerfile/java:oracle-java8

4) Building images

docker build

# Build a new image from the source path
$ docker build .
Sending build context to Docker daemon 686.1 kB
Sending build context to Docker daemon
Step 0 : FROM nginx
 ---> f1c42afeb4a4
Step 1 : COPY . /usr/share/nginx/html
 ---> Using cache
 ---> b8c178b653b9
Successfully built b8c178b653b9

A Dockerfile

FROM        ubuntu:14.04
MAINTAINER  Matthias Luebken <matthias@giantswarm.io>

# To manually trigger cache invalidation
ENV build_date 2014-09-01

RUN apt-get update
RUN apt-get install -y nginx

RUN echo 'Hello world' > /usr/share/nginx/html/index.html

EXPOSE 80

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]

Dockerfile instructions 1

  • FROM the parent image
  • MAINTAINER the maintainer of this Dockerfile (optional)
  • RUN <command> run the command during build time with '/bin/sh -c'
  • EXPOSE <port> expose a specific port on the container
  • ADD <files> add files from the build environment into the image with tar extraction
  • ENV <variable> set environment variables
  • CMD ["<command>", "<arg 1>", "<arg 2>"] run the commands when container is launched. Can be overwritten via the command line

Dockerfile instructions 2

  • WORKDIR <dir> set the working directory for RUN and CMD/ENTRYPOINT
  • USER <user> specifies the USER
  • VOLUME ["<dir>"] adds a volume to a container
  • ONBUILD <build instruction> execute the instruction when child image is
  • ENTRYPOINT ["<command>", "<arg 1>", "<arg 2>"] run the commands when container is launched. Command line args will be passed on.

Excercise 4

Build a plain nginx image with a new Dockerfile Check with localhost:8000 Add a custom index.html Check nginx configuration during build time nginx -t Ensure that your build breaks with a broken config Add custom logging
# /etc/nginx/conf.d/logging.conf
 access_log /run/nginx/access.log;
 error_log /run/nginx/error.log;

5) Volumes

Volumes

  • For persisted and shared data
  • A special directory that bypasses the Union File System
  • Volumes can be shared between containers
  • Changes to a volume are immediate
  • Volumes persist until no containers uses them

docker run -v

# also doable with VOLUME in your Dockerfile
docker run -v <containerpath> ...

# only on docker run
docker run -v <hostpath>:<containerpath> ...

Volume container

  • Volumes live as long as a container uses them (running or stopped)
  • They get deleted if you clean up your containers (docker rm).
  • To persist data, they must live outside of the container
  • Use -v <host>:<path> to manually manage your volumes
  • Use a separate container to store the data

Excercise 5a

Based on solution from exercise 4.

Extend the Dockerfile to specify a new volume at /mnt/logs. Change your config files to write to the new folder. Start your container, open the index file in your browser. Start a new container with --volumes-from to tail the logfile.

Exercise 5b - Data container

Start a data container with a volume at /mnt/logs Start the nginx image with --volumes-from=<fist container> Make a request and examine the logs Restart the nginx and check old log entries

6) Linking containers

docker run --name

# Assign a name to the container
$ docker run -d --name mynginx 127.0.0.1:5000/dockerfile/nginx
f01e0624537deaa096d309ea8fd7e3d9abbaad72ba84aeda2292d7502ce66ed2
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                     PORTS               NAMES
f01e0624537d        nginx:latest        "nginx -g 'daemon of   About an hour ago   Up About a minute          443/tcp, 80/tcp     mynginx

docker run --link

# Add link to another container in the form of name:alias
$ docker run -it --link mynginx:web rossbachp/tomcat8 /bin/bash

Excercise 6

Start the nginx container with --name web Start a container with curl installed and link it to nginx We are using rossbachp/tomcat8 which has curl installed.