Comment créer une infrastructure web en partant de rien ? – Partie 1
Dernièrement j’ai eu l’occasion de mettre en place une infrastructure IT complète et j’ai remarqué qu’il existait peu de ressources sur une telle mise en place. Le but de cette série de tutoriels est de créer un ensemble cohérent et suffisamment exhaustif sur le sujet pour qu’il puisse servir de référence future, tant pour moi que pour d’autres qui voudraient se lancer dans l’administration système ou dans la construction de leur propre infrastructure. J’essaierai autant que possible de suivre les bonnes pratiques et recommandations dans le domaine. Ce que j’entends par «infrastructure web» c’est l’architecture matérielle et logicielle qui vous permette de gérer des services web (applications, bases de données etc.).
Vouloir tout gérer soi-même peut venir de plusieurs raisons:
- finance: coûts exorbitants des services externalisés ou cloud
- sécurité: un besoin de contrôle total sur les processus et les données
- indépendance: avoir les compétences en interne et ne pas dépendre d’un tiers, surtout en cas de problème
- …
Avant-propos et pré-requis
Ce tutoriel reflète de près ma propre façon de travailler donc il y a donc de nombreux choix que je fais par préférence personnelle ou par expérience passée. Rien ne vous oblige à suivre de près ce tutoriel mais ce sera évidemment plus simple si vous manquez d’expérience.
Il suppose que vous ayez quelques bases en *nix (unix, linux) et en ligne de commande (shell). Si cela ne vous parle pas, vous risquez d’être rapidement perdu même si je ferai mon possible pour ne pas sauter d’étape et pour expliquer les points importants. Cependant, n’hésitez pas à me demander ce que vous souhaitez voir apparaitre via les commentaires, je ferai mon possible pour compléter dans de futurs articles ou annexes.
Pour son faible coût et sa facilité d’utilisation pour ce genre de tutoriel, je vais utiliser Scaleway mais vous pouvez utiliser n’importe quel type d’hébergement (serveurs physiques, machines virtuelles, …) tant que vous avez un accès complet au système. Je vous recommande néanmoins un hébergement à base de machines virtuelles ou similaire car leur provisionnement est rapide (au maximum quelques minutes, souvent quelques secondes suffisent). Des machines physiques seront généralement bien plus onéreuses et plus lentes à obtenir.
Dans ce tutoriel nous allons utiliser la distribution linux Debian car elle est a de nombreux atouts: multiples paquets disponibles, nombreux tutos pour débutants, … Pour une utilisation professionnelle, il vous faudra peut être regarder du côté de CentOS pour le support sur le très long terme (10 ans) et le module SELinux (pour une sécurité accrue), mais je m’égare.
Toute la configuration que je vais mettre en place dans ce tutoriel est disponible sur mon github public pour avoir une référence rapide de la configuration. Je vous conseille par contre de tout refaire vous même au lieu de simplement cloner mes dépôts git.
Contenu du tutoriel
Voici les points que j’espère couvrir avec vous dans ce tutoriel:
- Comment gérer de 1 à 1000 machines sans devenir fou
- Les services et éléments essentiels: NTP, SSH, sudo, iptables, etc.
- Bases de données
- Infrastructure de développement et déploiement continu avec GitLab
- Ajout d’une application de A à Z sur notre infrastructure
Comment gérer un parc de 1 à 1000 machines sans devenir fou
Avant de parler web, il va falloir mettre en place de nombreux services essentiels pour pouvoir tout simplement faire tourner vos applications finales. Ces services sont au coeur de votre système, ce sont les fondations de votre future infrastructure. Pour cela, nous allons devoir gérer de nombreuses configurations, machines, services, etc., et nous n’allons pas le faire à la main. Nous allons plutôt utiliser un «système de gestion de systèmes» (systems management system en anglais).
Vous avez peut-être entendu parler de Chef, Puppet ou encore Ansible. Dans ce tutoriel, nous allons utiliser Salt mais la logique fondamentale devrait rester similaire quel que soit l’outil que vous utilisez.
Nous allons utiliser Salt en mode serveur principal + clients multiples. Tous les clients utiliseront un programme nommé le salt minion
pour se connecter au serveur principal, le salt master
. Pour commencer, nous allons donc avoir besoin d’une machine pour héberger le salt master
.
Notre première machine: saltmaster1
Installation
Nous allons créer une simple machine avec un linux Debian jessie (8.*), la dernière release stable à l’écriture de ce tutoriel. Je vous laisse voir avec votre hébergeur sur comment créer une nouvelle machine. Pour ceux qui utiliseraient aussi Scaleway, ils ont un tutoriel sur comment créer une instance et s’y connecter (en anglais).
Pour installer Salt, c’est simple, il suffit de suivre les instructions du site officiel de Salt (en anglais). Pour cela, nous allons commencer par ajouter les clés GPG des package Salt. Le plus simple est de lancer tout cela en tant qu’utilisateur root
mais vous pouvez le faire aussi via sudo
.
root@saltmaster1# wget -O - https://repo.saltstack.com/apt/debian/8/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add -
Puis nous allons ajouter le dépot debian de Salt à aptitude
et ses cousins apt-*
le gestionnaire de paquets de debian:
root@saltmaster1# echo "deb http://repo.saltstack.com/apt/debian/8/amd64/latest jessie main" > /etc/apt/sources.list.d/saltstack.list
Une fois cela fait, il vous suffit de lancer une mise à jour d’aptitude
et d’installer les paquets nécessaires:
root@saltmaster1# apt-get update && apt-get upgrade [...] root@saltmaster1# apt-get install -y salt-master salt-minion
Une fois le salt master
installé, il faut lui donner une configuration à appliquer aux machines. Nous allons la stocker dans deux dépots git
:
Pourquoi 2 dépots ? Car chacun va stocker des informations bien différentes:
- les fichiers d’états (appelés Salt States en anglais) et les templates des fichiers de configuration, situés par défaut dans
/srv/salt
- les variables de configuration, dont les informations sensibles (mot de passes, clés de chiffrement, …), situés par défaut dans
/srv/pillar
.
Création des dépots git pour la configuration
Il nous suffit pour commencer de cloner les deux dépots au bon endroit sur le saltmaster1
:
root@saltmaster1# rm -rf /srv/salt && git clone git@git.example.com:pseudo/infra-salt-master.git /srv/salt root@saltmaster1# rm -rf /srv/pillar && git clone git@git.example.com:pseudo/infra-salt-pillar.git /srv/pillar
Pour finir la configuration de saltmaster1
, nous allons apporter quelques personnalisations au fichier de configuration de salt master
situé dans /etc/salt/master
(et faites une copie de sauvegarde, nous en aurons besoin sous peu):
root@saltmaster1# cp /etc/salt/master /etc/salt/master.default root@saltmaster1# vim /etc/salt/master [...] conf_file: /etc/salt/master state_output: mixed hash_type: sha512
Comme vous pouvez le voir dans la configuration, nous avons laissé le seul « environnement » par défaut utilisé par Salt dans file_root
et pillar_roots
: base
. Une fois que vous serez plus à l’aise, vous pourrez configurer des environnements multiples: base
, dev
, prod
, qa
, …
Ajouter d’une nouvelle configuration
Pour pouvoir gérer la configuration d’un service, nous allons toujours suivre toujours la même logique:
- installer manuellement le programme (le plus souvent via
apt-get install <...>
) - récupérer les fichiers de configuration par défaut, situés généralement dans
/etc/...
- ajouter les fichiers de configuration par défaut dans notre dépot git de
salt master
- faire une copie de ces fichiers et les personnaliser en fonction de nos besoins
- supprimer le programme installé à l’étape 1 (avec un
apt-get purge <...>
pour ne laisser aucune trace du programme d’origine) - appliquer la configuration automatique via
salt master
et vérifier que le programme a été installé et configuré correctement
Pour saltmaster1
, nous avons déjà plus ou moins effectué les étapes 1 à 4. Il ne nous reste plus qu’à copier les fichiers de configuration de salt master
et à écrire les fichiers salt states. Salt utilise un fichier d’entrée qui doit s’appeler top.sls
qui va lui ensuite inclure d’autres Salt States à appliquer sur différentes machines. Créons pour le moment le fichier top.sls
situé à la racine du dépot pour salt master
:
base: '*': - salt 'saltmaster1': - salt.master
Que veut dire ce fichier ligne par ligne ?
- nous utilisons un seul environnement
base
, mais nous pourrions en rajouter d’autreprod
,dev
etc. cf voir ci-dessus dans le fichier/etc/salt/master
- Salt utilise le hostname de la machine (appelé l’ID de la machine chez Salt) pour savoir quelle configuration appliquer sur quelle machine. Pour nous éviter de devoir écrire une liste de toutes les machines dans le fichier, Salt nous permet de faire du globbing via
'*'
pour sélectionner toutes les machines possibles. - Salt va appliquer le fichier d’état contenu dans le fichier spécifié. Dans cet exemple,
salt
est un dossier qui va contenir la configuration de Salt. Dans cet exemple, il se situe dans/srv/salt/salt
. Lorsque vous ne spécifiez pas le nom du fichier mais seulement le dossier, Salt utilisera par défaut le fichierinit.sls
par défaut, ce qui donne ici/etc/salt/salt/init.sls
. - Ici, nous voulons appliquer des règles seulement au hostname
saltmaster1
- Le fichier d’état à appliquer est
salt.master
, qui est traduit par Salt en chemin suivantsalt/master.sls
, ce qui donne/etc/salt/salt/master.sls
Créons donc le dossier salt
dans notre dépot git pour salt master
(nous n’en avons pas besoin dans salt pillar
pour le moment) et deux fichiers: init.sls
et master.sls
. Avant d’écrire les fichiers d’états, nous allons copier les fichier de configuration de Salt dans notre dépot git aux chemins suivants. Dans tous les tutoriels qui vont suivre, j’utiliserai la notation <git-salt-master>
et <git-salt-pillar>
pour représenter le dossier racine du dépôt git de salt master
et de salt pillar
respectivement.
/etc/salt/master
vers<git-salt-master>/salt/templates/master
, que nous avons déjà personnalisé/etc/salt/master.default
vers<git-salt-master>/salt/defaults/master.default
, qui nous sert à garder une copie du fichier d’origine, au cas où nous aurions besoins de repartir d’une configuration par défaut/etc/salt/minion
vers<git-salt-master>/salt/templates/minion
, que nous allons aussi personnaliser/etc/salt/minion
vers<git-salt-master>/salt/defaults/minion.default
, qui, comme ci-dessus, nous sert de copie de sauvegarde du fichier de configuration d’origine.
achedeuzot@localhost# tree . . ├── salt │ ├── defaults │ │ └── master.default | | └── minion.default │ └── templates | │ └── master | │ └── minion │ ├── init.sls │ ├── master.sls └── top.sls
Il ne nous reste plus qu’à écrire les fichiers d’état pour appliquer les règles à notre machine saltmaster1
.
Le fichier init.sls
sera appliqué à toutes les machines, master comme clientes, il convient d’y mettre le nécessaire pour pouvoir installer salt minion
:
# Ici nous ajoutons le dépot de paquets apt de saltstack pour pouvoir l'installer facilement salt_repository_add: pkgrepo.managed: - humanname: saltstack-repo - name: deb http://repo.saltstack.com/apt/debian/8/amd64/latest jessie main - file: /etc/apt/sources.list.d/saltstack.list - key_url: https://repo.saltstack.com/apt/debian/8/amd64/latest/SALTSTACK-GPG-KEY.pub - refresh_db: True # Vérifier que le package salt-minion est installé salt_minion_installed: pkg.installed: - name: salt-minion # Copier la configuration locale situé dans<git-salt-master>/salt/templates/minion vers la machine # salt:// représente le dossier racine de la configuration de salt master, c'est à dire /srv/salt salt_minion_conf_set: file.managed: - name: /etc/salt/minion - source: salt://salt/templates/minion - user: root - group: root - mode: 600 - template: jinja - require: - pkg: salt-minion # Vérifier que le service tourne et le relancer en cas de changement (directive watch) salt_minion_service_running: service.running: - name: salt-minion - enable: True - watch: - pkg: salt-minion - file: /etc/salt/minion # Lancer un rafraichissement de la configuration toutes les 15 minutes. salt_minion_highstate_cron_set: cron.present: - identifier: salt_minion_highstate_cron_set - name: salt-call state.highstate > /dev/null - user: root - minute: '*/15'
Puis, ajoutons la configuration spécifique du master dans master.sls
:
# Le dépot de paquets a déjà été installé par le fichier init.sls, il ne nous reste plus qu'à installer salt-master salt_master_installed: pkg.installed: - name: salt-master # Ajouter la configuration personnalisée du salt-master issue du template salt/templates/master salt_master_conf_set: file.managed: - name: /etc/salt/master - source: salt://salt/templates/master - user: root - group: root - mode: 600 - require: - pkg: salt-master # Vérifier que le service tourne et qu'il est relancé en cas de changement du package ou du fichier de configuration (directive watch) salt_master_service_running: service.running: - name: salt-master - enable: True - watch: - pkg: salt-master - file: /etc/salt/master
Il ne nous reste plus qu’à ajouter tout celà dans notre dépot git, le récupérer sur le saltmaster1
et l’appliquer:
achedeuzot@localhost:~/<git-salt-master># git add top.sls salt/ achedeuzot@localhost:~/<git-salt-master># git commit -m "Tutorial first step: bootstrap Salt" [..] achedeuzot@localhost:~/<git-salt-master># git push origin master [...] # Sur saltmaster1: root@saltmaster1# cd /src/salt root@saltmaster1# git pull origin master [...]
L’heure du premier test
Pour pouvoir finir ce premier volet et vérifier que tout fonctionne, nous allons devoir vérifier que saltmaster1
peut gérer sa propre configuration. Pour cela, il ne nous manque plus grand chose.
D’abord, personnaliser la configuration du salt minion
en changeant la ligne suivante, qui permettra au salt minion
de contacter le salt master
:
master: <ip publique de saltmaster1>
Ensuite, ajouter le saltmaster1
à la liste des minions gérés par salt master
grâce à salt-key
:
root@saltmaster1# salt-call state.highstate [ERROR ] The Salt Master has cached the public key for this node, this salt minion will wait for 10 seconds before attempting to re-authenticate Minion failed to authenticate with the master, has the minion key been accepted? root@saltmaster1# salt-key -a saltmaster1 salt-key -a saltmaster1 The following keys are going to be accepted: Unaccepted Keys: saltmaster1 Proceed? [n/Y] y Key for minion saltmaster1 accepted. root@saltmaster1# salt '*' state.highstate [...]
Terminé ! Revoyons rapidement ce que nous venons de faire:
- Nous avons utilisé
salt-call
, une fonctionnalité dusalt-minion
pour appliquer un état (state). Cela force le minion à contacter lesalt master
, vu que lesalt minion
n’est pas encore authentifié auprès dusalt master
, il est rejeté mais sa clé est mise en mémoire chez lesalt master
. - Nous utilisons la commande
salt-key
dusalt master
pour ajouter (-a
) le minion dont l’ID estsaltmaster1
. - Une fois que le minion est ajouté, nous utilisons la commande
salt
dusalt master
pour appliquer l’étatstate.highstate
à tous les IDs'*'
. Nous aurions pu relancer la commandesalt-call state.highstate
qui aurait eu le même résultat dans ce contexte.
L’état state.highstate
indique à salt master
d’appliquer tous les fichiers d’états aux salt minion
sélectionnés.
Cette première étape de « bootstrapping » étant faite pour Salt, dans le prochain volet nous verrons comment installer et configurer tous les services de base de votre machine.
Bien entendu, si vous avez des questions ou des remarques, posez-les dans les commentaires ci-dessous et n’oubliez pas de me soutenir si vous aimez ce que je fais !
Commentaires
Laisser un commentaire