Containers et Docker

Introduction

Historique

- MainFrame IBM
- Batch Processing
- Mono-utilisateur
- Virtualisation du main-framew

VM modernes

  • Emulation du hardware

  • Déploiement de services

  • Anciennement 1 service => 1 machine

  • Plusieurs services sur la même machine: difficultés, incompatibilités, maj, etc.

  • Comment mieux utiliser le hardware tout en isolant les services ?

But: Rassembler les services sur un même matériel

Schema VM

VM1             VM2         VM3
---             ---         ---
Apps            Apps        Apps
Libs            Libs        Libs
OS              OS          OS
------------------------------------------
|                                          |
|                                          |
|       Hyperviseur                        |
|                                          |
|                                          |
-----------------------------------------------
|                                              |
|                                              |
|     matériel                                 |
|                                              |
-----------------------------------------------

techniquement

Code binaire dans la VM Hyperviseur contient un autre compilateur qui transforme le code binaire vers le code binaire de l’architecture souhaitée : JIT-like.

Containers

  • Solomon Hykes

  • Containers de bateau : Ports équipés, standardisation

  • Fonctionnement dev-prod identique

Schema Containers

Container1     Container2  Container 3
----------     ----------  ------------
Apps            Apps        Apps
Libs            Libs        Libs

----------------------------------------

-----------------------------------------------
               OS hôtes
-----------------------------------------------
|                                           |
|                                           |
|               Machine                     |
|                                           |
|                                           |
---------------------------------------------

Explications

  • Le container n’a pas d’OS

  • Mais on ne peut pas faire tourner un container Windows sous Linux

  • Containers légers (mémoire, temps d’activation)

  • Isolés les uns des autres:

    • Namespaces pour les processus et le réseau

    • A l’intérieur du container on peut être root sans forcément être root ps aux => Processus a 1 PID

Containers peuvent être référencés par leur nom ou par leur ID

Pb d’incompatibilité de bibliothèques:

  • Par exemple virtualenv en Python ou Node

  • Docker offre une isolation similaire pour les bibliothèques

Technique

Commandes de base

docker start --help

L’option -i connect l’entrée du terminal à la sortie du container:

docker run -ti ubuntu bash

On est root à l’intérieur du container

Tous les docker présents ou quittés:

docker ps -a

Microservices

Un container est destiné à contenir des microservices qui ensuite communiqueront entre eux. Exemple: - Serveur Web - API - BD qui se trouvent dans des containers différents.

Suppression et lancement de containers

On supprime les containers existants:

docker rm $(docker ps -aq)
docker run nginx

Bloque le terminal donc on le relance en mode detaché:

docker run -d nginx

Autres commandes de base

Arrêter un container

docker stop

Mapping de ports réseaux:

docker run -d p 4000:80 nginx

Le port 4000 est mappé au port 80 à l’intérieur du container A l’IUT, plage de ports réservée par user

App HelloWorld

Créons une app1 hello:

mkdir Docker/app1
echo "hello world" > Docker/app1/hello

Bind Mount:

docker run -ti -v ~/Docker/app1:/foo ubuntu bash

Nginx avec bash:

docker run -d nginx bash

Config serveur nginx

  • on modifie /usr/share/nginx/html

Systèmes de fichiers ‘empilables’ : union fs

  • aufs

  • overlay fs

  • union fs

  • Top level RW

  • Level -1 R

  • Level -2 R

  • Level -3 R

Ce qui permet le démarrage très rapide des containers

Docker Files

App Docker multi container

Images plus petites: python:alpine ou alpine:python3

3 containers: - api - mongo - app

mongo

docker run --add-host mydocker:99.99.99.99 -p 4000:2707 - $PWD/mongo/db:/data/db --name todos-mongo mvertes/alpine-mongo

Api

docker run --add-host mydocker:99.99.99.99 -p 4001:8082  --name todos-api duchier/todos-api-v1

App

docker run --add-host mydocker:99.99.99.99 -p 4002:7777  --name todos-app duchier/todos-app-v1

Réglages

  • Dans APP: API_URL configurée à 4001

  • Dans API: MONGO configuré sur 4000

  • Docker configure automatiquement des interfaces virtuelles

Nettoyage

docker stop $(docker ps -aq)
docker rm $(docker ps -aq)

Création d’un réseau dédié pour notre Docker multi-container

docker network create --driver bridge todos-net
docker run --network todos-net --name todos-api -d -v $PWD/mongo/db/:/data/db mvertes/alpine-mongo

Dans API, l’hôte a contacter est maintenant ‘todos-mongo’

docker run --network todos-net -d -p 4002:7777 --name todos-app duchier/todos-app-v2

Dans APP:

API_URL = 'todos-api:8082'

docker-compose

docker-compose --help
  • build

  • up

  • mode swarm (déploiement cloud)

  • scale

basé sur le fichier docker-compose.yml

services:
  todos-mongo:
    image: mvertes/alpine-mongo
    volumes:
      - /home/denys/cours/lp-docker/todos-demo/mongo/db:/data/db
  todos-api:
    build: api
  todos-app:
    build: app
    ports:
      - 4002:7777

Vérifions que ça marche et puis

docker networks ls

bridge par défaut Dans le cloud on aurait un overlay

On arrête tout:

Docker-compose down

Attention à la persitence des données si besoin …

auto-scaling

services:
  web:
    image:
    volumes
  redis:
   ../..
lb:
  image: dockercloud/haproxy
  ports:
    - 80:80
  links:
    - web
  networks:
    - front-tier
    - back-tier
   volumes:
     - /var/run/docker.sock:/var/run/docker.sock
networks:
  front-tier:
    driver: bridge
  back-tier:
    driver: bridge

Lancement avec scaling

docker compose web --scale=3 up -d