Documentation Infrastructure¶
Cette section couvre la configuration de l'infrastructure, les processus de déploiement et les procédures opérationnelles pour tous les projets Optim.
Aperçu¶
Notre infrastructure est conçue pour l'évolutivité, la fiabilité et la sécurité dans plusieurs environnements.
Stratégie d'Environnement¶
Types d'Environnements¶
| Environnement | Objectif | Accès | Déploiement |
|---|---|---|---|
| Développement | Développement local et tests | Tous les développeurs | Manuel/automatique |
| Recette | Tests de pré-production | Consultants, développeurs | Manuel |
| Production | Système en direct | Distributeurs, clients | Approbation manuelle requise |
Configuration des Environnements¶
# environments.yml
development:
api_url: "http://localhost:3000"
database_url: "postgres://localhost:5432/optim_dev"
redis_url: "redis://localhost:6379"
log_level: "debug"
staging:
api_url: "https://staging-api.optim.com"
database_url: "${STAGING_DATABASE_URL}"
redis_url: "${STAGING_REDIS_URL}"
log_level: "info"
production:
api_url: "https://api.optim.com"
database_url: "${PRODUCTION_DATABASE_URL}"
redis_url: "${PRODUCTION_REDIS_URL}"
log_level: "warn"
Architecture de Déploiement¶
Architecture de Haut Niveau¶
graph TB
A[Équilibreur de Charge] --> B[Passerelle API]
B --> C[Service d'Authentification]
B --> D[Services Métier]
D --> E[Cluster de Base de Données]
D --> F[Couche de Cache]
D --> G[Stockage de Fichiers]
H[Pipeline CI/CD] --> I[Registre de Conteneurs]
I --> J[Cluster Kubernetes]
J --> D
Stack Technologique¶
Orchestration de Conteneurs
- Kubernetes (EKS/GKE)
- Conteneurs Docker
- Charts Helm pour le déploiement
Bases de Données
- PostgreSQL (base de données principale)
- Redis (cache et sessions)
- MongoDB (stockage de documents)
Infrastructure
- Fournisseurs cloud AWS/GCP
- Terraform pour l'infrastructure en tant que code
- CDN pour les ressources statiques
Surveillance et Journalisation
- Prometheus/Grafana pour les métriques
- Stack ELK pour la journalisation
- Sentry pour le suivi des erreurs
Processus de Déploiement¶
Pipeline CI/CD¶
# .github/workflows/deploy.yml
name: Déployer
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Exécuter les tests
run: |
npm ci
npm run test:coverage
npm run lint
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Construire l'image Docker
run: |
docker build -t optim/app:${{ github.sha }} .
docker push optim/app:${{ github.sha }}
deploy-staging:
needs: build
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
steps:
- name: Déployer en staging
run: |
helm upgrade --install optim-app ./helm/optim-app \
--set image.tag=${{ github.sha }} \
--namespace staging
deploy-production:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- name: Déployer en production
run: |
helm upgrade --install optim-app ./helm/optim-app \
--set image.tag=${{ github.sha }} \
--namespace production
Étapes de Déploiement¶
- Fusion de Code - Code fusionné vers la branche main/develop
- Tests Automatisés - Tests unitaires et d'intégration exécutés
- Processus de Build - Images Docker construites et étiquetées
- Scan de Sécurité - Images de conteneurs scannées pour les vulnérabilités
- Déploiement Staging - Déploiement automatique vers staging
- Approbation Production - Approbation manuelle pour le déploiement en production
- Déploiement Production - Déploiement avec stratégie blue-green
- Vérifications de Santé - Vérification automatique de la santé
- Rollback - Rollback automatique en cas d'échec
Stratégie de Rollback¶
# Rollback rapide vers la version précédente
kubectl rollout undo deployment/optim-app -n production
# Rollback vers une révision spécifique
kubectl rollout undo deployment/optim-app --to-revision=3 -n production
# Vérifier le statut du rollout
kubectl rollout status deployment/optim-app -n production
Infrastructure en tant que Code¶
Configuration Terraform¶
# main.tf
provider "aws" {
region = var.aws_region
}
module "eks_cluster" {
source = "./modules/eks"
cluster_name = "optim-cluster"
node_groups = {
main = {
instance_types = ["t3.medium"]
min_size = 2
max_size = 10
desired_size = 3
}
}
}
module "rds_database" {
source = "./modules/rds"
engine = "postgres"
engine_version = "13.7"
instance_class = "db.t3.micro"
allocated_storage = 20
}
module "elasticache" {
source = "./modules/elasticache"
engine = "redis"
node_type = "cache.t3.micro"
num_cache_nodes = 1
}
Manifestes Kubernetes¶
# k8s/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: optim-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: optim-app
template:
metadata:
labels:
app: optim-app
spec:
containers:
- name: app
image: optim/app:latest
ports:
- containerPort: 3000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secret
key: url
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
Surveillance et Alertes¶
Collecte de Métriques¶
# prometheus/config.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: "optim-app"
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
Règles d'Alerte¶
# alerts/app.yml
groups:
- name: optim-app
rules:
- alert: TauxErreurEleve
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "Taux d'erreur élevé détecté"
description: "Le taux d'erreur est de {{ $value }} erreurs par seconde"
- alert: UtilisationMemoireElevee
expr: container_memory_usage_bytes / container_spec_memory_limit_bytes > 0.9
for: 2m
labels:
severity: critical
annotations:
summary: "Utilisation mémoire élevée"
description: "L'utilisation mémoire est supérieure à 90%"
Tableaux de Bord¶
{
"dashboard": {
"title": "Métriques Application Optim",
"panels": [
{
"title": "Taux de Requêtes",
"type": "graph",
"targets": [
{
"expr": "rate(http_requests_total[5m])",
"legendFormat": "{{method}} {{status}}"
}
]
},
{
"title": "Temps de Réponse",
"type": "graph",
"targets": [
{
"expr": "histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))",
"legendFormat": "95e percentile"
}
]
}
]
}
}
Sécurité¶
Sécurité Réseau¶
# k8s/network-policy.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: optim-app-policy
namespace: production
spec:
podSelector:
matchLabels:
app: optim-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: nginx-ingress
ports:
- protocol: TCP
port: 3000
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
Gestion des Secrets¶
# k8s/secrets.yml
apiVersion: v1
kind: Secret
metadata:
name: database-secret
namespace: production
type: Opaque
data:
url: <url-base-de-donnees-encodee-base64>
password: <mot-de-passe-encode-base64>
Configuration SSL/TLS¶
# k8s/ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: optim-app-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- api.optim.com
secretName: optim-tls
rules:
- host: api.optim.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: optim-app-service
port:
number: 80
Sauvegarde et Reprise après Sinistre¶
Sauvegardes de Base de Données¶
#!/bin/bash
# scripts/backup-database.sh
# Sauvegarde quotidienne
pg_dump $DATABASE_URL | gzip > backups/$(date +%Y%m%d)-database.sql.gz
# Upload vers S3
aws s3 cp backups/$(date +%Y%m%d)-database.sql.gz s3://optim-backups/database/
# Nettoyage des anciennes sauvegardes (conserver 30 jours)
find backups/ -name "*.sql.gz" -mtime +30 -delete
Plan de Reprise après Sinistre¶
- RTO (Objectif de Temps de Récupération) : 4 heures
- RPO (Objectif de Point de Récupération) : 1 heure
- Stratégie de Sauvegarde : Sauvegardes quotidiennes de base de données, réplication de fichiers en temps réel
- Processus de Basculement : Basculement DNS automatique vers la région secondaire
Optimisation des Performances¶
Stratégies de Mise à l'Échelle¶
# k8s/hpa.yml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: optim-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: optim-app
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Stratégie de Cache¶
# Configuration Redis
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
data:
redis.conf: |
maxmemory 256mb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
Snippets de Code pour Tâches Récurrentes¶
Cette section contient des extraits de code réutilisables pour les tâches d'infrastructure courantes et répétitives.
Gestion des Deployments Kubernetes¶
Déploiement Rapide d'une Nouvelle Version¶
#!/bin/bash
# Déploiement rapide avec vérification de santé
APP_NAME=${1:-optim-app}
NAMESPACE=${2:-production}
IMAGE_TAG=${3:-latest}
echo "🚀 Déploiement de $APP_NAME:$IMAGE_TAG vers $NAMESPACE..."
# Mise à jour de l'image
kubectl set image deployment/$APP_NAME app=optim/$APP_NAME:$IMAGE_TAG -n $NAMESPACE
# Attendre que le rollout soit terminé
kubectl rollout status deployment/$APP_NAME -n $NAMESPACE --timeout=300s
# Vérifier la santé des pods
kubectl get pods -l app=$APP_NAME -n $NAMESPACE
Redimensionnement Rapide d'Application¶
#!/bin/bash
# Script de redimensionnement rapide
APP_NAME=${1:-optim-app}
REPLICAS=${2:-3}
NAMESPACE=${3:-production}
echo "📊 Redimensionnement de $APP_NAME à $REPLICAS répliques..."
kubectl scale deployment $APP_NAME --replicas=$REPLICAS -n $NAMESPACE
kubectl rollout status deployment/$APP_NAME -n $NAMESPACE
Redémarrage Forcé de Pods¶
#!/bin/bash
# Redémarrage complet des pods d'une application
APP_NAME=${1:-optim-app}
NAMESPACE=${2:-production}
echo "🔄 Redémarrage forcé de $APP_NAME..."
kubectl rollout restart deployment/$APP_NAME -n $NAMESPACE
kubectl rollout status deployment/$APP_NAME -n $NAMESPACE
Gestion des Bases de Données¶
Sauvegarde Complète de Base de Données¶
#!/bin/bash
# Sauvegarde complète avec métadonnées
DB_NAME=${1:-optim_production}
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups"
echo "💾 Sauvegarde de $DB_NAME..."
# Créer le répertoire de sauvegarde
mkdir -p $BACKUP_DIR
# Sauvegarde avec compression
pg_dump $DATABASE_URL \
--verbose \
--clean \
--no-acl \
--no-owner \
| gzip > $BACKUP_DIR/${DB_NAME}_${TIMESTAMP}.sql.gz
# Vérifier la sauvegarde
if [ $? -eq 0 ]; then
echo "✅ Sauvegarde réussie: ${DB_NAME}_${TIMESTAMP}.sql.gz"
# Upload vers S3
aws s3 cp $BACKUP_DIR/${DB_NAME}_${TIMESTAMP}.sql.gz \
s3://optim-backups/database/
else
echo "❌ Échec de la sauvegarde"
exit 1
fi
Restauration de Base de Données¶
#!/bin/bash
# Restauration sécurisée de base de données
BACKUP_FILE=${1}
TARGET_DB=${2:-optim_staging}
if [ -z "$BACKUP_FILE" ]; then
echo "❌ Fichier de sauvegarde requis"
echo "Usage: $0 <backup_file> [target_db]"
exit 1
fi
echo "⚠️ ATTENTION: Restauration vers $TARGET_DB"
read -p "Êtes-vous sûr? (oui/non): " confirm
if [ "$confirm" = "oui" ]; then
echo "🔄 Restauration en cours..."
# Décompresser et restaurer
gunzip -c $BACKUP_FILE | psql $TARGET_DATABASE_URL
echo "✅ Restauration terminée"
else
echo "❌ Restauration annulée"
fi
Monitoring et Logs¶
Collection de Logs d'Urgence¶
#!/bin/bash
# Collecte rapide de logs pour debug
APP_NAME=${1:-optim-app}
NAMESPACE=${2:-production}
LINES=${3:-1000}
OUTPUT_DIR="/tmp/logs_$(date +%Y%m%d_%H%M%S)"
echo "📝 Collecte des logs de $APP_NAME..."
mkdir -p $OUTPUT_DIR
# Logs de tous les pods
for pod in $(kubectl get pods -l app=$APP_NAME -n $NAMESPACE -o name); do
pod_name=$(basename $pod)
echo "Collecte logs de $pod_name..."
kubectl logs $pod_name -n $NAMESPACE --tail=$LINES \
> $OUTPUT_DIR/${pod_name}.log
# Logs du conteneur précédent si redémarrage
kubectl logs $pod_name -n $NAMESPACE --previous --tail=$LINES \
> $OUTPUT_DIR/${pod_name}_previous.log 2>/dev/null || true
done
# Événements Kubernetes
kubectl get events -n $NAMESPACE --sort-by='.lastTimestamp' \
> $OUTPUT_DIR/k8s_events.log
echo "✅ Logs collectés dans: $OUTPUT_DIR"
tar -czf $OUTPUT_DIR.tar.gz -C /tmp $(basename $OUTPUT_DIR)
echo "📦 Archive créée: $OUTPUT_DIR.tar.gz"
Vérification de Santé Complète¶
#!/bin/bash
# Script de vérification de santé globale
NAMESPACE=${1:-production}
echo "🏥 Vérification de santé globale..."
# Statut des deployments
echo "=== DEPLOYMENTS ==="
kubectl get deployments -n $NAMESPACE -o wide
# Statut des pods
echo -e "\n=== PODS ==="
kubectl get pods -n $NAMESPACE -o wide
# Utilisation des ressources
echo -e "\n=== RESSOURCES ==="
kubectl top pods -n $NAMESPACE --sort-by=memory
# Services et endpoints
echo -e "\n=== SERVICES ==="
kubectl get services -n $NAMESPACE
# Événements récents
echo -e "\n=== ÉVÉNEMENTS RÉCENTS ==="
kubectl get events -n $NAMESPACE --sort-by='.lastTimestamp' | tail -10
# Alertes actives (si Prometheus)
echo -e "\n=== ALERTES ACTIVES ==="
curl -s http://prometheus:9090/api/v1/alerts | jq '.data.alerts[] | select(.state=="firing")' 2>/dev/null || echo "Prometheus non accessible"
Maintenance et Nettoyage¶
Nettoyage d'Images Docker¶
#!/bin/bash
# Nettoyage des images Docker obsolètes
KEEP_DAYS=${1:-7}
echo "🧹 Nettoyage des images Docker (conserver $KEEP_DAYS jours)..."
# Supprimer les images non utilisées
docker image prune -a -f --filter "until=${KEEP_DAYS}*24h"
# Supprimer les volumes orphelins
docker volume prune -f
# Supprimer les réseaux inutilisés
docker network prune -f
# Supprimer les conteneurs arrêtés
docker container prune -f
echo "✅ Nettoyage terminé"
docker system df
Rotation des Secrets Kubernetes¶
#!/bin/bash
# Rotation de secret avec zero-downtime
SECRET_NAME=${1}
NAMESPACE=${2:-production}
if [ -z "$SECRET_NAME" ]; then
echo "❌ Nom du secret requis"
echo "Usage: $0 <secret_name> [namespace]"
exit 1
fi
echo "🔐 Rotation du secret $SECRET_NAME..."
# Sauvegarder l'ancien secret
kubectl get secret $SECRET_NAME -n $NAMESPACE -o yaml > /tmp/${SECRET_NAME}_backup.yaml
# Générer nouveau mot de passe
NEW_PASSWORD=$(openssl rand -base64 32)
# Mettre à jour le secret
kubectl create secret generic $SECRET_NAME \
--from-literal=password=$NEW_PASSWORD \
--dry-run=client -o yaml | kubectl apply -n $NAMESPACE -f -
# Redémarrer les deployments qui utilisent ce secret
for deployment in $(kubectl get deployments -n $NAMESPACE -o json | jq -r '.items[] | select(.spec.template.spec.containers[].env[]?.valueFrom.secretKeyRef.name=="'$SECRET_NAME'") | .metadata.name'); do
echo "Redémarrage de $deployment..."
kubectl rollout restart deployment/$deployment -n $NAMESPACE
done
echo "✅ Rotation du secret terminée"
Scripts d'Automatisation CI/CD¶
Validation Pré-Déploiement¶
Post-Déploiement Health Check¶
Procédures d'Infrastructure et Kubernetes¶
Cette section contient des guides étape par étape pour les manipulations courantes d'infrastructure et de Kubernetes.
🚀 Procédures de Déploiement¶
Déploiement d'une Nouvelle Application¶
Prérequis: Accès kubectl configuré, Helm installé, images Docker prêtes
- Préparer l'environnement
# Vérifier la connexion au cluster
kubectl cluster-info
# Vérifier l'espace de noms
kubectl get namespaces
# Créer l'espace de noms si nécessaire
kubectl create namespace nouvelle-app
- Configurer les secrets
# Créer les secrets de base de données
kubectl create secret generic db-secret \
--from-literal=username=dbuser \
--from-literal=password=motdepasse \
-n nouvelle-app
# Créer les secrets API
kubectl create secret generic api-secret \
--from-literal=api-key=votre-cle-api \
-n nouvelle-app
- Déployer avec Helm
# Ajouter le dépôt Helm
helm repo add optim https://charts.optim.com
helm repo update
# Installer l'application
helm install nouvelle-app optim/app-chart \
--namespace nouvelle-app \
--set image.tag=v1.0.0 \
--set replicas=3
- Vérifier le déploiement
# Vérifier les pods
kubectl get pods -n nouvelle-app
# Vérifier les services
kubectl get services -n nouvelle-app
# Vérifier les ingress
kubectl get ingress -n nouvelle-app
Mise à Jour d'Application (Blue-Green)¶
Déploiement Optim Factory vers Recette¶
Prérequis:
- Accès au dépôt Git configuré
- Docker installé et configuré
- Azure CLI installé et configuré
- Accès au registry Azure (optimfactoryregistry.azurecr.io)
- Helm installé
- Accès au cluster AKS
Processus complet de déploiement:
- Préparation et Vérification du Code
# Récupérer les dernières modifications du dépôt
git pull
# Vérifier les fichiers modifiés (vue et art)
git status
git diff
# Vérifier que tous les fichiers sont bien suivis
git add -A
- Mise à Jour de la Version
# Modifier le numéro de version dans les fichiers de configuration
# Exemple: package.json, version.txt, ou fichiers de configuration
# Format recommandé: W2024.70.a (Semaine.Numéro.Révision)
# Vérifier la nouvelle version
grep -r "version" package.json
- Construction des Images Docker
# Construire l'image de l'application FastAPI
docker compose build fastapi
# Construire l'image de l'application principale
docker compose build app
# Vérifier que les images sont créées
docker images | grep saas
- Étiquetage des Images pour Azure Registry
# Étiqueter l'image FastAPI avec la version et timestamp
# Format: YYMMDD-HHMM
docker tag saas-fastapi optimfactoryregistry.azurecr.io/optim-factory-web-fastapi:250905-1000
# Étiqueter l'image principale avec la version et timestamp
docker tag saas-app optimfactoryregistry.azurecr.io/optim-factory-web-app:250904-1800
# Vérifier les tags
docker images | grep optimfactoryregistry
- Authentification Azure
# Se connecter à Azure avec le code de périphérique
az login --use-device-code
# Suivre les instructions affichées et entrer le code sur https://aka.ms/devicelogin
# Se connecter au registry Azure Container Registry
az acr login --name optimfactoryregistry.azurecr.io
- Publication des Images
# Pousser l'image FastAPI vers le registry
docker push optimfactoryregistry.azurecr.io/optim-factory-web-fastapi:250905-1000
# Pousser l'image principale vers le registry
docker push optimfactoryregistry.azurecr.io/optim-factory-web-app:250904-1800
# Vérifier que les images sont bien poussées
az acr repository list --name optimfactoryregistry
- Configuration Kubernetes
# Récupérer les credentials du cluster AKS
az aks get-credentials --resource-group optimfactorykubernetes_group --name optimfactorykubernetes
# Confirmer avec 'y' si demandé
# Vérifier la connexion au cluster
kubectl cluster-info
kubectl get nodes
- Déploiement avec Helm (MISE EN LIGNE)
# Naviguer vers le répertoire des charts Helm
cd charts
# Déployer vers l'environnement de recette
helm upgrade optimbtp-saas-recette ./ -f ./values-recette.yaml
# Vérifier le déploiement
kubectl get pods -n recette
kubectl get services -n recette
# Retourner au répertoire principal
cd ..
- Validation du Déploiement
# Vérifier le statut des pods
kubectl get pods -l app=optimbtp-saas-recette
# Vérifier les logs si nécessaire
kubectl logs -l app=optimbtp-saas-recette --tail=50
# Tester l'endpoint de santé
kubectl port-forward service/optimbtp-saas-recette 8080:80
curl http://localhost:8080/health
-
Enregistrement Git (ENREGISTREMENT GIT)
-
Gestion des Branches de Version
# Récupérer les dernières modifications de origin git fetch origin # Basculer vers la branche de développement git checkout dev # Créer une nouvelle branche de version git checkout -b "versions/20250904-W2024.70.a" # Pousser la nouvelle branche de version git push origin "versions/20250904-W2024.70.a" # Récupérer les modifications et retourner à dev git fetch origin git checkout dev
Notes importantes:
- Nommage des versions: Utiliser le format
YYMMDD-HHMMpour les tags Docker - Branches de version: Suivre le format
versions/YYYYMMDD-W2024.XX.x - Environnements: Cette procédure concerne l'environnement
recette - Rollback: En cas de problème, utiliser
helm rollback optimbtp-saas-recette [REVISION]
Vérifications post-déploiement:
# Vérifier l'état du déploiement Helm
helm status optimbtp-saas-recette
# Vérifier les ressources Kubernetes
kubectl get all -l app=optimbtp-saas-recette
# Vérifier les événements récents
kubectl get events --sort-by=.metadata.creationTimestamp | tail -10
🔧 Gestion des Clusters Kubernetes¶
Ajout d'un Nouveau Nœud au Cluster¶
- Préparer la machine
# Sur la nouvelle machine
# Installer Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
# Installer kubeadm, kubelet, kubectl
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update && sudo apt-get install -y kubelet kubeadm kubectl
- Générer le token de join (sur le master)
- Joindre le nœud au cluster
# Sur la nouvelle machine, exécuter la commande générée
sudo kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash <hash>
- Vérifier l'ajout
Configuration d'un Ingress Controller¶
- Installer NGINX Ingress
# Ajouter le dépôt Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# Installer l'ingress controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.replicaCount=2
- Configurer les certificats SSL
# Installer cert-manager
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set installCRDs=true
- Créer un ClusterIssuer
# cluster-issuer.yml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@optim.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
- Appliquer la configuration
💾 Gestion des Bases de Données¶
Sauvegarde Complète de PostgreSQL dans Kubernetes¶
- Créer un Job de sauvegarde
# backup-job.yml
apiVersion: batch/v1
kind: Job
metadata:
name: postgres-backup
namespace: database
spec:
template:
spec:
containers:
- name: postgres-backup
image: postgres:13
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
command:
- /bin/bash
- -c
- |
pg_dump -h postgres-service -U postgres -d optim_db | gzip > /backup/$(date +%Y%m%d_%H%M%S).sql.gz
aws s3 cp /backup/*.sql.gz s3://optim-backups/database/
volumeMounts:
- name: backup-storage
mountPath: /backup
volumes:
- name: backup-storage
emptyDir: {}
restartPolicy: Never
- Exécuter la sauvegarde
Restauration de Base de Données¶
- Préparer la restauration
# Arrêter l'application
kubectl scale deployment app-deployment --replicas=0 -n production
# Télécharger la sauvegarde
aws s3 cp s3://optim-backups/database/20240909_120000.sql.gz /tmp/
- Créer un Job de restauration
# restore-job.yml
apiVersion: batch/v1
kind: Job
metadata:
name: postgres-restore
namespace: database
spec:
template:
spec:
containers:
- name: postgres-restore
image: postgres:13
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
command:
- /bin/bash
- -c
- |
gunzip -c /backup/backup.sql.gz | psql -h postgres-service -U postgres -d optim_db
volumeMounts:
- name: backup-data
mountPath: /backup
volumes:
- name: backup-data
configMap:
name: backup-configmap
restartPolicy: Never
- Redémarrer l'application
🔐 Gestion des Secrets et Sécurité¶
Rotation des Secrets de Base de Données¶
- Générer un nouveau mot de passe
# Générer un mot de passe sécurisé
NEW_PASSWORD=$(openssl rand -base64 32)
echo "Nouveau mot de passe: $NEW_PASSWORD"
- Mettre à jour le secret Kubernetes
# Encoder en base64
echo -n "$NEW_PASSWORD" | base64
# Mettre à jour le secret
kubectl patch secret postgres-secret \
-p '{"data":{"password":"'$(echo -n "$NEW_PASSWORD" | base64)'"}}' \
-n database
- Mettre à jour la base de données
# Se connecter au pod PostgreSQL
kubectl exec -it postgres-pod -n database -- bash
# Dans le pod, changer le mot de passe
psql -U postgres -c "ALTER USER optim_user PASSWORD '$NEW_PASSWORD';"
- Redémarrer les applications
Configuration du RBAC¶
- Créer un ServiceAccount
# service-account.yml
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-service-account
namespace: production
- Créer un Role
# role.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: app-role
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "update"]
- Créer un RoleBinding
# role-binding.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-role-binding
namespace: production
subjects:
- kind: ServiceAccount
name: app-service-account
namespace: production
roleRef:
kind: Role
name: app-role
apiGroup: rbac.authorization.k8s.io
- Appliquer les configurations
📊 Surveillance et Monitoring¶
Configuration de Prometheus et Grafana¶
- Installer Prometheus avec Helm
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.adminPassword=admin123
- Configurer les ServiceMonitors
# app-service-monitor.yml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: app-service-monitor
namespace: monitoring
spec:
selector:
matchLabels:
app: optim-app
endpoints:
- port: metrics
path: /metrics
interval: 30s
- Créer des alertes personnalisées
# custom-alerts.yml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: app-alerts
namespace: monitoring
spec:
groups:
- name: optim.rules
rules:
- alert: HighMemoryUsage
expr: container_memory_usage_bytes / container_spec_memory_limit_bytes > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "Utilisation mémoire élevée détectée"
- Accéder aux interfaces
# Port-forward Grafana
kubectl port-forward svc/prometheus-grafana 3000:80 -n monitoring
# Port-forward Prometheus
kubectl port-forward svc/prometheus-kube-prometheus-prometheus 9090:9090 -n monitoring
🛠️ Maintenance et Mise à l'Échelle¶
Mise à l'Échelle Automatique (HPA)¶
- Installer Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
- Créer un HPA
# hpa.yml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app-deployment
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- Appliquer et vérifier
Nettoyage et Maintenance¶
- Nettoyer les images inutilisées
# Sur chaque nœud
docker system prune -a -f
# Ou utiliser un DaemonSet
kubectl create -f - <<EOF
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: docker-cleanup
namespace: kube-system
spec:
selector:
matchLabels:
name: docker-cleanup
template:
metadata:
labels:
name: docker-cleanup
spec:
containers:
- name: docker-cleanup
image: docker:dind
command: ["docker", "system", "prune", "-a", "-f"]
volumeMounts:
- name: docker-sock
mountPath: /var/run/docker.sock
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
EOF
- Nettoyer les ressources Kubernetes
# Supprimer les pods terminés
kubectl delete pods --field-selector=status.phase=Succeeded --all-namespaces
# Supprimer les jobs terminés
kubectl delete jobs --field-selector=status.successful=1 --all-namespaces
# Nettoyer les événements anciens
kubectl get events --sort-by=.metadata.creationTimestamp --all-namespaces
Dépannage¶
Problèmes Courants¶
- Plantages de Pods
- Utilisation Mémoire Élevée
- Problèmes de Connexion Base de Données
Procédures d'Urgence¶
- Réduire le Trafic
- Activer le Mode Maintenance
- Accès d'Urgence à la Base de Données
Ressources¶
Pour les questions d'infrastructure ou les urgences, contactez immédiatement l'équipe DevOps.