docker, the future of devops
TRANSCRIPT
Outline
• Introduction
• What is Docker and why care?
• Docker Overview
• Docker in depth
• Orchestration and Clustering
• Consultant Company• Malmö, København, Halmstad, Helsingborg,
Stockholm, San Fransisco
• A lot of competence activities• Competence weekends, competence days, Øredev
• We are hiring!
Process Tree
$ pstree VM
-+= /VirtualBox.app|--= coreos-vagrant
$ pstree docker
-+= /docker|--= /bin/sh |--= node server.js|--= go run app|--= ruby server.rb...|--= /bin/bash
• Standardized Environments
• Few changes
• Isolated dependencies
Ops• Always new
Environments
• Many changes
• Isolated dependencies
Dev
100x Faster Enables
• Throwaway dev environments• Databases, Filesystems, Tools
• Throwaway test environments• Filesystems, Databases
• Throwaway prod environments• Upgrade the server by plopping in a new container
Docker Client-ServerDocker Client
Docker Client
Docker Client
Docker Client
Docker Daemon
DockerContainer
DockerContainer
DockerContainer
DockerHost
Docker Interactions
Registry
Images
Host
Images
ContainerContainerContainer
Volumes
push
pull
build
run, createcommit
start, stop, restart
tag
Images
$ docker images # shows all images.$ docker import # creates an image from a tarball.$ docker build # creates image from Dockerfile.$ docker commit # creates image from a container.$ docker rmi # removes an image.$ docker history # list changes of an image.
Example Image Sizes
Name Size Files
scratch 0 0
busybox 2.4 MB ~10500
debian:jessie 122 MB ~18000
ubuntu:14.04 188 MB ~23000
docker commit <container-id>$ docker run -i -t debian:jessie bashroot@e6c7d21960:/# apt-get updateroot@e6c7d21960:/# apt-get install postgresqlroot@e6c7d21960:/# apt-get install noderoot@e6c7d21960:/# node --versionroot@e6c7d21960:/# curl https://iojs.org/dist/v1.2.0/iojs-v1.2.0-linux-x64.tar.gz -o iojs.tgzroot@e6c7d21960:/# tar xzf iojs.tgzroot@e6c7d21960:/# lsroot@e6c7d21960:/# cd iojs-v1.2.0-linux-x64/root@e6c7d21960:/# lsroot@e6c7d21960:/# cp -r * /usr/local/root@e6c7d21960:/# iojs --version1.2.0root@e6c7d21960:/# exit$ docker ps -l -qe6c7d21960$ docker commit e6c7d21960 postgres-iojsdaeb0b76283eac2e0c7f7504bdde2d49c721a1b03a50f750ea9982464cfccb1e
DockerfilesFROM debian:jessie
RUN apt-get updateRUN apt-get install postgresqlRUN curl https://iojs.org/dist/iojs-v1.2.0.tgz -o iojs.tgzRUN tar xzf iojs.tgzRUN cp -r iojs-v1.2.0-linux-x64/* /usr/local
$ docker build -tag postgres-iojs .
Dockerfiles
$ docker build -tag postgres-iojs .
FROM debian:jessie
RUN apt-get update && \ apt-get install postgresql && \ curl https://iojs.org/dist/iojs-v1.2.0.tgz -o iojs.tgz && \ tar xzf iojs.tgz && \ cp -r iojs-v1.2.0-linux-x64/* /usr/local
1 FROM debian:wheezy 2 3 MAINTAINER NGINX Docker Maintainers "[email protected]" 4 5 RUN apt-key adv --keyserver pgp.mit.edu --recv-keys \ 6 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 7 RUN echo "deb http://nginx.org/packages/mainline/debian/ wheezy nginx" >> 8 /etc/apt/sources.list 9 10 ENV NGINX_VERSION 1.7.10-1~wheezy 11 12 RUN apt-get update && \ 13 apt-get install -y ca-certificates nginx=${NGINX_VERSION} && \ 14 rm -rf /var/lib/apt/lists/* 15 16 # forward request and error logs to docker log collector 17 RUN ln -sf /dev/stdout /var/log/nginx/access.log 18 RUN ln -sf /dev/stderr /var/log/nginx/error.log 19 20 VOLUME ["/var/cache/nginx"] 21 22 EXPOSE 80 443 23 24 CMD ["nginx", "-g", "daemon off;"]
Dockerfile
BUILD Both RUNFROM WORKDIR CMDMAINTAINER USER ENVCOPY EXPOSEADD VOLUMERUN ENTRYPOINTONBUILD.dockerignore
Containers
$ docker create # creates a container but does not start it.$ docker run # creates and starts a container.$ docker stop # stops it.$ docker start # will start it again.$ docker restart # restarts a container.$ docker rm # deletes a container.$ docker kill # sends a SIGKILL to a container.$ docker attach # will connect to a running container.$ docker wait # blocks until container stops.$ docker exec # executes a command in a running container.
docker run --env
$ docker run \ --name mydb \ --env MYSQL_USER=db-user \ -e MYSQL_PASSWORD=secret \ --env-file ./mysql.env \ mysql
docker run publish
$ docker run -p 8080:80 nginx
1 FROM debian:wheezy 2 3 MAINTAINER NGINX "[email protected]" 21 22 EXPOSE 80 443 23
docker run publish
$ docker run \ -p 127.0.0.1:8080:80 nginx
1 FROM debian:wheezy 2 3 MAINTAINER NGINX "[email protected]" 21 22 EXPOSE 80 443 23
docker run publish-all
$ docker run -P nginx
1 FROM debian:wheezy 2 3 MAINTAINER NGINX "[email protected]" 21 22 EXPOSE 80 443 23
docker run limits
$ docker run -m 256m yourapp
$ docker run \ --cpu-shares 512 \ # of 1024 myapp
$ docker run -u=www nginx
docker run -v
$ docker run \ -v /var/log \ nginx
host filesystem
/var/lib/docker/volumes/ec3c543bc..535
--volumes-from
-v /var/logs/nginx -v /var/www
--volumes-from <nginx>--volumes-from <stats>
statsnginx
worker
Docker Hub
RepositoryPublic (free), Private (fee)
Automatic BuildsIntegration with Github and Bitbucket
Official reposCertified by vendors
Docker Interactions
Registry
Images
Host
Images
ContainerContainerContainer
Volumes
push
pull
build
runcommit
start, stop, restart
tag
Inspecting
$ docker ps # shows running containers.$ docker inspect # info on a container (incl. IP address).$ docker logs # gets logs from container.$ docker events # gets events from container.$ docker port # shows public facing port of container.$ docker top # shows running processes in container.$ docker diff # shows changed files in container's FS.$ docker stats # shows metrics, memory, cpu, filsystem
docker ps
$ docker ps --allCONTAINER ID IMAGE COMMAND NAMES9923ad197b65 busybox:latest "sh" romantic_fermatfe7f682cf546 debian:jessie "bash" silly_bartik09c707e2ec07 scratch:latest "ls" suspicious_perlmanb15c5c553202 mongo:2.6.7 "/entrypo some-mongofbe1f24d7df8 busybox:latest "true" db_data
docker inspect$ docker inspect silly_bartik 1 [{ 2 "Args": [ 3 "-c", 4 "/usr/local/bin/confd-watch.sh" 5 ], 6 "Config": { 10 "Hostname": "3c012df7bab9", 11 "Image": "andersjanmyr/nginx-confd:development", 12 }, 13 "Id": "3c012df7bab977a194199f1", 14 "Image": "d3bd1f07cae1bd624e2e", 15 "NetworkSettings": { 16 "IPAddress": "", 18 "Ports": null 19 }, 20 "Volumes": {}, 22 }]
ip of a container
$ docker inspect -f \ '{{ .NetworkSettings.IPAddress }}' \ 6f2c42c05500
172.17.0.11
env-vars of container
$ docker exec -it \ 6f2c42c05500 \ env
PATH=/usr/local/sbin:/usr... HOSTNAME=6f2c42c05500 REDIS_1_PORT=tcp://172.17.0.9:6379 REDIS_1_PORT_6379_TCP=tcp://172.17.0.9:6379
Faster Dev Cycle 1 FROM dockerfile/nodejs:latest 2 3 MAINTAINER Anders Janmyr "[email protected]" 4 RUN apt-get update && \ 5 apt-get install zlib1g-dev && \ 6 npm install -g pm2 && \ 7 mkdir -p /srv/app 8 9 WORKDIR /srv/app 10 COPY . /srv/app 11 12 CMD pm2 start app.js -x -i 1 && pm2 logs 13
$ docker build -t myapp . $ docker run -it --rm myapp
Faster Dev Cycle
$ docker run -it --rm \ -v $(PWD):/srv/app \ myapp
Security Problems
• Image signatures are not properly verified
• If you have root in a container, you can, potentially, get root to the whole box
Security Remedies
• Use trusted images
• Don't run containers as root, if possible
• Treat root in a container as root outside a container
docker-compose.yml
1 web: 2 build: . 3 command: python app.py 4 ports: 5 - "5000:5000" 6 volumes: 7 - .:/code 8 links: 9 - redis 10 redis: 11 image: redis
docker-compose up
1 $ docker-compose up 2 Pulling image orchardup/redis... 3 Building web... 4 Starting figtest_redis_1... 5 Starting figtest_web_1... 6 redis_1 | [8] 02 Jan 18:43:35.576 # Server 7 started, Redis version 2.8.3 8 web_1 | * Running on http://0.0.0.0:5000/
docker-compose up -d
1 $ docker-compose up -d 2 Starting figtest_redis_1... 3 Starting figtest_web_1... 4 $ docker-compose ps 5 Name Command State Ports 6 ------------------------------------------------------------ 7 figtest_redis_1 /usr/local/bin/run Up 8 figtest_web_1 /bin/sh -c python app.py Up 5000->5000
Other stuff
1 # Get env variables for web container 2 $ docker-compose run web env
3 # Scale to multiple containers 4 $ docker-compose scale web=3 redis=2
5 # Get logs for all containers 6 $ docker-compose logs
Core OS Linux
• Minimal 114MB RAM on boot
• No package manager, Docker
• Dual-partition scheme• Read-only boot partitions
• Managed Linux
systemd
• Performance, boots extremely fast
• Logging journal has great features• JSON export
• Forward secure sealing
• Indexing for fast querying
• Socket Activation
Etcd 1 # Set a value that expires after 60s 2 # Also creates dir /foo is it does not exist 3 $ etcdctl set /foo/bar "Hello world" --ttl 60 4 Hello world 5 6 # Get a value 7 $ etcdctl get /foo/bar 8 Hello world 9 25 # List a directory recursively 26 $ etcdctl ls --recursive / 27 /coreos.com 28 ... 33 # Watch a key for changes 34 $ etcdctl watch /foo/bar 35 Hello world
fleet
• Cluster manager
• Extension of systemd
• Uses etcd for configuration
• On every Core OS machine
fleet
DEMO
DEMO
• Start a single container
• Start a container on every host
• Start a dependent container
Amazon ECS
1 $ aws ecs create-cluster # Creates a cluster 2 $ aws ec2 run instances --image-id i123456 # Starts instances 3 $ aws ecs register-task-definition # Registers a new task 4 $ aws ecs run-task # Runs a task 5 $ aws ecs list-tasks # Lists tasks 6 $ aws ecs list-container-instances # Runs instances
Summary
• Docker fixes dependency hell
• Containers are fast!
• Cluster solutions exists• But don't expect it to be seamless