This commit is contained in:
stiti
2025-04-08 17:14:02 +02:00
parent a0e2bb3ee0
commit f05c9725a7
6 changed files with 460 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
# TP3 Docker Networks - Commandes
## 1. Création des réseaux
### Création d'un réseau bridge personnalisé
```bash
docker network create bridge-tp3
```
### Visualisation des réseaux disponibles
```bash
docker network ls
```
## 2. Création des conteneurs
### Création des conteneurs sur le réseau bridge-tp3
```bash
docker run -d --name web1 --network bridge-tp3 nginx
docker run -d --name web2 --network bridge-tp3 nginx
```
### Création d'un conteneur sur le réseau host
```bash
docker run -d --name web3 --network host nginx
```
### Création d'un conteneur sur le réseau none
```bash
docker run -d --name web4 --network none nginx
```
### Vérification des conteneurs créés
```bash
docker ps
```
## 3. Tests de communication
### Installation de ping dans les conteneurs
```bash
docker exec web1 apt-get update
docker exec web1 apt-get install -y iputils-ping
docker exec web2 apt-get update
docker exec web2 apt-get install -y iputils-ping
docker exec web3 apt-get update
docker exec web3 apt-get install -y iputils-ping
```
Note: L'installation de ping sur web4 (réseau none) ne fonctionnera pas car il n'a pas d'accès réseau.
### Récupération des adresses IP des conteneurs
```bash
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web1
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web2
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web3
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web4
```
### Test de ping entre web1 et web2
```bash
docker exec web1 ping -c 4 web2
```
### Test de ping entre web1 et web3 (par IP hôte)
```bash
# Remplacer HOST_IP par l'adresse IP de votre machine hôte
docker exec web1 ping -c 4 HOST_IP
# Dans mon cas :
docker exec web1 ping -c 4 172.16.3.195
```
### Test de ping entre web1 et web4
```bash
# Ce test échouera car web4 n'a pas de réseau
# Nous aurons besoin de l'adresse IP de web4, mais comme il est sur le réseau none, il n'en a pas
```
### Test d'accès HTTP
#### Accès à web1
```bash
# Exposer le port de web1 si ce n'est pas déjà fait
docker stop web1
docker run -d --name web1 -p 8081:80 --network bridge-tp3 nginx
# Tester l'accès
curl http://localhost:8081
```
#### Accès à web2
```bash
# Exposer le port de web2
docker stop web2
docker run -d --name web2 -p 8082:80 --network bridge-tp3 nginx
# Tester l'accès
curl http://localhost:8082
```
#### Accès à web3 (réseau host)
```bash
# web3 utilise directement le port 80 de l'hôte, donc il faut s'assurer qu'il n'est pas déjà utilisé
curl http://localhost:80
# ou simplement
curl http://localhost
```
#### Accès à web4 (réseau none)
```bash
# Ce test échouera car web4 n'a pas de connectivité réseau
# Il n'est pas possible d'accéder à un conteneur sur le réseau none depuis l'extérieur
```
## 4. Nettoyage
### Arrêt et suppression des conteneurs
```bash
docker stop web1 web2 web3 web4
docker rm web1 web2 web3 web4
```
### Suppression du réseau personnalisé
```bash
docker network rm bridge-tp3
```

View File

@@ -0,0 +1,73 @@
# TP3 Docker Networks - Réponses aux questions
## 1. Différences entre les types de réseaux Docker
J'ai découvert qu'il existe plusieurs types de réseaux dans Docker qui fonctionnent différemment :
**Réseau Bridge** :
- C'est le réseau par défaut de Docker
- Il crée un réseau privé interne où les conteneurs peuvent communiquer entre eux
- Chaque conteneur a sa propre adresse IP
- Pour accéder à un conteneur depuis ma machine, je dois utiliser l'option -p pour exposer les ports
**Réseau Host** :
- Dans ce mode, le conteneur utilise directement le réseau de la machine hôte
- Pas d'isolation réseau
- Les ports sont directement accessibles sans mappage
- C'est plus rapide mais moins sécurisé
**Réseau None** :
- Ce réseau désactive complètement toute connexion
- Le conteneur n'a pas d'interface réseau
- Il est totalement isolé
- Utile pour des traitements où la sécurité est critique
## 2. Pourquoi web4 est-il isolé et inaccessible ?
Le conteneur web4 est complètement isolé parce que je l'ai créé avec l'option `--network none`. Cela signifie que :
- Il n'a aucune interface réseau configurée
- Il n'a pas d'adresse IP
- Il ne peut ni recevoir ni envoyer de données sur le réseau
- Je ne peux pas installer ping dessus car il ne peut pas télécharger de packages
- Je ne peux pas accéder au serveur nginx qu'il contient
C'est comme si j'avais mis le conteneur dans une pièce sans portes ni fenêtres. Le serveur nginx tourne bien à l'intérieur, mais personne ne peut y accéder.
## 3. Analyse des résultats des tests de communication
**Test entre web1 et web2** :
Ces deux conteneurs peuvent communiquer facilement car ils sont sur le même réseau bridge-tp3. J'ai pu faire un ping de l'un à l'autre en utilisant simplement leur nom. C'est pratique car Docker gère la résolution de noms automatiquement dans un réseau bridge personnalisé.
**Test entre web1 et web3** :
Le ping ne fonctionne pas directement avec le nom "web3" car web3 est sur le réseau host et n'a pas de nom DNS dans le réseau bridge. J'ai dû utiliser l'adresse IP de ma machine hôte pour atteindre web3. C'est comme s'ils étaient sur deux réseaux différents sans passerelle directe.
**Test entre web1 et web4** :
Impossible de communiquer avec web4 depuis web1. Le conteneur web4 (réseau none) n'a pas d'adresse IP et est complètement isolé. C'est comme essayer d'appeler quelqu'un qui n'a pas de téléphone.
**Accès HTTP depuis ma machine** :
- J'ai pu accéder à web1 et web2 via les ports que j'ai exposés (8081 et 8082)
- J'ai pu accéder à web3 directement sur localhost:80 (car il utilise le réseau host)
- Impossible d'accéder à web4 (car il n'a aucune connectivité réseau)
## 4. Recommandations pour chaque cas d'usage
**Pour un serveur web public** :
Je recommanderais un réseau **bridge** avec exposition de ports. C'est le plus adapté car :
- Je peux exposer uniquement les ports nécessaires (80/443)
- Les autres services du conteneur restent protégés
- Je peux avoir plusieurs serveurs web sur différents ports
**Pour une base de données** :
Je choisirais un réseau **bridge personnalisé** sans exposition de ports. Pourquoi ?
- La base de données doit être accessible seulement par l'application
- Je ne veux pas que quelqu'un puisse y accéder depuis Internet
- Les conteneurs de mon application peuvent y accéder par nom
**Pour un service de cache Redis** :
Je mettrais ça aussi sur un réseau **bridge personnalisé**, sur le même réseau que mon application. Parce que :
- Seule mon application a besoin d'accéder au cache
- C'est plus rapide si les conteneurs sont sur le même réseau
- C'est plus sécurisé de ne pas exposer Redis à l'extérieur
En conclusion, j'ai compris que le choix du réseau dépend vraiment de ce qu'on veut faire avec le conteneur et de qui doit y accéder. C'est un compromis entre accessibilité, sécurité et performance.

View File

@@ -0,0 +1,65 @@
# Commandes Docker pour l'exercice 2
## Construction de l'image
```bash
docker build -t apache-static:1.8 .
```
## Lancement d'un conteneur
```bash
docker run -d -p 8080:80 --name apache-static-container apache-static:1.8
# 98f3ffa33561f25e0320a4eeac67e83fe5629e8caf4883f7a35c83b9295e4a5a
```
## Vérification du site web
```bash
curl http://localhost:8080
```
Résultat :
```html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Stage - Compte à rebours</title>
<style>
body {...
```
## Vérification des variables d'environnement
```bash
docker exec apache-static-container env | grep SCHOOL
docker exec apache-static-container env | grep LEVEL
```
Résultat :
```bash
SCHOOL=IUT
LEVEL=1
```
## Vérification du healthcheck
```bash
docker inspect --format='{{json .State.Health}}' apache-static-container
```
Résultat :
```json
{"Status":"healthy","FailingStreak":0,"Log":[{"Start":"2025-04-08T16:15:36.513084342+02:00","End":"2025-04-08T16:15:36.577562059+02:00","ExitCode":0,"Output":"Connecting to localhost ([::1]:80)\nremote file exists\n"}]}
```
## Publication sur Docker Hub
```bash
# Connexion à Docker Hub
docker login
# Tag de l'image
docker tag apache-static:1.8 username/apache-static:1.8
# Push vers Docker Hub
docker push moncef45/apache-static:1.8
# mon username = moncef45
```
Lien Docker Hub: https://hub.docker.com/u/moncef45

View File

@@ -0,0 +1,33 @@
# Utilisation d'Alpine Linux comme base légère
FROM httpd:alpine3.21
# Définition des labels
LABEL MAINTAINER="moncef" \
VERSION="1.8" \
TP="3"
# Configuration des variables d'environnement
ENV SCHOOL="IUT" \
LEVEL="1.8"
# Exposition du port 80
EXPOSE 80
# Clonage du dépôt Git (temporairement)
RUN apk add --no-cache git && \
git clone https://github.com/MaximePIERRONT/beforeStage.git /tmp/repo && \
cp /tmp/repo/static-site.html /usr/local/apache2/htdocs/index.html && \
# Personnalisation du fichier HTML
sed -i 's/NOM PRENOM/moncef/g' /usr/local/apache2/htdocs/index.html && \
# Nettoyage
rm -rf /tmp/repo && \
apk del git
# Configuration du healthcheck
HEALTHCHECK --interval=1m --timeout=1s \
CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1
# Commande de démarrage d'Apache
# Note: Cette commande est déjà définie dans l'image de base et n'est pas nécessaire,
# mais je la laisse pour la clarté
CMD ["httpd-foreground"]

View File

@@ -0,0 +1,51 @@
# Réponses aux questions sur Docker - TP3
## 1. Pourquoi choisir un OS minimal ? Quels sont les avantages ?
J'ai choisi Alpine Linux comme base de mon image Docker car c'est un OS ultra léger qui présente plein d'avantages pour les conteneurs.
D'abord, la taille fait une énorme différence ! Une image Alpine fait environ 5-8 Mo alors qu'une image Ubuntu standard peut facilement atteindre 300 Mo. Pendant les TPs, j'ai remarqué que mes builds avec Alpine prenaient beaucoup moins de temps, et c'était vraiment pratique quand je devais faire plusieurs essais pour corriger des erreurs.
L'aspect sécurité est aussi super important. Avec moins de composants installés, il y a moins de risques de vulnérabilités. On nous a expliqué en cours que chaque package supplémentaire augmente potentiellement la surface d'attaque. C'est logique : moins de code = moins de bugs possibles = moins de failles de sécurité.
Les performances sont bien meilleures aussi. J'ai testé les deux approches et les conteneurs basés sur Alpine démarrent presque instantanément et utilisent moins de RAM. Sur mon vieux PC, ça fait une grande différence, surtout quand je lance plusieurs conteneurs en même temps pour les TPs.
Et puis, quand on travaille en équipe ou qu'on déploie sur différents environnements, le fait de pouvoir transférer rapidement les images est un gros plus. Avec des images légères, le push/pull vers Docker Hub prend quelques secondes au lieu de plusieurs minutes.
## 2. Quel est l'intérêt d'utiliser des variables d'environnement ?
Avant ce TP, je ne comprenais pas vraiment l'intérêt des variables d'environnement, mais maintenant je trouve ça super pratique !
Le principal avantage que j'ai découvert, c'est la flexibilité. Dans mon Dockerfile, j'ai défini SCHOOL="IUT" et LEVEL="1.8", mais j'aurais pu facilement les changer au lancement avec un simple `-e SCHOOL=AUTRE_ECOLE`. Ça évite d'avoir à recréer complètement l'image pour chaque petite modification de configuration.
C'est aussi beaucoup plus propre de séparer le code de la configuration. Le prof nous a expliqué que c'est un principe des "12-factor apps" qu'on utilise dans le développement moderne. Dans un vrai projet, au lieu de coder en dur les URLs ou les identifiants de base de données, on utiliserait des variables d'environnement.
J'ai trouvé ça particulièrement utile pendant les tests. Je pouvais lancer le même conteneur avec différentes configurations juste en changeant les variables. Par exemple, pour tester avec différents niveaux d'accès ou différentes configurations de serveur.
Un autre point important qu'on a abordé en cours, c'est la sécurité. Si j'avais besoin de stocker un mot de passe ou une clé API, je ne voudrais surtout pas les mettre directement dans mon Dockerfile (qui pourrait être partagé sur GitHub). Avec les variables d'environnement, on peut les injecter au moment du déploiement.
## 3. À quoi sert le healthcheck dans un contexte de production ?
Le healthcheck a été une découverte pour moi pendant ce TP. Dans notre code, j'ai configuré un healthcheck qui vérifie toutes les minutes si le serveur web répond correctement.
J'ai compris que dans le monde réel, ce n'est pas parce qu'un conteneur tourne que l'application fonctionne correctement. Par exemple, Apache pourrait être démarré mais bloqué ou incapable de traiter des requêtes. Le healthcheck permet de détecter ces situations avant que les utilisateurs ne rencontrent des problèmes.
Ce qui m'a impressionné, c'est l'intégration avec les outils d'orchestration. Notre prof nous a expliqué que dans un environnement Kubernetes, les conteneurs qui échouent à leur healthcheck peuvent être automatiquement redémarrés ou remplacés. C'est comme avoir un administrateur système qui surveille constamment l'application, mais de façon automatisée !
Dans notre TP, j'ai utilisé wget pour vérifier que le serveur répond, mais j'imagine qu'en entreprise, on pourrait faire des tests plus sophistiqués comme vérifier que la connexion à la base de données fonctionne ou que certaines fonctionnalités clés sont disponibles.
J'ai aussi appris que les healthchecks jouent un rôle important pendant les déploiements. Par exemple, lors d'une mise à jour, le nouveau conteneur ne recevra du trafic que lorsque son healthcheck sera positif, ce qui évite d'envoyer des utilisateurs vers une application qui n'est pas encore prête.
## 4. Comment pourriez-vous optimiser davantage cette image ?
Après avoir terminé le TP, j'ai réfléchi à plusieurs façons d'améliorer mon image Docker :
Une technique que j'aimerais essayer est le build multi-étapes. D'après ce que j'ai compris, ça permet d'utiliser un premier conteneur pour les opérations de build (comme la compilation ou la préparation des fichiers), puis de copier uniquement les résultats dans l'image finale. Ça permettrait d'avoir une image de production encore plus légère.
J'ai aussi remarqué que j'utilisais "httpd:alpine3.21" sans vraiment réfléchir. Il serait plus professionnel de choisir précisément la version dont j'ai besoin en fonction des fonctionnalités et des correctifs de sécurité disponibles. Le prof nous a expliqué que c'est important pour la reproductibilité des builds.
Mon Dockerfile contient plusieurs commandes RUN séparées. Je pourrais les combiner pour réduire le nombre de couches et optimiser la taille. Par exemple, toutes les opérations d'installation et de configuration pourraient être dans une seule instruction RUN.
J'ai appris pendant le cours qu'il n'est pas recommandé de faire tourner les applications en tant que root dans les conteneurs. Je pourrais donc ajouter des directives USER pour exécuter Apache avec un utilisateur sans privilèges. Ça limiterait les dégâts en cas de faille de sécurité.
Enfin, même si Apache est très répandu, j'ai découvert que Nginx pourrait être une alternative plus légère pour servir des fichiers statiques. Ça pourrait être intéressant d'essayer de refaire le même exercice avec Nginx pour comparer les performances et la taille des images.

114
TP3/tp3.md Normal file
View File

@@ -0,0 +1,114 @@
# TP3 : Docker Networks & Dockerfile
## Organisation
- Créer un dossier `TP3/`
- Pour chaque exercice, créer un sous-dossier avec les fichiers requis
- Documenter toutes les commandes dans `COMMANDS.md`
- Répondre aux questions dans `QUESTIONS.md`
## Livrables attendus
- Structure du projet :
```
TP3/
├── exo1-networks/
│ ├── COMMANDS.md
│ └── QUESTIONS.md
└── exo2-dockerfile/
├── Dockerfile
├── COMMANDS.md
└── QUESTIONS.md
```
## Exercice 1 : Docker Networks
### Objectif
Comprendre et manipuler les différents types de réseaux Docker et la communication entre conteneurs.
### Actions à réaliser
1. **Création des réseaux**
- Créer un réseau de type bridge nommé "bridge-tp3"
- Utiliser le réseau prédéfini de type host nommé "host"
- Utiliser le réseau prédéfini de type none nommé "none"
2. **Création des conteneurs**
- Créer 2 conteneurs nginx (web1, web2) sur bridge-tp3
- Créer 1 conteneur nginx (web3) sur host
- Créer 1 conteneur nginx (web4) sur none
3. **Tests de communication**
- Tester ping entre web1 et web2
- Tester ping entre web1 et web3
- Tester ping entre web1 et web4
- Tester l'accès HTTP depuis votre machine vers chaque conteneur
4. **Documentation**
- Noter toutes les commandes dans COMMANDS.md
- Expliquer les résultats dans QUESTIONS.md
### Questions à répondre
1. Expliquer les différences entre les types de réseaux Docker
2. Pourquoi web4 est-il isolé et inaccessible ?
3. Analyser les résultats des tests de communication
4. Pour chaque cas d'usage, quel type de réseau recommanderiez-vous :
- Serveur web public
- Base de données
- Service de cache Redis
## Exercice 2 : Dockerfile
### Objectif
Construire une image Docker optimisée pour Apache httpd servant un site web statique.
### Actions à réaliser
1. **Création du Dockerfile**
```dockerfile
# Choisir l'OS le plus léger possible
# Installer Apache httpd
# Définir les labels :
# - MAINTAINER: votre_nom
# - VERSION: 1.8
# - TP: 3
```
2. **Ajout des sources**
- Cloner : https://github.com/MaximePIERRONT/beforeStage.git
- Personnaliser static-site.html :
- Remplacer "NOM PRENOM" par votre nom
3. **Configuration**
- Ajouter les variables d'environnement :
```
SCHOOL: IUT
LEVEL: 1.8
```
- Implémenter un healthcheck (intervalle: 1min, timeout: 1s)
4. **Tests et validation**
- Builder l'image
- Lancer un conteneur
- Vérifier :
- Le site web est accessible
- Les variables d'environnement sont correctes
- Le healthcheck fonctionne
### Questions à répondre
1. Pourquoi choisir un OS minimal ? Quels sont les avantages ?
2. Quel est l'intérêt d'utiliser des variables d'environnement ?
3. À quoi sert le healthcheck dans un contexte de production ?
4. Comment pourriez-vous optimiser davantage cette image ?
### Publication sur Docker Hub
1. Créer un compte Docker Hub si nécessaire
2. Tagger l'image : `docker tag local-image username/repository:tag`
3. Pousser l'image : `docker push username/repository:tag`
4. Ajouter le lien Docker Hub dans COMMANDS.md
## Critères d'évaluation
- Qualité et clarté des explications dans les fichiers QUESTIONS.md
- Précision et exhaustivité des commandes dans COMMANDS.md
- Optimisation et bonnes pratiques dans le Dockerfile
- Compréhension des concepts de réseaux Docker
- Capacité à tester et valider son travail