Studio MacoMaco, studio graphique

Déploiement Stateless de sites WordPress sur un cluster Kubernetes

Aujourd’hui, je vous présente comment je gère le déploiement des sites WordPress que nous développons au sein du Studio MacoMaco.

Cet article se base sur un schéma complet qui présente l’architecture générale qui supporte l’hébergement des sites WordPress. Le schéma présente l’architecture pour un site appelé WordPress Website 1.

Le repository GitLab.com

Commençons par la partie située en bas à gauche du schéma. Pour chaque site internet, nous créons un repository au sein du groupe GitLab MacoMaco. Ceci permet de partager des variables d’environnement (dîtes de groupe) entre les différents repositories. Par exemple les informations de connexion au cluster Kubernetes.

Pour chaque tag sur le master, une pipeline est automatiquement lancée via le service GitLab CI. Nous hébergeons les runners sur notre cluster Kubernetes afin de ne pas dépendre du quota gratuit proposé par GitLab.com.

La pipeline de déploiement continu (GitLab CI)

Cette pipeline se décompose en plusieurs étapes :

Étape 1 : Construction et publication de l’image Docker

Nous avons créé notre propre image Docker générique pour un site WordPress hébergé dans notre cluster. Nous nous sommes basés sur l’image Docker officielle de WordPress. Cette image personnalisée nous permet de préinstaller des plugins pour tous les sites que nous hébergeons. Par exemple, la configuration SMTP est effectué via un plugin qui se trouve dans cette image générale.

Nous ajoutons donc le code source du / des thèmes et plugins spécifiques au site à cette image générique. Puis nous la publions sur le registry Docker privé du repository.

Étape 2 : Déploiement de l’image Docker via Helm

Nous avons créé un chart Helm personnalisé qui contient toutes les ressources Kubernetes nécessaires pour héberger un site WordPress sur le cluster (service, déploiement, certificat …). Nous utilisons ce chart comme base pour tous les déploiements des sites.

Nous nous connectons au cluster, puis nous déployons le site en configurant le chart pour utiliser l’image Docker que nous venons de publier. Le chart consomme des configmaps / secrets créés préalablement sur le cluster et qui ne change pas de déploiement en déploiement.

À l’aide de la fonctionnalité ReadinessProbe de Kubernetes, nous assurons un déploiement zéro downtime.

Étape 3 : Notification automatique du client via un email

Nous informons le client par email qu’une nouvelle mise à jour de son site a été publiée. Nous utilisons un dynamic template SendGrid pour la mise en forme de l’email.

Le cluster Kubernetes (GKE)

Les outils permanents installés

La base de données MySQL

Nous utilisons le chart Helm MySQL maintenu par le groupe Bitnami. Chaque site WordPress déployé sur le cluster possède son propre schéma de base de données. De plus, un utilisateur MySQL est créé pour chaque instance WordPress. Ceci permet de réduire la surface d’attaque en cas de compromission d’un utilisateur (isolation logique).

La base de données REDIS

Afin d’accélérer le chargement des pages, nous avons mis en place une solution de caching des objets WordPress (principalement des requêtes de la base de données MySQL) via REDIS grâce au plugin Redis Object Cache. Comme précédemment, nous utilisons le chart Helm Redis de Bitnami pour déployer un serveur redis sur notre cluster.

Les sauvegardes automatiques des schémas MySQL

En cas de problème sur notre base de données, nous avons développé une CronJob Kubernetes utilisant MySQLDump pour sauvegarder tous les schémas de notre serveur MySQL sur un bucket Google Cloud Storage. De plus, nous sauvegardons tous les utilisateurs. Ces sauvegardes s’effectuent toutes les deux heures. Ceci nous permet de très rapidement remettre en place les données d’un site WordPress qui aurait un problème.

Le monitoring

Nous avons créé un CronJob Kubernetes pour monitorer les sites hebergés sur le cluster. Ce CronJob est un script NodeJS qui effectue une requête HTTP sur les URL configurées via une ConfigMap. Il vérifie que le code de réponse est 200 pour chacune des requêtes. Sinon, un mail est automatiquement envoyé via SendGrid pour informer les administrateurs du cluster.

La gestion des certificats HTTPS

Nous utilisons l’outil CertManager pour la gestion des certificats HTTPS. Il est configuré pour automatiquement provisionner des certificats Wildcard via le service gratuit Let’s Encrypt. Grâce à une clé d’API CloudFlare, il est capable d’automatiquement résoudre les challenge DNS pour, et ainsi de mettre à jour les certificats périmés.

La gestion des médias (le dossier wp-media)

Pour rendre les instances WordPress Stateless, il nous fallait un moyen de décorréler les fichiers médias téléversés du sytème de fichier de l’instance (= du pod Kubernetes). Pour ce faire, nous utilisons le plugin WP-Stateless. Ce plugin nous assure une synchronisation de tous les médias téléversés sur un bucket Google Cloud Storage. Cela signifie que si le pod redémarre, aucun fichier média n’est perdu.

Nous avons préféré cette approche à un PVC pour des raisons de coût.

Le système de cache

Nous utilisons le système de cache proposé par CloudFlare. Tous les fichiers statiques (JS, CSS, images …) du thème personnalisé (ou plugin) seront donc mis en cache pour réduire le temps de chargement du site.

De plus, un système de cache est mis en place au niveau des médias téléversés. Le nom de domaine par défaut de Google Cloud Storage est remplacé par un nom de domaine personnalisé via une entrée DNS CNAME. Ceci nous permet de passer par le sytème de cache de CloudFlare (qui agit comme un proxy, en ajoutant le HTTPS) plutôt que de directement demander les fichiers sur le bucket GCS.

';