CC PartII - 3
CC PartII - 3
What do we need?
• Hardware Platform
• Operating System
• OS Library
• Process Dependencies
Docker needs some tools to coordinate the static and dynamic configuration
with Orchestrators → we will go deeper into some of them in the next module
Docker Swarm, Kubernetes, MESOS, …
Containers (& Orchestration…) for Scalability
Large targets
Under the hood: Docker Engine
Client-server architecture
• Docker daemon
▪ Docker daemon – The Docker daemon listens for Docker API requests and manages
Docker components such as images, containers, networks, and volumes.
▪ Docker client – The Docker client (docker) is the primary way that many Docker users
interact with Docker. When you use commands such as docker run, the client sends these
commands to dockerd, which carries them out.
▪ Docker registries – A Docker registry stores Docker images. Docker Hub and Docker Cloud
are public registries that anyone can use, and Docker is configured to look for images on
Docker Hub by default. You can even run your own private registry. Docker registries are
the distribution component of Docker.
Docker main components
Docker images
A Docker image is a read-only template. For example, an image could contain an Ubuntu
operating system with Apache and your web application installed. Images are used to create
Docker containers. Docker provides a simple way to build new images or update existing images,
or you can download Docker images that other people have already created. Docker images
are the build component of Docker.
Docker containers
Docker containers are similar to a directory. A Docker container holds everything that is needed
for an application to run. Each container is created from a Docker image. Docker containers can
be run, started, stopped, moved, and deleted. Each container is an isolated and secure
application platform. Docker containers are the run component of Docker.
Main Docker components revised
LOCAL HOST
DOCKER HOST
Main Docker components revised
LOCAL HOST DOCKER HUB
IMAGE 1 IMAGE 2
REPOSITORY
IMAGE N IMAGE M
IMAGE 1 IMAGE 2
REPOSITORY
CONTAINER A1 CONTAINER A2
IMAGE 1 IMAGE 2
CONTAINER A1 CONTAINER A2
IMAGE 1 IMAGE 2
REMOTE HOST
CONTAINER X
CONTAINER Y
IMAGE 6 IMAGE 7
DOCKER DAEMON
DOCKER HOST
Main Docker components revised
LOCAL HOST DOCKER HUB
CONTAINER A1 CONTAINER A2
IMAGE 1 IMAGE 2
PRIVATE REGISTRY
IMAGE 6 IMAGE 7
REPOSITORY
DOCKER REGISTRY
Docker Container Lifecycle
Docker images
holds all container-specific CONTAINER
Random UUID
writes and deletes LAYER (R/W)
91e54dfb1179 0B
ubuntu:15.04
Docker images
39
Docker Images - Naming convention
[hostname[:port]]/[username]/reponame[:tag]
40
Dockerfile
Starting Image
Configuration
NO Layer creation
Modify fs
Multi-Stage Build Layer creation
Docker container lifecycle (and related events)
Docker plugins
Docker is a rich ecosystem and there are plugins to extend Docker basic functionalities
(we do not have time to go into details, but just report some hints for those who are interested…)
Volume
Network
Authorization
Networks
• Bridge: uses a software bridge which allows containers connected to the same bridge
network to communicate, while providing isolation from containers which are not
connected to that bridge network
• Host: Remove network isolation between the container and the Docker host, and use the
host’s networking directly
• Overlay: software network abstraction that can be used to run multiple separate,
discrete virtualized network layers on top of the physical network ( We will go deeper….)
To organize internally your application, e.g., a data container and an application logic container
Example: containerization of a 2-tier Web/REST application
What if we want to simplify this? This idea is the genesis for Embedded Servers.
For example, for a Spring Boot Application, you can generate an application jar which contains
Embedded Tomcat. You can run a web application as a normal Java application!
Example: Spring Boot Application Tier 2
Entities
- Author.java
Thanks to Spring deep integration with JPA we don’t need to
- Book.java
spend too much time in configuring the persistence layer
since most part of the setup is done automatically (i.e. db
creation) by exploiting Java annotations. Repositories
- AuthorRepository.java
Application Tier Database Tier - BookRepository.java
Controller
- MainController.java
JPA
This let us to re-use this web app with any database we want.
spring:
profiles: container
datasource:
driverClassName: ${DATABASE_DRIVER}
url: jdbc:mysql://${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}?useSSL=false&allowPublicKeyRetrieval=true
username: ${DATABASE_USER}
password: ${DATABASE_PASSWORD}
tomcat:
test-while-idle: true
time-between-eviction-runs-millis: 60000
validation-query: SELECT 1
jpa:
hibernate.ddl-auto: create-drop
properties.hibernate.dialect: org.hibernate.dialect.MySQL5Dialect
Example: Application containerization
App organization
One container for Spring
One container for MySQL + Volume
The first step is to define an image for each container by writing the Dockerfile.
Thanks to a simple sintax a Dockerfile let us to define all the steps necessary to create an
image and to execute it.
Spring container Dockerfile
Image creation and upload in the DockerHub
1 FROM openjdk:8-jre-alpine $ docker build –t librarydemo
2 MAINTAINER Dmitrij David Padalino Montenero
3 $ docker login
5 VOLUME /tmp
4 EXPOSE 8080 $ docker tag librarydemo davidmonnuar/springbootlibrarydemo:1.0
6
7 ARG JAR_FILE $ docker push davidmonnuar/springbootlibrarydemo:1.0
8 ADD target/${JAR_FILE} app.jar
9 ADD wrapper.sh wrapper.sh
10
11
12
RUN apk add --update bash && rm -rf /var/cache/apk/*
RUN bash -c 'chmod +x /wrapper.sh'
Image size only 116 MB
13 RUN bash -c 'touch /app.jar'
14
15 ENTRYPOINT ["/bin/bash", "/wrapper.sh"]
MySQL container Dockerfile
No need to create a new Docker image since the
Script entrypoint official MySQL image available in the DockerHub is
1 #!/bin/bash enough for our purposes.
2 while ! exec 6<>/dev/tcp/${DATABASE_HOST}/${DATABASE_PORT}; do
3 echo "Trying to connect to MySQL at ${DATABASE_PORT}..."
4 sleep 10
5 done
6
7 java -Djava.security.egd=file:/dev/./urandom
-Dspring.profiles.active=container -jar /app.jar
Cluster creation and configuration
A swarm is a group of machines, physical or virtual, that are running Docker and joined into a
cluster. The cluster we will use is composed by two nodes, a master and one worker.
Virtual machines creation
$ docker-machine create –driver virtualbox myvm1
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 - virtualbox Running tcp://192.168.99.100:2376 v18.06.1-ce
myvm2 - virtualbox Running tcp://192.168.99.101:2376 v18.06.1-ce
Cluster initialization
$ docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100:2377
Swarm initialized: current node 0unmutpbeeeytxpquhiy1b6ok is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-4y8bpxyrbno89dapkkwyjdw3268qfzp128tpf5hecjdti5hb1k-00oatopl9dzw3jejbietxa9vp 192.168.99.100:2377
Services in Docker are really just “containers in production.” A service only runs one image, but it
codifies the way that image runs - what ports it should use, how many replicas of the container
should run so the service has the capacity it needs, and so on. Scaling a service changes the
number of container instances running that piece of software, assigning more computing resources
to the service in the process.
In order to connect services, Docker uses the concept of Stack. A stack is a group of interrelated
services that share dependencies, and can be orchestrated and scaled together.
Application deployment
$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml librarywebapp"
Deployment - 2
1 version: "3" 31 environment:
2 services: 32 - DATABASE_DRIVER=com.mysql.jdbc.Driver
3 mysqldb: 33 - DATABASE_HOST=mysqldb
4 image: mysql:latest 34 - DATABASE_PORT=3306
5 volumes: 35 - DATABASE_NAME=db_example
6 - my-datavolume:/var/lib/mysql 36 - DATABASE_USER=springuser
7 deploy: 37 - DATABASE_PASSWORD=mysql2019
8 placement: 38 networks:
9 constraints: [node.role == manager] 39 - webnet
10 environment: 40 visualizer:
11 - MYSQL_ROOT_PASSWORD=password 41 image: dockersamples/visualizer:stable
12 - MYSQL_DATABASE=db_example 42 ports:
13 - MYSQL_USER=springuser 43 - "8080:8080"
14 - MYSQL_PASSWORD=mysql2019 44 volumes:
15 networks: 45 - "/var/run/docker.sock:/var/run/docker.sock"
16 - webnet 46 deploy:
17 spring: 47 placement:
18 image: davidmonnuar/springbootlibrarydemo:1.0 48 constraints: [node.role == manager]
19 depends_on: 49 networks:
20 - mysqldb 50 - webnet
21 deploy: 51 volumes:
22 replicas: 5 52 my-datavolume:
23 restart_policy: 53 networks:
24 condition: on-failure 54 webnet:
25 resources:
26 limits:
27 cpus: "0.15"
28 memory: 500M
29 ports:
30 - "80:8080"
31
Deployment - 3
Swarm
vm1 (manager) 192.168.99.100 vm2 (worker) 192.168.99.101
Node
Service
MySQL (port 3306)