Alors que les architectures de microservices continuent de dominer le développement logiciel moderne, la complexité de la gestion des cycles de vie de chaque service augmente de manière exponentielle. Alors que de nombreuses équipes se précipitent vers Kubernetes pour l'orchestration, une part significative de l'industrie s'appuie encore sur des cibles de déploiement plus simples, telles que des machines virtuelles, des offres PaaS (comme AWS Elastic Beanstalk ou Heroku) ou des serveurs nus. Pour ces environnements, le pipeline CI/CD doit non seulement automatiser les builds, mais aussi gérer la logique de déploiement, la configuration des environnements et les stratégies de rollback avec précision.
GitHub Actions offre une approche puissante et centrée sur le code pour l'intégration continue et la livraison continue (CI/CD). Dans cet article, nous explorerons comment construire un pipeline robuste pour les microservices non Kubernetes, en mettant l'accent sur la modularité, la sécurité et la fiabilité.
La philosophie des pipelines modulaires
L'une des erreurs les plus courantes commises par les développeurs consiste à coder en dur chaque étape du processus de déploiement dans un seul fichier YAML monolithique. Pour une architecture de microservices, cette approche devient rapidement ingérable. Au lieu de cela, nous devrions traiter nos workflows GitHub Actions comme des unités composables.
En tirant parti des workflows réutilisables et de la configuration spécifique à l'environnement, nous pouvons maintenir une source unique de vérité pour notre logique de build tout en permettant aux cibles de déploiement de varier. Cela est particulièrement crucial pour les environnements non Kubernetes où l'infrastructure en tant que code (IaC) peut être gérée différemment selon les services (par exemple, certains utilisant Terraform, d'autres utilisant de simples scripts shell).
Composants principaux du pipeline
Un pipeline robuste pour les services non Kubernetes se compose généralement de trois phases distinctes : Build, Test et Deploy. Examinons comment structurer un workflow GitHub Actions qui encapsule efficacement ces phases.
1. La phase de Build et de Test
La base de tout pipeline CI/CD est la vitesse et la fiabilité. Nous voulons échouer rapidement si les tests échouent. En utilisant GitHub Actions, nous pouvons paralléliser l'exécution des tests pour réduire les boucles de rétroaction.
Voici un exemple de workflow qui gère l'installation des dépendances, le linting et les tests unitaires :
name: Build and Test
on:
pull_request:
branches: [ main ]
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run unit tests
run: npm test -- --coverage
2. Conteneurisation pour la cohérence
Même si vous n'utilisez pas Kubernetes, la conteneurisation reste la norme pour garantir la cohérence entre les environnements de développement, de staging et de production. L'utilisation de Docker permet à votre microservice de s'exécuter de manière prévisible, quel que soit le système d'exploitation de l'hôte sous-jacent.
Nous pouvons intégrer la construction et le push Docker directement dans le pipeline. Cela garantit que l'artifact déployé est exactement le même que celui qui a passé tous les tests.
- name: Build and Push Docker Image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
3. Déploiement spécifique à l'environnement
Pour les services non Kubernetes, le déploiement implique souvent de se connecter en SSH à un serveur ou d'appeler l'API d'un fournisseur PaaS. La sécurité est primordiale ici. Nous ne devons jamais coder en dur les identifiants. Utilisez plutôt les Secrets GitHub combinés avec des règles de protection d'environnement.
Supposons que nous déployons sur un serveur Linux via SSH. Nous pouvons utiliser l'action `appleboy/ssh-action` pour exécuter des scripts de déploiement.
deploy-staging:
needs: build
runs-on: ubuntu-latest
environment: staging
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy to Staging Server
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.STAGING_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /opt/my-service
docker pull ghcr.io/${{ github.repository }}:${{ github.sha }}
docker-compose up -d --no-deps my-service
# Perform health check
curl -f http://localhost:8080/health || exit 1
Meilleures pratiques pour la résilience
- Idempotence : Assurez-vous que vos scripts de déploiement peuvent être exécutés plusieurs fois sans effets secondaires. Docker facilite cela, mais l'idempotence au niveau de l'application est toujours requise pour les migrations de base de données.
- Stratégie de rollback : Dans les environnements non Kubernetes, le rollback peut être manuel. Automatisez-le en taguant les images Docker avec des versions sémantiques et en conservant les versions précédentes disponibles. Si un contrôle de santé échoue, le pipeline doit déclencher automatiquement un workflow de rollback.
- Gestion des secrets : Rotationnez régulièrement vos clés SSH et vos jetons API. Utilisez les Environnements GitHub pour restreindre qui peut approuver les déploiements en production.
Conclusion
Construire des pipelines CI/CD pour les microservices non Kubernetes nécessite un changement d'état d'esprit. Au lieu de s'appuyer sur le moteur d'orchestration pour gérer les déploiements progressifs et les rollbacks, la responsabilité repose entièrement sur le pipeline lui-même. En tirant parti de la nature modulaire de GitHub Actions, de la conteneurisation et de la gestion sécurisée des secrets, vous pouvez créer un système de déploiement aussi robuste et évolutif que ses homologues Kubernetes. Adoptez l'automatisation, priorisez la sécurité et validez toujours vos déploiements avec des contrôles de santé automatisés.