Module 17 : Conteneurisation
Objectifs du Module
À l'issue de ce module, vous serez capable de :
- Comprendre les concepts de conteneurisation
- Utiliser Docker et Podman efficacement
- Créer et optimiser des images
- Gérer les volumes et le réseau
- Orchestrer avec Docker Compose
Durée : 10 heures
Niveau : Expert
1. Concepts Fondamentaux
Conteneurs vs VMs
graph TB
subgraph "Virtual Machines"
H1[Hardware]
HV[Hypervisor]
VM1[VM1<br/>OS + Libs + App]
VM2[VM2<br/>OS + Libs + App]
H1 --> HV
HV --> VM1
HV --> VM2
end
subgraph "Containers"
H2[Hardware]
OS[Host OS]
CR[Container Runtime]
C1[Container 1<br/>Libs + App]
C2[Container 2<br/>Libs + App]
H2 --> OS
OS --> CR
CR --> C1
CR --> C2
end
| Aspect | VM | Conteneur |
|---|---|---|
| Isolation | Complète (hyperviseur) | Processus (namespaces) |
| Taille | GB | MB |
| Démarrage | Minutes | Secondes |
| Ressources | Élevées | Faibles |
| Portabilité | Moyenne | Excellente |
Technologies Linux
# Namespaces - Isolation
# - PID : Processus
# - NET : Réseau
# - MNT : Montages
# - UTS : Hostname
# - IPC : Communication inter-processus
# - USER : Utilisateurs
# Cgroups - Limitation des ressources
# - CPU
# - Mémoire
# - I/O
# - Réseau
# Union FS - Système de fichiers en couches
# - OverlayFS (default)
# - AUFS, Btrfs, ZFS
2. Docker
Installation
# RHEL/Rocky
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install docker-ce docker-ce-cli containerd.io
# Ubuntu
sudo apt install docker.io
# Démarrer
sudo systemctl enable --now docker
# Ajouter l'utilisateur au groupe docker
sudo usermod -aG docker $USER
newgrp docker
Commandes Essentielles
# Images
docker pull nginx:alpine
docker images
docker rmi nginx:alpine
# Conteneurs
docker run -d --name web -p 8080:80 nginx:alpine
docker ps
docker ps -a
docker stop web
docker start web
docker rm web
# Logs et debug
docker logs -f web
docker exec -it web /bin/sh
docker inspect web
# Nettoyage
docker system prune -a
docker volume prune
docker network prune
Options de Run
# Mapping de ports
docker run -p 8080:80 nginx # host:container
# Variables d'environnement
docker run -e MYSQL_ROOT_PASSWORD=secret mysql
# Volumes
docker run -v /host/path:/container/path nginx
docker run -v myvolume:/data nginx
# Réseau
docker run --network mynetwork nginx
# Ressources
docker run --memory=512m --cpus=1 nginx
# Restart policy
docker run --restart=always nginx
# Exemple complet
docker run -d \
--name webapp \
-p 8080:80 \
-v ./html:/usr/share/nginx/html:ro \
-e NGINX_HOST=localhost \
--memory=256m \
--cpus=0.5 \
--restart=unless-stopped \
nginx:alpine
3. Dockerfile
Structure
# syntax=docker/dockerfile:1
# Image de base
FROM python:3.11-slim
# Métadonnées
LABEL maintainer="admin@example.com"
LABEL version="1.0"
# Variables de build
ARG APP_VERSION=1.0.0
# Variables d'environnement
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
APP_HOME=/app
# Répertoire de travail
WORKDIR $APP_HOME
# Copier les dépendances d'abord (cache)
COPY requirements.txt .
# Installer les dépendances
RUN pip install --no-cache-dir -r requirements.txt
# Copier le code
COPY . .
# Créer un utilisateur non-root
RUN useradd -r -s /bin/false appuser && \
chown -R appuser:appuser $APP_HOME
USER appuser
# Port exposé
EXPOSE 8000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
# Commande par défaut
CMD ["python", "app.py"]
Multi-stage Build
# syntax=docker/dockerfile:1
# Stage 1: Build
FROM golang:1.21-alpine AS builder
WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o app .
# Stage 2: Runtime
FROM alpine:3.18
RUN apk --no-cache add ca-certificates
WORKDIR /app
# Copier uniquement le binaire
COPY --from=builder /build/app .
# Utilisateur non-root
RUN adduser -D -H appuser
USER appuser
EXPOSE 8080
CMD ["./app"]
Bonnes Pratiques
# ❌ Mauvais
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y python3
RUN apt-get install -y pip
COPY . /app
# ✅ Bon
FROM python:3.11-slim
# Combiner les RUN pour réduire les layers
RUN apt-get update && \
apt-get install -y --no-install-recommends \
curl \
ca-certificates && \
rm -rf /var/lib/apt/lists/*
# Copier requirements en premier (cache Docker)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copier le code en dernier
COPY . /app
Build et Push
# Build
docker build -t myapp:1.0 .
docker build -t myapp:1.0 -f Dockerfile.prod .
# Tag
docker tag myapp:1.0 registry.example.com/myapp:1.0
# Push
docker login registry.example.com
docker push registry.example.com/myapp:1.0
# Build multi-architecture
docker buildx create --use
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t myapp:1.0 \
--push .
4. Volumes et Persistance
Types de Volumes
# Named volumes (recommandé)
docker volume create mydata
docker run -v mydata:/data nginx
docker volume ls
docker volume inspect mydata
# Bind mounts
docker run -v /host/path:/container/path nginx
docker run -v $(pwd)/config:/etc/nginx/conf.d:ro nginx
# tmpfs (en mémoire)
docker run --tmpfs /tmp nginx
Backup et Restore
# Backup d'un volume
docker run --rm \
-v mydata:/source:ro \
-v $(pwd):/backup \
alpine tar czf /backup/mydata.tar.gz -C /source .
# Restore
docker run --rm \
-v mydata:/dest \
-v $(pwd):/backup:ro \
alpine tar xzf /backup/mydata.tar.gz -C /dest
5. Réseau Docker
Types de Réseaux
# Bridge (défaut)
docker network create mynetwork
docker run --network mynetwork --name app1 nginx
docker run --network mynetwork --name app2 nginx
# app1 peut ping app2 par nom
# Host
docker run --network host nginx
# None
docker run --network none nginx
# Overlay (Swarm)
docker network create --driver overlay myoverlay
Configuration Réseau
# Créer un réseau personnalisé
docker network create \
--driver bridge \
--subnet 172.20.0.0/16 \
--ip-range 172.20.240.0/20 \
--gateway 172.20.0.1 \
mynetwork
# Connecter un conteneur
docker network connect mynetwork mycontainer
# Inspecter
docker network inspect mynetwork
# DNS personnalisé
docker run --dns 8.8.8.8 --dns-search example.com nginx
6. Docker Compose
Fichier docker-compose.yml
# docker-compose.yml
version: '3.8'
services:
web:
build:
context: ./web
dockerfile: Dockerfile
image: myapp-web:latest
ports:
- "8080:80"
environment:
- DB_HOST=db
- DB_NAME=myapp
volumes:
- ./web/static:/var/www/static:ro
depends_on:
db:
condition: service_healthy
networks:
- frontend
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
api:
build: ./api
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_URL=postgres://user:pass@db:5432/myapp
depends_on:
- db
- redis
networks:
- backend
db:
image: postgres:15-alpine
volumes:
- db_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: myapp
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
networks:
- backend
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- web
- api
networks:
- frontend
networks:
frontend:
backend:
volumes:
db_data:
redis_data:
Commandes Compose
# Démarrer
docker compose up -d
# Voir les logs
docker compose logs -f
docker compose logs -f web
# Status
docker compose ps
# Arrêter
docker compose stop
docker compose down
docker compose down -v # Supprime aussi les volumes
# Rebuild
docker compose build
docker compose up -d --build
# Scaling
docker compose up -d --scale api=3
# Exec
docker compose exec web /bin/sh
7. Podman (Alternative Rootless)
Installation
Commandes (compatibles Docker)
# Alias pour compatibilité
alias docker=podman
# Commandes identiques
podman pull nginx:alpine
podman run -d --name web -p 8080:80 nginx:alpine
podman ps
podman logs web
# Mode rootless (sans sudo)
podman run --rm nginx:alpine
# Pods (groupe de conteneurs)
podman pod create --name mypod -p 8080:80
podman run -d --pod mypod nginx
podman run -d --pod mypod redis
# Générer un fichier Kubernetes
podman generate kube mypod > pod.yaml
Différences Podman vs Docker
| Aspect | Docker | Podman |
|---|---|---|
| Daemon | Oui (dockerd) | Non (daemonless) |
| Root | Par défaut | Rootless natif |
| Pods | Non | Oui |
| Systemd | Limité | Intégration native |
| Kubernetes | Non | Génération YAML |
Intégration Systemd
# Générer un service systemd
podman generate systemd --name web --files
# Installer en user service
mkdir -p ~/.config/systemd/user
mv container-web.service ~/.config/systemd/user/
# Activer
systemctl --user enable --now container-web
systemctl --user status container-web
# Pour démarrage au boot (sans login)
loginctl enable-linger $USER
8. Sécurité des Conteneurs
Bonnes Pratiques
# Utilisateur non-root
FROM alpine:3.18
RUN adduser -D -H appuser
USER appuser
# Image minimale
FROM scratch
COPY app /app
CMD ["/app"]
# Pas de secrets dans l'image
# ❌ ENV API_KEY=secret
# ✅ Runtime: docker run -e API_KEY
Scan de Sécurité
# Trivy
trivy image nginx:alpine
trivy image --severity HIGH,CRITICAL myapp:latest
# Docker Scout
docker scout cves myapp:latest
# Snyk
snyk container test myapp:latest
Runtime Security
# Read-only filesystem
docker run --read-only nginx
# Capabilities
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx
# Seccomp
docker run --security-opt seccomp=profile.json nginx
# AppArmor
docker run --security-opt apparmor=docker-default nginx
# No new privileges
docker run --security-opt no-new-privileges nginx
9. Exercice Pratique
Exercice : Application Multi-conteneurs
Créer une stack complète avec :
- Frontend React (Nginx)
- Backend API (Python/Node)
- Base de données PostgreSQL
- Cache Redis
- Reverse proxy Nginx
Exigences : - Dockerfile multi-stage pour le frontend - Health checks sur tous les services - Volumes persistants pour la BDD - Réseau isolé backend/frontend - Variables d'environnement via .env
Durée estimée : 60 minutes
Points Clés à Retenir
| Concept | Commande/Fichier |
|---|---|
| Run | docker run -d -p 80:80 nginx |
| Build | docker build -t app . |
| Compose | docker compose up -d |
| Volumes | -v data:/app/data |
| Network | --network mynet |
| Logs | docker logs -f container |
| Exec | docker exec -it container sh |
Retour au : Programme de la Formation
Navigation
| ← Module 16 : Haute Disponibilité | Module 18 : Kubernetes → |