Introduction
Bien menée, l’automatisation d’HDFS (Hadoop Distributed File System) : système de fichiers distribué de Hadoop, s’amortit vite : moins d’erreurs manuelles, des changements prévisibles et une traçabilité claire. Ce guide montre comment construire des pipelines de CI/CD (Continuous Integration/Continuous Delivery) : chaîne d’intégration et de déploiement continus, pratiques et testables pour HDFS, déployables dès aujourd’hui. Vous allez mettre en œuvre deux workflows à fort impact avec plan, application, vérification et retour arrière (rollback) :
- Gérer des répertoires, quotas et ACLs (Access Control Lists) : listes de contrôle d’accès, comme du code.
- Déployer des changements du facteur de réplication de manière sûre et vérifiable.
L’approche est simple : déclarer l’état désiré dans des manifestes, générer un plan, appliquer de façon idempotente, puis vérifier. En chemin, vous verrez des commandes concrètes, des modes de panne typiques et une checklist d’exploitation à dérouler à chaque fenêtre de changement.
Environnement et prérequis
Avant d’automatiser, consignez les versions et points de terminaison afin de garantir des exécutions cohérentes :
- HDFS : exemple 3.3.6 avec NameNodes en HA (High Availability) : haute disponibilité (nn1, nn2) et JournalNodes.
- Hadoop client CLI (Command Line Interface) : interface en ligne de commande, exemple 3.3.6 disponible sur l’hôte d’automatisation.
- Java : exemple 11.x pour les outils Hadoop.
- Kerberos : activé avec un principal de service et un keytab pour kinit non interactif.
- OS et accès : un hôte passerelle avec HADOOP_CONF_DIR pointant vers les XML du cluster et un accès réseau aux ports RPC/IPC (Remote Procedure Call / Inter‑Process Communication) : appels distants et inter‑processus des NameNodes.
- Optionnel : Ranger ou Sentry pour une autorisation centralisée.
Vous aurez besoin de :
- Un dépôt Git pour les manifestes et scripts.
- Un exécuteur CI/CD capable de lancer du shell sur l’hôte passerelle.
- yq installé sur l’exécuteur pour parser le YAML (YAML Ain’t Markup Language) : format de sérialisation lisible.
- Des variables d’environnement pour le keytab et le principal Kerberos si la sécurité est activée.
Un schéma sûr pour le CI/CD HDFS
Adoptez ces principes pour des résultats répétables :
- Déclarer l’état désiré comme du code. Stockez les intentions HDFS (chemins, quotas, ACLs, réplication) dans des manifestes versionnés, pas en dur dans des scripts.
- Planifier d’abord. Calculez et affichez un diff des actions proposées sans modifier HDFS.
- Appliquer de façon idempotente et vérifier. Rendez les opérations sûres à réexécuter, validez avec des contrôles explicites et définissez des étapes de rollback claires.
Les exemples suivants implémentent ce modèle de bout en bout.
Exemple A : Gérer répertoires, quotas et ACLs comme du code
Objectif : garantir l’existence d’un ensemble de répertoires projet avec des quotas de namespace et d’espace définis et des ACLs standard.
Manifeste (exemple)
# file: hdfs_dirs.yaml
root: /data/projects
entries:
- path: analytics
ns_quota: 200000 # namespace quota (files + dirs)
space_quota: 10t # logical space quota
acls:
- user:alice:rwx
- user:bob:r-x
- group:analytics:r-x
- path: ingest
ns_quota: 100000
space_quota: 5t
acls:
- user:etl:rwx
- group:ops:r-x
Script de planification/application (bash, idempotent)
#!/usr/bin/env bash
# file: hdfs_dirs.sh
set -euo pipefail
MODE="${1:-}" # plan | apply
MANIFEST="${2:-hdfs_dirs.yaml}"
if [[ -z "$MODE" || ! "$MODE" =~ ^(plan|apply)$ ]]; then
echo "Usage: $0 plan|apply [manifest.yaml]" >&2
exit 2
fi
need() { command -v "$1" >/dev/null 2>&1 || { echo "missing $1" >&2; exit 2; }; }
need hdfs
need yq
# Kerberos non-interactive login if configured
if [[ -n "${KRB5_PRINCIPAL:-}" && -n "${KRB5_KEYTAB:-}" ]]; then
kinit -kt "$KRB5_KEYTAB" "$KRB5_PRINCIPAL" >/dev/null
fi
ts() { date +"%Y-%m-%dT%H:%M:%S%z"; }
log() { echo "[$(ts)] $*"; }
die() { echo "ERROR: $*" >&2; exit 1; }
ROOT=$(yq -r '.root' "$MANIFEST")
[[ -n "$ROOT" && "$ROOT" != "null" ]] || die "manifest missing .root"
COUNT=$(yq -r '.entries | length' "$MANIFEST")
[[ "$COUNT" =~ ^[0-9]+$ ]] || die "manifest entries invalid"
for i in $(seq 0 $((COUNT-1))); do
SUBPATH=$(yq -r ".entries[$i].path" "$MANIFEST")
NSQ=$(yq -r ".entries[$i].ns_quota // \"\"" "$MANIFEST")
SPQ=$(yq -r ".entries[$i].space_quota // \"\"" "$MANIFEST")
FULL="$ROOT/$SUBPATH"
# Ensure directory exists
if ! hdfs dfs -test -d "$FULL"; then
log "CREATE dir $FULL"
[[ "$MODE" == "apply" ]] && hdfs dfs -mkdir -p "$FULL"
else
log "EXISTS $FULL"
fi
# Read current quotas (fields: QUOTA REMAINING SPACE_QUOTA REMAINING ... PATH)
CURRENT_LINE=$(hdfs dfs -count -q "$FULL" | tail -n1 || true)
CUR_NSQ=$(awk '{print $1}' <<<"$CURRENT_LINE")
CUR_SPQ=$(awk '{print $3}' <<<"$CURRENT_LINE")
# Set namespace quota if different and desired provided
if [[ -n "$NSQ" && "$NSQ" != "null" ]]; then
if [[ "$CUR_NSQ" != "$NSQ" ]]; then
log "SET ns_quota $NSQ on $FULL (was ${CUR_NSQ:-none})"
[[ "$MODE" == "apply" ]] && hdfs dfsadmin -setQuota "$NSQ" "$FULL"
fi
fi
# Set space quota if different and desired provided
if [[ -n "$SPQ" && "$SPQ" != "null" ]]; then
if [[ "$CUR_SPQ" != "$SPQ" ]]; then
log "SET space_quota $SPQ on $FULL (was ${CUR_SPQ:-none})"
[[ "$MODE" == "apply" ]] && hdfs dfsadmin -setSpaceQuota "$SPQ" "$FULL"
fi
fi
# Build ACL spec from array of strings like user:alice:rwx
ACLS_LEN=$(yq -r ".entries[$i].acls | length" "$MANIFEST" 2>/dev/null || echo 0)
if [[ "$ACLS_LEN" =~ ^[1-9][0-9]*$ ]]; then
ACLSPEC=$(yq -r ".entries[$i].acls[]" "$MANIFEST" | paste -sd, -)
log "SET ACL '$ACLSPEC' on $FULL (recursive)"
[[ "$MODE" == "apply" ]] && hdfs dfs -setfacl -R -m "$ACLSPEC" "$FULL"
fi
done
Notes :
- Le script affiche ce qu’il changerait en mode plan et n’exécute qu’en mode apply.
- Les réexécutions sont sûres : créer un répertoire existant est ignoré ; des quotas ou ACLs identiques n’entraînent aucun changement.
- Pour Kerberos, passez KRB5_PRINCIPAL et KRB5_KEYTAB via les secrets CI. Le script n’appelle kinit que si les deux sont présents.
Squelette CI/CD (idée portable)
- Étape : lint
- Valider le YAML (yamllint), linter le shell (shellcheck) et échouer rapidement.
- Étape : plan
- Exécuter
bash hdfs_dirs.sh plan hdfs_dirs.yamlet archiver plan.out. - Étape : apply (garde manuelle)
- Exécuter
bash hdfs_dirs.sh apply hdfs_dirs.yamlet archiver apply.out.
Exemple de sortie de plan (illustratif)
[2026-08-16T10:12:05+0000] CREATE dir /data/projects/analytics
[2026-08-16T10:12:05+0000] SET ns_quota 200000 on /data/projects/analytics (was none)
[2026-08-16T10:12:05+0000] SET space_quota 10t on /data/projects/analytics (was none)
[2026-08-16T10:12:05+0000] SET ACL 'user:alice:rwx,user:bob:r-x,group:analytics:r-x' on /data/projects/analytics (recursive)
[2026-08-16T10:12:05+0000] EXISTS /data/projects/ingest
[2026-08-16T10:12:05+0000] SET ns_quota 100000 on /data/projects/ingest (was 80000)
[2026-08-16T10:12:05+0000] SET space_quota 5t on /data/projects/ingest (was 4t)
[2026-08-16T10:12:05+0000] SET ACL 'user:etl:rwx,group:ops:r-x' on /data/projects/ingest (recursive)
Retour arrière (Exemple A)
- Quotas : rétablir les valeurs précédentes avec
hdfs dfsadmin -setQuota <ancien>et-setSpaceQuota <ancien>. - ACLs : supprimer toutes les ACLs étendues avec
hdfs dfs -setfacl -R -b <chemin>(le propriétaire et le mode restent). - Répertoires : ne supprimer que les répertoires vides avec
hdfs dfs -rmdir <chemin>; ne supprimez jamais des arbres peuplés sans plan de rétention.
Exemple B : Déploiement sûr des changements de facteur de réplication
Changer la réplication a un impact sur la capacité et les SLAs (Service Level Agreements) : engagements de niveau de service, de reprise. Planifiez d’abord, appliquez lors de fenêtres maîtrisées et vérifiez la convergence.
Manifeste (exemple)
# file: hdfs_replication.yaml
rules:
- path: /data/projects/analytics
replication: 3
- path: /data/projects/ingest
replication: 2
Script de planification/application (bash)
#!/usr/bin/env bash
# file: hdfs_replication.sh
set -euo pipefail
MODE="${1:-}" # plan | apply
MANIFEST="${2:-hdfs_replication.yaml}"
if [[ -z "$MODE" || ! "$MODE" =~ ^(plan|apply)$ ]]; then
echo "Usage: $0 plan|apply [manifest.yaml]" >&2
exit 2
fi
need() { command -v "$1" >/dev/null 2>&1 || { echo "missing $1" >&2; exit 2; }; }
need hdfs
need yq
if [[ -n "${KRB5_PRINCIPAL:-}" && -n "${KRB5_KEYTAB:-}" ]]; then
kinit -kt "$KRB5_KEYTAB" "$KRB5_PRINCIPAL" >/dev/null
fi
ts() { date +"%Y-%m-%dT%H:%M:%S%z"; }
log() { echo "[$(ts)] $*"; }
COUNT=$(yq -r '.rules | length' "$MANIFEST")
for i in $(seq 0 $((COUNT-1))); do
PATH_PREFIX=$(yq -r ".rules[$i].path" "$MANIFEST")
DESIRED=$(yq -r ".rules[$i].replication" "$MANIFEST")
log "Inspecting $PATH_PREFIX (desired $DESIRED)"
# Sample up to 50 files for planning clarity
SAMPLE_FILES=$(hdfs dfs -ls -R "$PATH_PREFIX" 2>/dev/null | awk '{print $8}' | head -n 50)
CHANGES=0
while read -r F; do
[[ -z "$F" ]] && continue
if hdfs dfs -test -d "$F"; then continue; fi
CUR=$(hdfs dfs -stat %r "$F" 2>/dev/null || echo -1)
if [[ "$CUR" -ne "$DESIRED" ]]; then
log "DIFF $F rep=$CUR -> $DESIRED"
CHANGES=$((CHANGES+1))
fi
done <<< "$SAMPLE_FILES"
if [[ "$MODE" == "apply" ]]; then
log "Applying replication=$DESIRED under $PATH_PREFIX (recursive, wait)"
hdfs dfs -setrep -R -w "$DESIRED" "$PATH_PREFIX"
fi
log "Summary for $PATH_PREFIX: sample files needing change=$CHANGES"
done
Vérification post‑application (Exemple B)
- Convergence :
hdfs fsck <chemin> -files -blocks | grep Under-replicateddoit retourner 0. - Contrôles ponctuels :
hdfs dfs -stat %r <un/fichier>doit égaler la réplication désirée. - Sur la capacité : assurez-vous que les DataNodes ont de la marge ; activez ou mettez en pause le balancer avec discernement.
Retour arrière (Exemple B)
- Rétablir la réplication au facteur précédent avec
hdfs dfs -setrep -R -w <ancien_facteur> <chemin>. - Si la capacité est tendue, mettez en pause les charges lourdes (DistCp, gros ingests) jusqu’à stabilisation de la réplication.
Vérification et diagnostics
Exécutez ces contrôles avant et après chaque application.
Contrôles pré‑application :
- NameNode et état HA :
hdfs haadmin -getServiceState nn1(attendez un actif, un standby)hdfs dfsadmin -safemode get(attendez OFF)- Authentification :
klistaffiche un TGT (Ticket Granting Ticket) : ticket d’octroi Kerberos valide pour le principal CI- Autorisation (sanity check sur un chemin) :
hdfs dfs -test -w /tmpretourne succès pour le principal- Filet de sécurité :
- Confirmez
fs.trash.intervaldans core-site.xml si vous comptez sur la Corbeille (Trash)
Contrôles post‑application :
- Exemple A (chemins, quotas, ACLs) :
- Répertoires présents :
hdfs dfs -test -d <chemin> - Quotas appliqués :
hdfs dfs -count -q <chemin>; comparez QUOTA et SPACE_QUOTA au manifeste - ACLs en place :
hdfs dfs -getfacl <chemin> | grep user:alice:rwx(adaptez à vos entrées) - Exemple B (réplication) :
- Blocs sous‑répliqués :
hdfs fsck <chemin> -blocks -files | grep Under-replicatedretourne 0 - Des fichiers choisis affichent la réplication
%rdésirée
Diagnostics quand quelque chose cloche :
- SafeMode est ON : n’appliquez pas ; investiguez les journaux NameNode et les rapports de blocs DataNode.
- Permission refusée pour ACL ou quota : vérifiez la politique Ranger/Sentry ; utilisez un principal de service avec droits d’admin sur les opérations de métadonnées.
- Échecs Kerberos : refaites
kinit -kt; assurez la synchro temporelle et le principal/domaine corrects. - Récursivité ACL lente : appliquez par lots plus petits ou en heures creuses.
- Réplication bloquée : examinez la santé des DataNodes, la prise en compte des racks et l’espace disque ; mettez temporairement en pause les charges de stockage lourdes.
Commencez petit : un pilote court et inspectable
Démarrez avec un seul répertoire projet et un manifeste réduit. Exécutez le plan pendant une fenêtre peu fréquentée, relisez le diff, puis appliquez. Gardez les premiers lancements assez petits pour lire l’intégralité de plan.out et d’apply.out en quelques minutes. Une fois stabilisé, étendez à d’autres chemins et équipes.
Liste de contrôle opérationnelle
Avant de commencer :
- Confirmez la fenêtre de changement et l’astreinte.
- Vérifiez la HA : un actif, un standby ; safemode OFF.
- Validez l’authentification :
klistaffiche un TGT valide pour le principal CI. - Confirmez que HADOOP_CONF_DIR pointe vers le cluster visé.
Phase de plan :
- Mettez à jour les manifestes, validez, et tagguez si vous versionnez les releases.
- Lancez les linters ; corrigez YAML ou shell avant de poursuivre.
- Exécutez le plan ; relisez plan.out pour la portée et l’exactitude.
- Si les changements sont étendus, scindez en lots plus petits ou échelonnez sur plusieurs fenêtres.
Phase d’application :
- Optionnellement, mettez en pause les opérations HDFS lourdes (gros ingests, DistCp, balancer) pour réduire le bruit.
- Exécutez l’application et suivez les logs ; si des erreurs répétées surviennent, stoppez, diagnostiquez, puis replanifiez.
Vérification post‑application :
- Refaites les contrôles clés : quotas via
dfs -count -q, ACLs viagetfacl, réplication viafscket%r. - Assurez‑vous que les blocs sous‑répliqués reviennent au niveau de base sur les chemins modifiés.
- Archivez apply.out, les journaux de vérification et les timings pour audit et rollback.
En cas d’échec :
- Servez‑vous d’apply.out pour identifier exactement ce qui a changé.
- Restaurez de façon sélective : réinitialisez des quotas, supprimez des ACLs ou rétablissez des facteurs de réplication.
- Documentez le problème et les enseignements ; planifiez un changement de suivi si nécessaire.
Modes de défaillance et réponses sûres
- NameNode en SafeMode : annulez l’application ; attendez la sortie ; investiguez les rapports de blocs.
- Ticket Kerberos expiré : kinit avec keytab ; relancez plan/apply.
- Autorisation refusée : ajustez la politique ou utilisez un principal admin ; revenez sur les changements partiels selon l’état antérieur.
- Quota déjà dépassé : nettoyez des données ou augmentez temporairement le quota sous contrôle de changement.
- Réplication qui ne converge pas : vérifiez DataNodes et capacité ; revenez au facteur précédent si la contrainte persiste.
- Basculement HA en cours d’application : réessayez après stabilisation ; gardez des lots courts pour réduire le rayon d’impact.
Astuce : si des snapshots sont activés sur les répertoires cibles, prenez un snapshot juste avant l’application pour simplifier un retour de données, par exemple : hdfs dfs -createSnapshot /data/projects/analytics pre_change_w32.
Conclusion
Vous n’avez pas besoin d’une plateforme lourde pour fiabiliser les changements HDFS. Commencez par deux workflows simples et précieux : gérer répertoires, quotas et ACLs comme du code, et déployer les changements de réplication avec un plan clair et des vérifications. Conservez les manifestes dans Git, exécutez un plan avant d’appliquer, rendez les modifications idempotentes et intégrez des pré‑contrôles pour la HA, le SafeMode et l’authentification. Capturez plan.out et apply.out à chaque exécution pour que les retours arrière soient rapides et ciblés. Une fois ces pratiques routinières, étendez‑les à d’autres workflows (zones d’atterrissage d’ingest, chemins de staging, rétention étagée) en gardant un risque faible et des résultats prévisibles.