Ajouter un commentaire

Par :
Eric Manuguerra

lun, 04/12/2017 - 16:05

Bénéfices de l’approche DevOps

L’accroissement du nombre de développeurs dans une entreprise s’accompagne souvent d’une diminution de la productivité, due aux difficultés d’intégration, de communication et de validation des composants développés.

DevOps facilite la montée en échelle des organisations.

Combiné à un style d’architecture d’entreprise adaptée, qui promeut l’autonomie des équipes et l’indépendance des applications (cf. style d’architectures micro-services), DevOps permet de continuer à développer, à intégrer, à tester et à déployer en flux continu lorsque la taille de l’entreprise augmente.

Pour cela, les processus de développement sont transformés en chaînes de production logicielle automatisées. Les activités manuelles répétitives des analystes, développeurs, testeurs et opérateurs sont converties, autant que possible, en activités automatiques.

Automatisation du processus de développement

L’automatisation de la chaîne de production logicielle s’accompagne de la mise en œuvre d’une boucle de feedback rapide.

A tous les niveaux du processus de production logicielle, les intervenants doivent contrôler que les modifications apportées n’induisent pas d’anomalies.

A chaque fois qu’une modification est introduite dans le système de gestion de configuration, des tests automatiques s’exécutent rapidement dans un environnement identique à celui utilisé en production et valident le bon fonctionnement du système.


Note : Dans le cas d’architectures micro-services, il n’est pas toujours possible de reproduire un environnement de test complet, compte-tenu du nombre élevé de composants à déployer. Le système étant distribué la problématique des tests automatiques qui permet d’assurer la non-régression prend un nouveau tour.

Les tests E2E (end to end) deviennent encore plus difficiles à réaliser qu’avant et la bonne communication d’un micro-service avec le reste du système (les tests d’interface) prend une importance accrue, cf. approche « Consumer Driven Contract »

La chaîne de production logicielle se transforme en une "Pipeline" et fournit une boucle de retour rapide aux équipes à chaque fois qu'une modification est introduite dans le système de gestion des codes source.


Un exemple de pipeline

Pratiques liées à la transformation DevOps

La transformation DevOps de l’entreprise nécessite d’adresser de multiples domaines d’activité :

  1. La gestion de la configuration
  2. La gestion des codes sources
  3. La gestion des données de test et de production
  4. Les tests
  5. Les déploiements d’application
  6. La gestion des environnements

Dans chacun de ces domaines, l’organisation peut se révéler plus ou moins mature, avec des processus de travail plus ou moins efficaces, maîtrisés et automatisés.

Docker facilite la construction de la pipeline en permettant d’automatiser la gestion des environnements.

Dans ce domaine, les critères de maturité de l’organisation sont :

-        Les environnements (machines virtuelles) sont provisionnés de façon automatique

-        L’environnement dans lequel le système est déployé est reconstruit de façon rapide et répétable

-        L’état de l’environnement dans lequel le système est déployé est maîtrisé et géré comme du code source (historisation et traçabilité des modifications)

Gérer les environnements d’exécution avec Docker

Docker est un logiciel libre et une plateforme de gestion de conteneurs dont la première version est sortie en mars 2013. Le site web de Docker indique :

“Enterprises use Docker to build agile software delivery pipelines to ship new features faster, more securely and with confidence for both Linux and Windows Server apps.”

Les solutions de containerisation d’applications telles que Docker jouent en effet un rôle essentiel dans la construction de la ligne de production continue.

Docker s’appuie sur les cgroups et les namespaces du noyau Linux pour isoler le système d’exploitation tel que vu par l’application, la plaçant ainsi dans un « conteneur » à l’instar des caissons métalliques utilisés en logistique pour faciliter le transport de marchandises.

Docker permet en particulier :

  • D’économiser l’utilisation des ressources machines : le conteneur n’inclut pas de système d’exploitation à la différence des machines virtuelles
  • De fiabiliser la gestion des environnements, gérés comme du code source
  • De maîtriser les modifications apportées aux environnements à l'aide des outils de gestion de configuration (tel que Git, Mercurial ...)
  • De réduire les délais de déploiement : rapidité de construction des images et de démarrage des conteneurs, « build once, deploy anywhere »
  • De réutiliser les environnements publiés par des tiers : Docker HubDocker Store
  • De disposer de registres de versions d'applications prêtes à être livrées en production à partir du Docker registry
  • D’amener l’entreprise à disposer de tout le nécessaire pour reconstruire de zéro l’intégralité d’une application, bénéficiant ainsi d'un plan de reprise sur « désastre »
  • D’accroître la portabilité des applications à l’intérieur du SI et vers le cloud

Il est possible de construire automatiquement les environnements utilisés dans la chaîne de production logicielle ou « Pipeline », rendant le "Continuous Delivery" atteignable plus facilement.


Docker : build once, deploy anywhere

Les "essaims" de conteneurs : Docker Swarm Mode

A partir de la version 1.12, le moteur Docker inclut le "Docker Swarm Mode" qui adresse la gestion de conteneurs en cluster. Docker swarm mode permet de gérer les applications à un plus haut niveau d’abstraction, comme des ensembles de services dont le déploiement, la répartition, la résilience et la scalabilité sont gérés par l’orchestration Docker Swarm.

La suite de cet article illustre la mise en œuvre d'un cluster à travers :

  • Le provisionning d'hôtes Docker avec Docker machine
  • La création du cluster de conteneurs Docker avec "Docker Swarm Mode"
  • Le déploiement de services sur le cluster


Docker Swarm Mode : mise en cluster de Docker engines

Fonctionnalités de Docker Swarm Mode

Docker Swarm Mode propose des fonctions de gestion de cluster et d’orchestration de conteneurs :

  • La localisation des services sur le parc des Docker Host grâce à un annuaire de services intégré dans lequel les conteneurs sont automatiquement enregistrés
  • Le chiffrage des communications entre conteneurs par défaut : « automatic TLS keying and signing »
  • Un modèle déclaratif de gestion des services permettant de déléguer au Swarm la gestion des conteneurs (répartition des conteneurs sur la grille des machines, détection des pannes et redémarrage (healthcheck), extensibilité (scaling de conteneurs) …)
  • La gestion réseau multi-host avec la possibilité de créer un réseau « overlay » propre aux services gérés par l’orchestrateur
  • Une répartition de charge automatique entre conteneurs fournissant le même service (load balancing)
  • Des mises à jour roulantes pour assurer des déploiements sans interruption de service (zero-downtime rolling update)
  • La haute disponibilité du service d’orchestration, grâce à l’utilisation du consensus Raft pour l’élection des nœuds maîtres

La deuxième partie de cet article illustre Docker et Docker Swarm mode à travers l’exemple d’une plateforme d'intégration et de déploiement déployée sur un cluster :

  • Jenkins LTS : orchestrateur des activités automatiques
  • Artifactory 5 : gestionnaire d’artefacts
  • SonarQube : analyseur de code source
  • Docker registry : registre d’images Docker

Mise en œuvre d’un cluster Docker Swarm Mode

Provisionnement des machines avec docker-machine

Le provisionnement des machines virtuelles qui accueillent le cluster Docker peut s'effectuer avec docker-machine - voir ici la documentation officielle.

Le déploiement d'un cluster peut s'effectuer sur une machine de développement à des fins d'évaluation (option 1 présentée ci-dessous).

-        Option 1 : sur un poste Windows, Mac ou Linux en s'appuyant sur le driver Virtual Box (cf. script ci-dessous)

#!/usr/bin/env bash

if [ "$1" != "" ]; then
    node_name="$1"
else
    node_name='swarm-node'
fi 

# Créer 3 hôtes Docker en utilisant le driver Virtual Box

for i in 1 2 3; do
  docker-machine create -d virtualbox $node_name-$i
done 

-        Option 2 : sur des machines fournies par un cloud provider - voir ici la liste des Cloud supportés

-        Option 3 : sur des machines virtuelles qui supportent Docker (version du noyau Linux > 3.10), comme présenté ci-dessous.

Les machines virtuelles Linux utilisées ici sont des distributions Debian Jessie (Debian v. 8). Le provisionnement des machines s'effectue avec docker-machine, en utilisant le driver générique (SSH). Au préalable, il est nécessaire d'installer un couple de clés RSA sur la machine cible pour pouvoir s'authentifier sans devoir saisir de mot de passe.

Il est également nécessaire de créer un groupe docker et un utilisateur affecté à ce groupe.

useradd -g docker docker
mkdir -p /home/docker/.ssh/
chown -R docker /home/docker/
su docker

Suivre ici les instructions pour Debian 8.

Il faut également ajouter l'utilisateur Docker aux « sudoers sans mot de passe » de la machine cible (cf. documentation Docker machine).

Pour cela, insérer la ligne :

docker ALL=(ALL) NOPASSWD: ALL

dans le fichier des sudoers (/etc/sudoers).


Note sur la sécurité : La mise en œuvre décrite ici est menée à des fins d’évaluation de l’orchestrateur Docker Swarm Mode.

La mise production d’un cluster Docker Swarm Mode nécessite d’étudier les risques occasionnés par l’innovation (augmentation de la surface d’attaque, risque d’afflux d’images basées sur du code source vulnérable, risque de monopolisation de ressources système …) et de prendre les précautions nécessaires (scans d’images, activation de Docker Content Trust, benchmarks de sécurité Docker tels que Docker bench security, durcissement des hôtes Docker …).

Créer les machines Docker

docker-machine create --driver generic --generic-ip-address=10.41.22.109 --generic-ssh-key ~/.ssh/id_rsa --generic-ssh-user=docker sqli-node-1

Répéter l'opération avec les autres machines.

Vérifier le succès du provisionning :

docker-machine ls


Machines provisionnées

La mise à jour de la version de docker sur la machine cible est extrêmement simple :

docker-machine upgrade sqli-node-1

Cluster Docker Swarm Mode

Une fois le provisionnement des machines achevé, créer un cluster Docker Swarm Mode :

# Injecter les variables d'environnement Docker pour configurer le client et pointer sur un manager
eval $(docker-machine env sqli-node-1)

# Initialiser le cluster Docker
docker swarm init --advertise-addr $(docker-machine ip sqli-node-1)

# Créer un token pour ajout de swarm node de type "manager"
TOKEN=$(docker swarm join-token -q manager)

# Les noeuds 2 et 3 rejoignent le cluster
for i in 2 3; do
  eval $(docker-machine env sqli-node-$i)
  docker swarm join \
  --token $TOKEN \
  --advertise-addr $(docker-machine ip sqli-node-$i) \
  $(docker-machine ip sqli-node-1):2377
done 

Note : Afin d’assurer la haute disponibilité, il est nécessaire d’utiliser au minimum 3 nœuds de type manager dans un cluster (5 sont recommandés).

Déployer les services sur le cluster

Deux approches sont décrites ci-dessous :

  1. La création des services en ligne de commande, par des appels « docker service create »
  2. Le déploiement d'une stack complète selon une approche "déclarative" basée sur le format docker-compose, version 3

Option 1 : créer les services individuellement

Visualizer

Le visualizer Docker Swarm est une application Node JS packagée dans un conteneur, qui permet de visualiser la répartition des tâches/conteneurs (les instances des services) sur le cluster.

docker service create \
  --name=viz \
  --publish=8083:8080/tcp \
  --constraint=node.role==manager \
  --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
  dockersamples/visualizer

Pointer un navigateur à l'adresse http://$(docker-machine ip sqli-node-1):8083.

Portainer

Portainer est une interface simple de gestion des hôtes Docker et des clusters Swarm.

Déployer le service de gestion du cluster Portainer.

docker service create \
  --name portainer \
  --publish 9000:9000 \
  --constraint 'node.role == manager' \
  --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
  portainer/portainer \
-H unix:///var/run/docker.sock

Pointer un navigateur à l'adresse http://$(docker-machine ip sqli-node-1):9000 et saisir un mot de passe administrateur.


Page d'accueil de Portainer

Registry

Un registre Docker privé permet de stocker des images et de les rendre accessibles aux noeuds du cluster.

docker service create --name registry \
  -p 5000:5000 \
  --reserve-memory 100m \
  --mount "type=bind,source=/home/docker/registry,target=/var/lib/registry" \
  registry:2.5.0

docker service create --name registry-frontend \
  -e ENV_DOCKER_REGISTRY_HOST=10.41.22.109 \
  -e ENV_DOCKER_REGISTRY_PORT=5000 \
 -p 8084:80 \
  konradkleine/docker-registry-frontend:v2

La création d'un registre d'entreprise accessible via un nom de domaine (afin d'héberger par exemple les images Docker produites par les différentes équipes projet) doit être sécurisée (communications TLS).

L'installation complète et sécurisée d'un registre d'entreprise est décrite ici.

Déploiement d'un service Jenkins

docker service create --name jenkins \
 -p 8085:8080 \
 -p 50000:50000 \
 --mount "type=bind,source=/home/jenkins,target=/var/jenkins_home" \
 --mount "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" \
 --constraint "node.hostname == sqli-node-1" \
 jenkinsci/jenkins:lts

Déploiement du service Artifactory

docker service create  --name artifactory-5 \
 --mount "type=volume,source=artifactory5_data,target=/var/opt/jfrog/artifactory" \
 -p 8086:8081 docker.bintray.io/jfrog/artifactory-oss:5.0.0

Option 2 : déployer la stack complète avec docker stack

Docker stack permet de déployer un ensemble de services dont la configuration est décrite dans un fichier docker-compose (en version 3).

Les services sont ainsi déployés à l'aide du fichier docker-compose-stack.yml de façon « déclarative » plutôt que scriptée.

version: '3'

services:
  jenkins:
    image: jenkinsci/jenkins:lts
    ports:
      - 8085:8080
      - 50000:50000
    deploy:
      placement:
        constraints:
          - node.hostname == sqli-node-1
    volumes:
      # Named volume
      - /home/jenkins:/var/jenkins_home
      # Bind volume to run Docker in Docker
      - /var/run/docker.sock:/var/run/docker.sock:rw
      - /usr/bin/docker:/usr/bin/docker:ro 

  sonarqube:
    image: sonarqube:6.3.1
    ports:
      - 9001:9000
    environment:
      - SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar
    volumes:
      - sonarqube_conf:/opt/sonarqube/conf
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins 

  db:
    image: postgres:9
    environment:
      - POSTGRES_USER=sonar
      - POSTGRES_PASSWORD=sonar
    volumes:
      - postgresql:/var/lib/postgresql
      - postgresql_data:/var/lib/postgresql/data 

  artifactory-5:
    image: docker.bintray.io/jfrog/artifactory-oss:5.0.0
    ports:
      - 8086:8081
    volumes:
      - artifactory5_data:/var/opt/jfrog/artifactory 

networks:
  cd:
    driver: overlay

volumes:
  sonarqube_conf:
  sonarqube_data:
  sonarqube_extensions:
  sonarqube_bundled-plugins:
  postgresql:
  postgresql_data:
  artifactory5_data:

(fichier docker-compose-stack.yml)

Le déploiement s’effectue à l’aide de la commande « docker stack deploy » :

docker stack deploy -c docker-compose-stack.yml cip

Pour visualiser le résultat, pointer un navigateur à l'adresse du visualiseur.

Les services sont effectivement déployés et visibles via l'interface de gestion.

En conclusion

Docker Swarm Mode permet de gérer les hôtes Docker en tant que cluster et modifie la relation des développeurs et des opérateurs système à l’égard des serveurs, en la rendant plus abstraite et détachée, selon la métaphore « les serveurs : des animaux de compagnie ou des animaux de bétail (cf. pets VS cattle) ? ».

L’automatisation de la chaîne de production logicielle nécessite une excellente connaissance du processus de développement et permet de le rendre répétable et prédictible. Selon Edward Deming : « If you can’t describe what you are doing as a process, you don’t know what you are doing », et c’est bien d’une parfaite description du processus de développement dont il s’agit ici.

Dans cette démarche d’industrialisation, les solutions de containerisation telles que Docker jouent un rôle essentiel en permettant de fiabiliser les environnements dans lesquels les applications s’exécutent et d’automatiser les activités de déploiement des applications.

A propos de l'auteur

Eric Manuguerra
Directeur technique chez SQLI

Filtered HTML

Plain text

CAPTCHA
Cette question permet de vérifier que vous n'êtes pas un robot spammeur :-)
 FFFF  U   U   CCC  EEEE      J 
F U U C E J
FFF U U C EEE J
F U U C E J J
F UUU CCC EEEE JJJ