RousselTMLEARNING

TP · Docker : de la découverte à l'expertise

Projet 1 avec correction

La correction est intégrée au TP (Voir les encadrés de couleur vert)

Ce que vous allez apprendre dans ce TP
  • Installer Docker
  • Activer le mode SWARM de Docker
  • De créer un fichier Dockerfile
  • De modifier et/ou surcharger un fichier docker compose existant
  • De créer un fichier Docker compose à partir d'un besoin
  • Déployer un fichier docker compose
  • De créer une stack/service docker avec un fichier docker compose
  • De surveiller son infrastructure avec Prometheus/Grafana
  • De déployer un registre privé avec Harbor
  • Déployer un registre Harbor
  • Importer une image dans un registre
  • Rechercher des vulnérabilités sur une image
  • Mettre en place la surcharge d'un fichier docker compose
  • Utilisation avancée des labels (Mise en place dans le Projet 2)

Introduction #

Ce que vous allez apprendre dans cette section
  • Installer Docker
  • Activer le mode SWARM de Docker
  • De créer un fichier Dockerfile
  • De modifier et/ou surcharger un fichier docker compose existant
  • De créer un fichier Docker compose à partir d'un besoin
  • Déployer un fichier docker compose
  • De créer une stack/service docker avec un fichier docker compose
  • De surveiller son infrastructure avec Prometheus/Grafana
  • De déployer un registre privé avec Harbor
Ce projet a pour objectif de vous faire manipuler différentes notions autour de Docker et surtout de les combiner en vue d'atteindre un objectif. Pour cela, nous allons installer et configurer un cluster Docker avec SWARM d'activé et déployer sur ce dernier différents sous-projets sous forme de stack. Le but est de mettre en place cette architecture : Une configuration matérielle recommandée est 16GO de RAM

Environnement de test #

Pour réaliser ce TP, il vous faudra un environnement Ubuntu(Mais le TP est faisable avec d'autres OS/distributions). Sur cette machine, nous allons créer 3 machines virtuelles avec les caractéristiques suivantes:
  • Machine virtuelle 1 :
    • Nom : manager
    • vCPU : minimum 2
    • RAM : minimum 2 GO
    • IP : 192.168.56.2
  • Machine virtuelle 2 :
    • Nom : worker1
    • vCPU : minimum 2
    • RAM : minimum 2 GO
    • IP : 192.168.56.3
  • Machine virtuelle 3 :
    • Nom : worker1
    • vCPU : minimum 2
    • RAM : minimum 2 GO
    • IP : 192.168.56.4
Pour vous aider à mettre cet environnement en place, nous avons mis à votre disposition un repo avec une configuration Vagrant/Virtualbox prête à l'emploi.

RAPPEL : Ce TP est dédié à la configuration de Docker mais comme il s'agit d'un TP avancé, vous aurez besoin de notions et connaissances autour du DevOps qui ne sont pas propres à Docker mais qui seront utilisées dans vos configurations. Vous aurez besoin des compétences suivantes dont vous pouvez suivre gratuitement la formation : Bien évidemment, on va mettre le maximum d'informations à votre disposition pour vous faire avancer même sans ces prérequis.

Pour cela, il faut installer Vagrant et Virtualbox sur votre machine. Une fois cela fait, il ne vous reste plus qu'à lancer les commandes suivantes:
git clone https://github.com/RousselTM/docker-formation
cd docker-formation/tp/6_projet
vagrant up

Pre-configuration #

Les actions suivantes sont nécessaires pour préparer votre environnement de test.

  1. Les domaines

    Vous devez déclarer les domaines suivants sur votre machine (dans le fichier hosts). Ils seront utilisés pour accéder aux différents sous projet et doivent pointer vers 127.0.0.1(Dans le TP suivant on introduira Traefik pour optimiser la gestion des ports) :
    • tp.elearning.rousseltm.fr: Pour accéder aux applications. Par exemple, pour accéder à l'application 1, on utilisera l'adresse http://tp.elearning.rousseltm.fr/app1
    • registry.tp.elearning.rousseltm.fr : pour accéder à Harbor
    • grafana.tp.elearning.rousseltm.fr : pour accéder à Grafana
    • prometheus.tp.elearning.rousseltm.fr : pour accéder à Prometheus
    En entreprise, vous devez utiliser un serveur DNS.
    Vous devez ajouter cette information dans le fichier hosts. Le chemin pour accéder au fichier va varier en fonction de votre OS hôte :
    • /etc/hosts : Linux
    • C:\Windows\System32\drivers\etc : Windows
    Il vous faudra aussi des droits adminitrateur
  2. Installation Docker

    Vous pouvez vérifier si vos machines sont bien démarrés avec la commande suivante :
    vagrant status
    Si elles sont bien démarrées (status running), vous pouvez vous connecter à la machine manager avec la commande suivante :
    vagrant ssh manager
    Il ne vous reste plus qu'à installer Docker sur l'ensemble des VMs. Une fois l'installation faite, vous devez démarrer le service et le mettre en démarrage automatique
    Retrouvez l'ensemble des procédures d'installation de docker sur cette page Installation Docker.

    Pour notre TP, on va donc suivre la procédure pour l'OS Ubuntu. Vous devez privilégier les procédures qui se basent sur le gestionnaire de package : apt, dnf, yum.

    Vous pouvez demander à Vagrant de faire l'installation automatiquement :
    Il vous suffit de définir à 'true' la variable d'environnement ROUSSELTM_DEPLOY_DOCKER au moment de créer les machines et la configuration Vagrant va installer Docker
    ROUSSELTM_DEPLOY_DOCKER=true vagrant up
    Vous devez lancer les commandes suivantes pour respectivement démarrer et mettre en démarrage automatique Docker
    sudo systemctl start docker
    sudo systemctl enable docker
    Vagrant peut aussi automatiquement configurer votre cluster Docker SWARM :
    ROUSSELTM_DEPLOY_SWARM=true vagrant up
    Bien évidemment, en entreprise, il faudra plutôt utiliser votre solution de configuration as code (Ansible, Salt project, ...).
  3. Mode SWARM

    Vous devez mettre en place le cluster Docker avec le mode SWARM activé. La machine 'manager' doit être le manager du cluster et les machines 'workerX' doivent être les workers du cluster. Comme les machines ont plusieurs IP, on va utiliser l'IP 192.168.56.2 comme adresse de gestion du plan de contrôle.
    RAPPEL : Sur toutes les machines créées par Vagrant il y a un dossier /vagrant qui correspond au montage du dossier dans lequel se trouve le fichier Vagrantfile: donc le contenu dossier 6_projet. Donc vous pouvez utiliser ce dossier pour partager des fichiers entre les machines. Par exemple, le fichier contenant les tokens pour joindre le cluster. Bien évidemment en Production, il faudra utiliser une solution plus sécurisée
    Vous devez fournir la commande Docker qui va permettre de stocker dans le /vagrant/swarm-token-worker le token pour joindre le cluster comme worker.
    Vous devez initialiser le mode swarm sur une machine qui a vocation a être manager donc dans notre cas sur la machine 'manager' avec la commande suivante:
    docker swarm init --advertise-addr 192.168.56.2 --listen-addr 192.168.56.2
    Vous pouvez aussi utiliser le nom de la carte réseau à la place de l'IP (méthode recommandée).

    Pour générer et partager le token qui sera utilisé sur les noeuds worker :
    docker swarm join-token -q worker > /vagrant/swarm-token-worker
    Sur les noeuds worker, vous pouvez les faire joindre avec la commande suivante :
    docker swarm join --advertise-addr 192.168.56.2 --listen-addr 192.168.56.2 --token `cat /vagrant/swarm-token-worker` 192.168.56.2:2377
  4. Réseau partagé

    Vous devez créer les réseaux suivants
    • common-proxy: pour la communication entre les conteneurs via le proxy. Sera pleinement utilisé dans le TP suivant avec l'utilisation de Traefik.
    • common-observability: pour la communication entre les conteneurs d'observabilité
    On fera un déploiement mixte pour manipuler la communication entre des sous projets déployés avec le mode SWARM et ceux sans mode SWARM. Il faut donc mettre en place le bon paramètre sur le réseau 'common-proxy' lors de sa création.
    Sur une machine avec le statut manager(dans notre cas c'est la machine nommée manager), vous pouvez le faire avec les commandes suivantes :
    docker network create --driver overlay --attachable common-proxy
    docker network create --driver overlay common-observability
    Le fait d'utiliser le driver overlay active automatiquement le 'scope' SWARM.

Sous projet 1 #

Ce que vous allez apprendre dans cette section
  • Déployer un registre Harbor
  • Importer une image dans un registre
  • Rechercher des vulnérabilités sur une image
  • Mettre en place la surcharge d'un fichier docker compose
  • Utilisation avancée des labels (Mise en place dans le Projet 2)
Nous allons créer un registre docker avec Harbor sur la machine manager. Nous le ferons fonctionner sur le domaine registry.tp.elearning.rousseltm.fr. Pour ce premier projet, on va le déployer en HTTP sur le port 5000(port par défaut des registres Docker en HTTP).
RAPPEL : Le site officiel de Harbor https://goharbor.io/ et vous pouvez revoir la vidéo de présentation de Harbor à cette adresse : Présentation et déploiement Harbor
  1. Déploiement

    Vous devez installer Harbor avec le service trivy sur le port 5000. Si tout est ok, vous devez pouvoir accéder depuis la machine hôte à Harbor à l'adresse
    http://registry.tp.elearning.rousseltm.fr:5000
    INFORMATION : Dans le dossier 6_projet, vous avez un dossier nommé 'projects' dont le contenu sera automatiquement monté dans /opt/projects sur l'ensemble des VMs. Vous pouvez donc l'utiliser pour gérer vos fichiers pour les sous projets. Nous conseillons 1 dossier par sous projet.
    Vous devez suivre la procédure décrite sur le site de Harbor pour le télécharger et l'installer
    https://goharbor.io/docs/2.11.0/install-config/download-installer/
  2. Personnalisation

    Le script install.sh à généré un fichier docker-compose.yml donc si on souhaite modifier des paramètres il faudra éditer ce fichier. Mais on va perdre toutes nos modifications à chaque exécution du script.

    Vous devez proposer une solution pour éviter cela sachant qu'on souhaite que le conteneur 'proxy' se connecte au réseau 'common-proxy' et qu'il dispose du label dt.owner (Explication de ce label Dynatrace) avec comme valeur 'equipe1'. Dans la même lancée, ajouter un label pour dire à Filebeat de ne pas prendre en compte ses logs.

    On va dans un premier temps déployer simplement avec 'docker compose' pour tester et dans un second temps sous forme de stack 'docker stack'.

    ATTENTION : La surcharge doit aussi être prise en compte par le script install.sh
    Comme le script n'a pas d'option -f pour passer un fichier de surcharge il faut donc utiliser le fichier de surcharge par défaut
    compose.override.yml
    avec comme contenu

Sous projet 2 #

  1. Build image

    Vous devez créer un Dockerfile pour construire une image pour l'application GO suivante qui sera nommée simple-app er aura le tag 1.0 : Cette application doit générer un binaire '/app/simple-app' et utiliser '/app' comme dossier de travail.
    Voici un exemple de Dockerfile : Attention il faut faire un build multi-stage pour éviter de se retrouver avec des outils de DEV dans l'image finale. Vous pouvez builder l'image avec la commande ci-dessous :

    docker build -t simple-app:1.0 .
  2. Ajout de l'image au registre Harbor

    Vous devez envoyer cette image dans le projet(Explication sur la notion de projet dans Harbor) 'library' dans Harbor. On a fait le choix de 'library' car il s'agit du projet Public par défaut. Ainsi, l'image pourra être utilisée dans d'autres projets (Voir TP suivant). Pour rappel suite à votre installation, Harbor est disponible à l'adresse
    http://registry.tp.elearning.rousseltm.fr:5000
    Comme notre registre est en HTTP, il faut indiquer à docker de faire une connexion HTTP au lieu de HTTPS par défaut. Il faut donc ajouter cette configuration dans le fichier '/etc/docker/daemon.json' :
    {
    	...
    	"insecure-registries" : ["registry.tp.elearning.rousseltm.fr:5000"],
    	...
    }
    Voici les commandes pour envoyer l'image dans le registre privé
    docker login registry.tp.elearning.rousseltm.fr:5000
    docker tag simple-app:1.0 registry.tp.elearning.rousseltm.fr:5000/library/simple-app:1.0
    docker push registry.tp.elearning.rousseltm.fr:5000/library/simple-app:1.0
  3. Scan de vulnérabilité

    Vous devez scanner l'image importée pour vérifier ses vulnérabilités face aux failles CVE.

    Dans la console Harbor (http://registry.tp.elearning.rousseltm.fr:5000), vous devez suivre les étapes suivantes :
    1. Cliquer sur le menu 'Projects' à gauche (ouvert par défaut à la connexion à Harbor)
    2. Cliquez sur le projet. Dans notre cas 'library'
    3. Cliquez sur l'image. Dans notre cas 'library/simple-app'
    4. Sélectionnez l'image les tags (artefacts) à scanner. Dans notre cas celui avec le tags '1.0'
    5. Cliquez sur le bouton 'SCAN VULNERABILITY'
  4. Déploiement Docker

    La configuration à construire doit répondre à ces besoins :
    • Application 2-tier: go et redis
    • Les services ne doivent s'exécuter que sur les workers. Cette configuration doit être externalisée pour permettre de la partager avec d'autres applications dans le même cas.
    • Les services doivent utiliser les dernières versions (en production utiliser des versions fixes) des images officielles et l'application GO utiliser l'image construite précédemment et disponible sur Harbor.
    • 1 instance de chaque service
    • Le service GO doit exporter la variable d'environnement APP='APP1'
    • Le service GO doit exporter la variable d'environnement TASK_SLOT dans laquelle vous devez y mettre le numéro de replica du conteneur (Les templates).
    • Le service de l'application go doit rattaché au réseau 'common-proxy'
    Voici un exemple de contenu du fichier docker compose
  5. Répartition de charge

    Vous devez vérifier que lorsque vous appelez l'URL de l'application (http://tp.elearning.rousseltm.fr) il retourne bien cette page et que les champs surlignés changent bien quand vous mettez à jour la page et bascule bien entre les deux conteneurs :
    Comme il s'agit d'une URL en HTTP, il est possible que votre navigateur redirige automatiquement en HTTPS. Vous pouvez désactiver cette option du navigateur mais nous vous recommandons plutôt d'utiliser le mode 'navaigation privée' de ce dernier (il faut reouvrir la page pour voir la répartition de charge). Vous pouvez aussi vérifier cela en ligne de commande avec la commande curl :
    curl http://tp.elearning.rousseltm.fr/

Sous projet 3 #

Sous projet observabilité constitué de Prometheus, de Grafana, de Node exporter et de cAdvisor. Ce sous projet est celui de l'observabilité et donc va nous permettre d'avoir une visibilité sur l'ensemble de notre projet.

  1. Déploiement Docker

    La configuration à construire doit répondre à ces besoins :
    • Rendre accessible Grafana sur le port 3000
    • Rendre accessible Prometheus sur le port 9090
    Vous pouvez vous referer aux commandes du sous projet 2 pour tout ce qui est commande d'exécution. Si tout est OK, votre configuration doit ressembler à cette configuration : Attention au paramétrage de cAdvisor et Node exporter. Ces derniers doivent être configurés pour qu'un conteneur soit crée sur chaque noeud.
  2. Configuration des services

    La configuration à construire doit répondre à ces besoins :
    • Importer automatiquement dans Grafana la datasource Prometheus et Elasticsearch
    • Importer les tableaux de bord avec l'ID : 609
    • Collecter les métriques de Traefik
    • Collecter les métriques de l'ensemble des noeuds du cluster
    • Collecter les métriques de l'ensemble des conteneurs
    Comme indiqué dans le fichier compose.yaml, on a besoin :
    • Un fichier config/grafana/provisioning/datasources/datasource.yml: dont voici un exemple de contenu

    • Un fichier config/prometheus/prometheus.yml: dont voici un exemple de contenu On a deux types de configuration :
      • static_configs : utilisé pour des instances fixes
      • dns_sd_configs: utilisé pour des instances dynamiques.

Niveau de difficulté : ●●●○○ (3/5)

Glossaire de la formation

Micro-services

Architecture où une application est divisée en plusieurs petits services indépendants, souvent déployés dans le Cloud.

Docker

Outil permettant de virtualiser et packager des applications à l'intérieur de conteneurs légers pour un déploiement optimal.Exemple de déploiement d'u...

Prometheus

Système open source de surveillance et d'alerte, particulièrement adapté pour la collecte de métriques dans des environnements dynamiques (comme Kuber...

Kubernetes

Plateforme open source d'orchestration de conteneurs permettant d'automatiser le déploiement, la mise à l'échelle et la gestion des applications conte...

CI/CD

Intégration Continue et Déploiement Continu. Pratiques DevOps visant à automatiser les tests et le déploiement des applications pour livrer plus rapid...

Terraform

Outil d'Infrastructure as Code (IaC) permettant de définir et de provisionner des ressources d'infrastructure cloud et on-premise via des fichiers de ...

Métriques

Mesures numériques collectées à intervalles réguliers (ex: CPU, RAM, temps de réponse) utilisées pour évaluer l'état de santé global d'un système au f...

DevOps

Culture, mouvement et pratiques visant à unifier le développement logiciel (Dev) et l'administration des infrastructures informatiques (Ops).Découvrir...

API Gateway

Passerelle servant de point d'entrée unique pour l'ensemble des requêtes vers des architectures micro-services. Elle gère le routage, la sécurité et l...

Architecture

Conception globale et structurelle d'un système informatique, définissant ses différents composants, leurs relations et les principes guidant son évol...

Artefact (Artifact)

Résultat final d'un processus de compilation ou de construction logicielle (build), tel qu'un fichier .jar, une archive zip ou une image Docker, prêt ...

Repository

Dépôt de stockage centralisé. Peut désigner un dépôt de code source (ex: Git) ou un dépôt d'artefacts et binaires (ex: Harbor, Nexus, Artifactory).

Ansible

Outil open source d'automatisation informatique (IaC) permettant la gestion des configurations, le déploiement d'applications et l'orchestration, fonc...

Articles recommandés

Aide-mémoire Docker : Les commandes essentielles

Un guide pratique regroupant toutes les commandes indispensables pour manipuler les images, les c...