Problem Based Learning

Docker 3

I am Juan Cabrera

In [2]:
print ('Name: ', Juan['name'])
print ('Email: ', Juan['email'])
print ('Work: ', Juan['work'])
Name:  Juan A. Cabrera
Email:  juan.cabrera@tu-dresden.de
Work:  Deutsche Telekom Chair of Communication Networks

Slides: http://comnets.bitbucket.org/docker-pbl-2016/lecture-3/
Press esc for a menu of the slides
Files: https://bitbucket.org/comnets/docker-lecture-3/src

Slides inspired and adapted from:
Docker by Example. By:
Ganesh & Hari {ganesh|hari}(at)codeops.tech

Docker Container State Transition

title

Editing Nginx

Dockerfile

Dockerfile
=================================

FROM nginx:latest
MAINTAINER Juan

ADD ./index.html /usr/share/nginx/html/index.html
EXPOSE 80

index.html

index.html
=================================

<h1> Welcome to PBL </h1>

<h2> Have Fun! </h2>

Editing Nginx

docker build -t my_server .
docker run -p 80:80 -d my_server

Docker Volumes

They can be used to make data persistent

# Make a folder to store the data
mkdir ~/testing_data

# Run a container
docker run -v ~/testing_data:/container_volumes ubuntu /bin/sh -c "echo peristent data > /container_volumes/data.txt"

# Check that your data is there
cat ~/testing_data/data.txt

Make an image to compile and run our C code with a specific gcc version

Dockerfile
=======================
FROM gcc:4.9
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN gcc -o myapp main.c
CMD ["./myapp"]
main.c
=======================
#include <stdio.h>

main()
{
    printf("Hello container world\n");
}

Running the image

# Build the image
docker build . -t my-gcc-app

# Run a container
docker run -rm my-gcc-app

Monitoring your containers

First, Lets build a benchmarking image

Let us use sysbench

The cpu is one of the most simple benchmarks in SysBench. In this mode each request consists in calculation of prime numbers up to a value specified by the −−cpu−max−primes option. All calculations are performed using 64−bit integers.

Each thread executes the requests concurrently until either the total number of requests or the total execution time exceed the limits specified with the common command line options.

Monitoring your containers

First, Lets build a benchmarking image

Dockerfile
=======================
FROM ubuntu:latest
MAINTAINER Juan

RUN apt-get update \
    && apt-get install -y sysbench

CMD sysbench --test=cpu --cpu-max-prime=35000 --num-threads=4 run

build it and run it to test it

Monitoring your containers

Let us run the monitoring tool

There are several options out there.

Let us use Google's cAdvisor https://github.com/google/cadvisor

docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:rw \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  google/cadvisor:latest

Run the benchmarking container, and check the browser

Monitoring your containers

Limit the number of cores

docker run --cpuset-cpus="0,1" my-benchmark

Managing Multiple Containers and Containers Dependencies

Setting Up a Wordpress

To set a word press, we need a data base and a wordpress server

We can use docker compose to have one file to rule them all

yml
version: '2'

services:
   db:
     image: mysql:5.7
     volumes:
       - ./db_volume:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: wordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_PASSWORD: wordpress

Setting Up a Wordpress

What do we have in that file?

  • Services:
    • db: Database
      • Volumes
      • restart policy
      • environment variables
    • wordpress
      • Dependencies
      • ports
  • Volumes

Let us run it!

docker-compose up -d

Try it in your browser

Docker Compose: A Load Balancer

Excercise inspired from: http://blog.hypriot.com/

Lets create a webserver that performs a "computationally intensive" task

Let us create a Hello-World Node.js web application based on Express.js

Make two new folders: load-balancing/ and load-balancing/src/

We need 2 files inside load-balancing/src/. Namely index.js and package.json

load-balancing/src/index.js

var express = require('express');
var os = require("os");

var app = express();
var hostname = os.hostname();

app.get('/', function (req, res) {
    // A CPU Intensive task:
    for (var i = 0; i < 1000000 ; i++) {
        Math.pow(i,i);
    }
    // Respond the request:
    res.send('<html><body>Hello from Node.js container '
        + hostname + '</body></html>');
});

app.listen(80);
console.log('Running on http://localhost');

Docker Compose: A Load Balancer

load-balancing/src/package.json

{
  "name": "node-hello-world",
  "private": true,
  "version": "0.0.1",
  "description": "Node.js Hello world app on docker",
  "author": "hypriot.com",
  "dependencies": {
    "express": "4.12.0"
  }
}

Docker Compose: A Load Balancer

Now let us make the Dockerfile of our application

load-balancing/Dockerfile

FROM node

ADD src/ /src
WORKDIR /src

RUN npm install

EXPOSE 80

CMD ["node", "index.js"]

Build and run a container

docker build . -t node-hello
docker run -p 45700:80 --name web -d node-hello

Docker Compose: A Load Balancer

Try it in your browser

Lets benchmark it:

  • See the CPU utilization with htop
  • Install apache2-utils (in your pc or in an Ubuntu container)
  • run: ab -n 10000 -c 100 http://localhost:45700/
  • How many requests-per-second can you support?

Docker Compose: A Load Balancer

load-balancing/docker-compose.yml

yml
weba:
    build: .
    expose:
        - 80
webb:
    build: .
    expose:
        - 80
webc:
    build: .
    expose:
        - 80
haproxy:
    image: haproxy
    volumes:
        - ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
    links:
        - weba
        - webb
        - webc
    ports:
        - "80:80"
        - "70:70"
    expose:
        - "80"
        - "70"

Docker Compose: A Load Balancer

Haproxy config file

load-balancing/haproxy/haproxy.cfg

global
  log 127.0.0.1 local0
  log 127.0.0.1 local1 notice

defaults
  log global
  mode http
  option httplog
  option dontlognull
  timeout connect 5000
  timeout client 10000
  timeout server 10000

listen stats
  bind :70
  stats enable
  stats uri /

frontend balancer
  bind 0.0.0.0:80
  mode http
  default_backend aj_backends

backend aj_backends
  mode http
  option forwardfor
  # http-request set-header X-Forwarded-Port %[dst_port]
  balance roundrobin
  server weba weba:80 check
  server webb webb:80 check
  server webc webc:80 check
  # option httpchk OPTIONS * HTTP/1.1\r\nHost:\ localhost
  option httpchk GET /
  http-check expect status 200

Docker Compose: A Load Balancer

Let us run it!

docker-compose up -d

Try it in your browser!

Let us benchmark this one! :D