--- 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