Files
ObsidianWork/Subjects/Docker.md

415 lines
6.8 KiB
Markdown

---
date: 2025-03-06
---
# Docker
---
## Virtualisation
- VirtualBox
- VMWare
- VSphere
- Proxmox
--
### Architecture
![[Pasted image 20250305170955.png]]
--
### Hyperviseur type 1 (natif)
![[Pasted image 20250305171345.png]]
--
### Hyperviseur type 2 (hosted)
![[Pasted image 20250305171415.png]]
--
### Avantages
+ Isolation complète
+ OS / noyau complètement émulés
+ Tests sur OS spécifiques
+ Lancer un logiciel non supporté
+ Environnment reproductible
+ Image partagée en ISO
+ Ressources disponibles fixes et programmables
---
## Docker
### arrive
--
### Docker
+ Emuler un OS
+ Sur un autre OS
+ De manière reproductible
--
### VMs vs Containers
Les différences
![[Pasted image 20250305172704.png]]
+ Pas d'hyperviseur
+ usage direct de l'hôte pour l'émulation
+ Les outils sont partagés également
--
### Avantages par rapport aux VMs
+ Légèreté
+ Moins de choses dans un container que dans un iso
+ Rapidité
+ De mise en route, d'exécution et de destruction
+ containers = VM jetables à la volée
+ Flexibilité dans l'usage des ressources
--
### Inconvénients par rapport aux VMs
+ Isolation partielle
+ Sécurité
+ Pas de ressources fixes
--
### VM ou container ?
#### VM si:
+ Besoin d'une isolation complète
+ D'accéder aux éléments intrinsèques d'un OS (kernel, libs, ...)
+ Usage en ressources prédéfini
#### Docker si:
+ Isolation partielle suffisante
+ "Juste" besoin d'une machine indépendante
+ Flexibilité (ressources, network, etc.)
--
### C'est pas tout
Docker rend programmable un tas de trucs
+ Création et le partage d'images
+ La mise en réseau des containers
+ Le partage de variables, de filesystem avec l'hôtes
+ ...
---
## Docker
### Les engrenages
---
## Fonctionnement général
![[Pasted image 20250305175750.png|768]]
---
## Images
+ Représentation d'un OS et d'un système de fichier déjà préparé
+ Moyen principal de partage d'environnement
+ Template pour les containers
+ Container = instance d'image
+ `docker image ls`
--
### Créer son image
Avec un Dockerfile!
```Dockerfile
FROM python:3.12
WORKDIR /usr/local/app
# Install the application dependencies
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Copy in the source code
COPY src ./src
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
```
+ `docker build .`
+ Mais où est l'OS là dedans ?
--
### Images de base
--
### Layers
![[Pasted image 20250305180252.png|768]]
--
### En résumé
+ Les images décrivent comment créer un container, sur quel OS, etc.
+ Les images encapsulent et compressent notre application
+ Partagées et versionnées en layers
+ Décrites à l'aide d'un Dockerfile
+ `docker build` pour compiler le Dockerfile en image
---
## Containers
--
### Instance d'image
+ On peut avoir plusieurs containers qui lancent la même image
+ C'est même le principe de Kubernetes
+ Uniques par leur container layer mais c'est tout
+ `docker run`
--
### Examples
+ `docker run busybox`
+ `docker run busybox:latest`
+ `docker run busybox bash`
--
### Les paramètres d'un container
+ L'image (obligatoire) et son tag (optionnel)
+ Les variables d'environnement
+ Les volumes
+ Les ports
+ Le network
+ Et plus encore
--
### Variables d'environnement
+ Permet de définir sur la container layer une variable d'environnement au moment de la création du container
+ Pratique pour paramétrer une application
+ `docker run -e` ou `docker run --env-file`
--
### Examples
+ `docker run -e TEST=coucou busybox`
+ `docker run -e USER=alex -e PASSWORD=whoops busybox`
+ `docker run --env-file=./.env busybox`
--
### Volumes
+ Espace de stockage persistant
+ Peut-être nommé ou anonyme
+ Permet de monter le filesystem hôte sur celui du container
+ `docker volume`
--
### Examples
+ `docker volume ls`
+ `docker volume create myvolume`
+ `docker run -v myvolume:/data:ro busybox:latest`
+ `docker run -v ./src:/app busybox:latest`
--
### Ports
+ Par défaut, le container est complètement isolé
+ On peut ouvrir certains ports pour réseaux pour échanger du traffic
+ On map un port de l'hôte vers un port du container
+ `docker run --port`
--
### Exemples
+ `docker run --port 8080:80 nginx`
+ `docker run -p 8081:80 nginx`
+ `docker run -p 8082:80 nginx`
--
### Network
+ Les containers peuvent être connectés sur un réseau dédié
+ Permet de connecter les containers entre eux en les gardant isolés de l'hôte
+ Permet de simuler des architectures réseau
+ `docker network`
--
### Exemples
+ `docker network ls`
+ `docker network create --ipv4 --subnet 172.18.0.0/24 v4net`
+ `docker network create --ipv6 --subnet 2001:db8::/64 v6net`
+ `docker run --network=v6net -p 8080:80 nginx`
--
### Autres paramètres
+ healthcheck
+ entrypoint
+ command
+ cpus
+ memory
+ labels
+ ...
---
## Registries
--
### Container registry
+ Permet de partager des images
+ Mais aussi de les versionner avec les tags
+ Docker hub
+ ghcr.io - GitHub Container Registry
--
### Télécharger une image
+ `docker image pull`
+ `docker pull`
+ Implicitement lancé par `docker run` si l'image n'existe pas sur l'hôte
--
### Uploader une image
+ `docker image push`
+ `docker push`
+ Une image DOIT être taggée pour être uploadée avec `docker image tag`
--
### En pratique
On utilise rarement `pull` directement
On utilise souvent une CI pour `push`
```yaml
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
tags: user/app:latest
```
---
## Infrastructure as Code
IaC
--
### Le problème
+ On veut mettre en place, maintenir et étendre une infrastructure avec Docker
+ Toutes ces commandes Docker sont difficiles à retenir et reproduire
+ Elles ne sont pas versionnables
--
### Solution 1 - script
+ Écrire les commandes dans un script bash
+ OS spécifique
+ Difficilement idempotent (programmation impérative)
--
### Solution 2 - python
+ Utiliser un script python
+ OS agnostique
+ Toujours impérative
--
### Solution 3 - IaC
+ Programmation déclarative
+ On écrit ce qu'on veut, pas comme y arriver
+ OS agnostique
--
### Terraform / OpenTofu
+ Outil populaire de IaC
+ Extremement puissant et modulable
+ Écrit en HCL
```hcl
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-bucket"
acl = "private"
}
```
--
### Docker Compose
+ Natif avec Docker
+ Utilise du YAML (plus standard que HCL)
---
## Kubernetes