Développement d’actions de script avec HDInsight

Apprenez à personnaliser votre cluster HDInsight en utilisant des scripts Bash. Les actions de script sont un moyen de personnaliser HDInsight pendant ou après la création du cluster.

Que sont les actions de script ?

Les actions de script sont des scripts Bash que Azure exécute sur les nœuds du cluster pour effectuer des modifications de configuration ou installer des logiciels. Une action scriptée est exécutée en tant que racine et offre des droits d’accès complets aux nœuds du cluster.

Les actions scriptées peuvent être appliquées par les méthodes suivantes :

Utilisez cette méthode pour appliquer un script... Lors de la création de clusters... Sur un cluster en marche...
Azure portal ✓ ✓
Azure PowerShell ✓ ✓
Azure Classic CLI   ✓
SDK HDInsight .NET ✓ ✓
modèle de gestionnaire de ressources Azure ✓  

Pour plus d’informations sur l’utilisation de ces méthodes pour appliquer des actions de script, voir Personnaliser les clusters HDInsight à l’aide d’actions de script.

Meilleures pratiques pour le développement de scripts

Lorsque vous développez un script personnalisé pour un cluster HDInsight, il y a plusieurs bonnes pratiques à garder à l’esprit :

Important

Les actions de script doivent être terminées sous 60 minutes, sinon le processus échoue. Lors de l’approvisionnement du nœud, le script s’exécute en même temps que les autres processus d'installation et de configuration. La concurrence pour des ressources telles que le temps CPU ou la bande passante réseau peut faire que le script prenne plus de temps à se terminer que dans votre environnement de développement.

Ciblez la version Apache Hadoop

Différentes versions de HDInsight disposent de différentes versions des services et composants Hadoop. Si votre script attend une version de service ou de composant spécifique, vous devez utiliser uniquement le script avec la version de HDInsight qui inclut les composants requis. Vous pouvez trouver des informations sur les versions des composants incluses dans HDInsight en utilisant le document de versionnement des composants HDInsight .

Vérification de la version du système d’exploitation

Différentes versions de HDInsight reposent sur des versions spécifiques d’Ubuntu. Il peut y avoir des différences entre les versions du système d’exploitation que vous devez vérifier dans votre script. Par exemple, vous pourriez avoir besoin d’installer un binaire lié à la version d’Ubuntu.

Pour vérifier la version du système d’exploitation, utilisez lsb_release. Par exemple, le script suivant montre comment référencer un fichier tar spécifique selon la version du système d’exploitation :

OS_VERSION=$(lsb_release -sr)
if [[ $OS_VERSION == 14* ]]; then
    echo "OS version is $OS_VERSION. Using hue-binaries-14-04."
    HUE_TARFILE=hue-binaries-14-04.tgz
elif [[ $OS_VERSION == 16* ]]; then
    echo "OS version is $OS_VERSION. Using hue-binaries-16-04."
    HUE_TARFILE=hue-binaries-16-04.tgz
fi

Cibler la version du système d’exploitation

HDInsight est basé sur la distribution Ubuntu Linux. Différentes versions de HDInsight reposent sur différentes versions d’Ubuntu, ce qui peut modifier le comportement de votre script. Par exemple, HDInsight 3.4 et les versions antérieures sont basées sur des versions d’Ubuntu qui utilisent Upstart. Les versions 3.5 et suivantes sont basées sur Ubuntu 16.04, qui utilise Systemd. Systemd et Upstart reposent sur différentes commandes, donc votre script doit être écrit pour fonctionner avec les deux.

Une autre différence importante entre HDInsight 3.4 et 3.5 est que JAVA_HOME pointe désormais vers Java 8. Le code suivant montre comment déterminer si le script fonctionne sous Ubuntu 14 ou 16 :

OS_VERSION=$(lsb_release -sr)
if [[ $OS_VERSION == 14* ]]; then
    echo "OS version is $OS_VERSION. Using hue-binaries-14-04."
    HUE_TARFILE=hue-binaries-14-04.tgz
elif [[ $OS_VERSION == 16* ]]; then
    echo "OS version is $OS_VERSION. Using hue-binaries-16-04."
    HUE_TARFILE=hue-binaries-16-04.tgz
fi
...
if [[ $OS_VERSION == 16* ]]; then
    echo "Using systemd configuration"
    systemctl daemon-reload
    systemctl stop webwasb.service    
    systemctl start webwasb.service
else
    echo "Using upstart configuration"
    initctl reload-configuration
    stop webwasb
    start webwasb
fi
...
if [[ $OS_VERSION == 14* ]]; then
    export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
elif [[ $OS_VERSION == 16* ]]; then
    export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
fi

Vous pouvez trouver le script complet contenant ces extraits à https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh.

Pour la version d’Ubuntu utilisée par HDInsight, consultez le document version des composants HDInsight.

Pour comprendre les différences entre Systemd et Upstart, voir Systemd pour les utilisateurs d’Upstart.

Fournir des liens stables vers les ressources de script

Le script et les ressources associées doivent rester disponibles tout au long de la durée de vie du cluster. Ces ressources sont nécessaires si de nouveaux nœuds sont ajoutés au cluster lors des opérations de mise à l’échelle.

La meilleure pratique est de télécharger et d’archiver tout ce qui se trouve dans un compte stockage Azure de votre abonnement.

Important

Le compte de stockage utilisé doit être le compte de stockage par défaut pour le cluster ou un conteneur public en lecture seule sur n’importe quel autre compte de stockage.

Par exemple, les exemples fournis par Microsoft sont stockés dans le compte de stockage https://hdiconfigactions.blob.core.windows.net/. Cet emplacement est un conteneur public, en lecture seule, maintenu par l’équipe HDInsight.

Utilisez des ressources précompilées

Pour réduire le temps nécessaire à l’exécution du script, évitez les opérations qui compilent des ressources à partir du code source. Par exemple, pré-compiler les ressources et les stocker dans un blob de compte stockage Azure dans le même centre de données que HDInsight.

Assurez-vous que le script de personnalisation du cluster est idempotent

Les scripts doivent être idempotents. Si le script s’exécute plusieurs fois, il devrait remettre le cluster dans le même état à chaque fois.

Si le script s’exécute plusieurs fois, le script qui modifie les fichiers de configuration ne devrait pas ajouter de doublons.

Garantir une haute disponibilité de l’architecture de cluster

Les clusters HDInsight basés sur Linux fournissent deux nœuds principaux actifs au sein du cluster, et des actions de script s’exécutent sur les deux nœuds. Si les composants que vous installez s’attendent à un seul nœud de tête, ne les installez pas sur les deux nœuds de tête.

Important

Les services fournis dans le cadre de HDInsight sont conçus pour effectuer un basculement entre les deux nœuds de tête selon les besoins. Cette fonctionnalité ne s’applique pas aux composants personnalisés installés via des actions de script. Si vous avez besoin d’une grande disponibilité pour des composants personnalisés, vous devez mettre en place votre propre mécanisme de basculement.

Configurez les composants personnalisés pour utiliser le stockage Azure Blob

Les composants que vous installez sur le cluster peuvent avoir une configuration par défaut utilisant le stockage HDFS (Apache Hadoop Distributed File System). HDInsight utilise soit stockage Azure, soit Data Lake Storage comme stockage par défaut. Les deux fournissent un système de fichiers compatible HDFS qui fait persister les données même si le cluster est supprimé. Vous devrez peut-être configurer les composants que vous installez pour utiliser WASB ou ADL au lieu de HDFS.

Pour la plupart des opérations, il n’est pas nécessaire de spécifier le système de fichiers. Par exemple, ce qui suit copie le fichier hadoop-common.jar du système de fichiers local vers le stockage en cluster :

hdfs dfs -put /usr/hdp/current/hadoop-client/hadoop-common.jar /example/jars/

Dans cet exemple, la hdfs commande utilise de manière transparente le stockage par défaut du cluster. Pour certaines opérations, il peut être nécessaire de spécifier l’URI. Par exemple, adl:///example/jars pour Azure Data Lake Storage Gen1, abfs:///example/jars pour Data Lake Storage Gen2 ou wasb:///example/jars pour stockage Azure.

Écrire des informations sur STDOUT et STDERR

HDInsight enregistre la sortie de script écrite sur STDOUT et STDERR. Vous pouvez consulter ces informations via l’interface web d’Ambari.

Note

Apache Ambari n’est disponible que si le cluster est créé avec succès. Si vous utilisez une action de script lors de la création du cluster et que la création échoue, consultez Résoudre les problèmes liés aux actions de script pour d’autres moyens d’accéder aux informations enregistrées.

La plupart des utilitaires et des packages d’installation écrivent déjà des informations sur STDOUT et STDERR, cependant vous souhaiterez peut-être ajouter des journaux supplémentaires. Pour envoyer du texte à STDOUT, utilisez echo. Par exemple:

echo "Getting ready to install Foo"

Par défaut, echo envoie la chaîne à STDOUT. Pour le diriger vers STDERR, ajoutez >&2 avant echo. Par exemple:

>&2 echo "An error occurred installing Foo"

Cela redirige plutôt les informations écrites vers STDOUT vers STDERR (2). Pour plus d’informations sur la redirection des E/S, voir https://www.tldp.org/LDP/abs/html/io-redirection.html.

Pour plus d’informations sur la visualisation des informations enregistrées par les actions de script, voir Résoudre les problèmes liés aux actions de script.

Sauvegarder les fichiers en ASCII avec des fins de ligne LF

Les scripts bash doivent être stockés au format ASCII, avec des lignes terminées par LF. Les fichiers stockés en UTF-8, ou utilisant CRLF comme fin de ligne, peuvent échouer avec l’erreur suivante :

$'\r': command not found
line 1: #!/usr/bin/env: No such file or directory

Utilisez la logique de nouvelle tentative pour récupérer après des erreurs transitoires

Lorsque vous téléchargez des fichiers, installez des paquets via apt-get ou effectuez d’autres actions qui transmettent des données sur Internet, l’action peut échouer à cause d’erreurs réseau transitoires. Par exemple, la ressource distante avec laquelle vous communiquez peut être en train d’effectuer un basculement vers un nœud de secours.

Pour rendre votre script résistant aux erreurs transitoires, vous pouvez implémenter une logique de nouvelle tentative. La fonction suivante démontre comment implémenter la logique de réessayage. Il retente l’opération trois fois avant d’échouer.

#retry
MAXATTEMPTS=3

retry() {
    local -r CMD="$@"
    local -i ATTMEPTNUM=1
    local -i RETRYINTERVAL=2

    until $CMD
    do
        if (( ATTMEPTNUM == MAXATTEMPTS ))
        then
                echo "Attempt $ATTMEPTNUM failed. no more attempts left."
                return 1
        else
                echo "Attempt $ATTMEPTNUM failed! Retrying in $RETRYINTERVAL seconds..."
                sleep $(( RETRYINTERVAL ))
                ATTMEPTNUM=$ATTMEPTNUM+1
        fi
    done
}

Les exemples suivants montrent comment utiliser cette fonction.

retry ls -ltr foo

retry wget -O ./tmpfile.sh https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh

Méthodes d’aide pour les scripts personnalisés

Les méthodes d’aide aux actions de script sont des utilitaires que vous pouvez utiliser lors de l’écriture de scripts personnalisés. Ces méthodes sont contenues dans le https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh script. Utilisez ce qui suit pour les télécharger et les intégrer dans votre script :

# Import the helper method module.
wget -O /tmp/HDInsightUtilities-v01.sh -q https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh && source /tmp/HDInsightUtilities-v01.sh && rm -f /tmp/HDInsightUtilities-v01.sh

Les aides suivantes sont disponibles pour votre script :

Utilisation de l’aide Description
download_file SOURCEURL DESTFILEPATH [OVERWRITE] Télécharge un fichier depuis l’URI source vers le chemin de fichier spécifié. Par défaut, il ne remplace pas un fichier existant.
untar_file TARFILE DESTDIR Extrait un fichier tar (à l’aide de -xf,) dans le répertoire de destination.
test_is_headnode Si le script s’est exécuté sur un nœud principal de cluster, retourner 1 ; sinon, 0.
test_is_datanode Si le nœud actuel est un nœud de données (travailleur), retournez un 1 ; sinon, 0.
test_is_first_datanode Si le nœud courant est le premier nœud de données (travailleur) (nommé workernode0), retournez un 1 ; sinon, 0.
get_headnodes Retournez le nom de domaine entièrement qualifié des nœuds principaux du cluster. Les noms sont délimités par des virgules. Une chaîne vide est retournée en cas d’erreur.
get_primary_headnode Obtient le nom de domaine pleinement qualifié du nœud principal principal. Une chaîne vide est retournée en cas d’erreur.
get_secondary_headnode Obtient le nom de domaine pleinement qualifié du second headnode. Une chaîne vide est retournée en cas d’erreur.
get_primary_headnode_number Obtient le suffixe numérique du nœud principal principal. Une chaîne vide est retournée en cas d’erreur.
get_secondary_headnode_number Obtient le suffixe numérique du nœud principal secondaire. Une chaîne vide est retournée en cas d’erreur.

Modèles d’utilisation courants

Cette section fournit des conseils pour implémenter certains des schémas d’usage courants que vous pourriez rencontrer en écrivant votre propre script personnalisé.

Passage des paramètres à un script

Dans certains cas, votre script peut nécessiter des paramètres. Par exemple, vous pourriez avoir besoin du mot de passe administrateur du cluster lorsque vous utilisez l’API REST d’Ambari.

Les paramètres passés au script sont appelés paramètres positionnels, et sont attribués à $1 pour le premier paramètre, $2 pour le second, et ainsi de suite. $0 contient le nom du script lui-même.

Les valeurs transmises au script en tant que paramètres doivent être entourées de guillemets simples ('). Cela garantit que la valeur passée est traitée comme une valeur littérale.

Définition des variables d'environnement

La définition d’une variable d’environnement s’effectue par l’instruction suivante :

VARIABLENAME=value

Dans l’exemple précédent, VARIABLENAME est le nom de la variable. Pour accéder à la variable, utilisez $VARIABLENAME. Par exemple, pour assigner une valeur fournie par un paramètre positionnel comme variable d’environnement nommée PASSWORD, vous utiliseriez l’instruction suivante :

PASSWORD=$1

Un accès ultérieur à l’information pourrait alors utiliser $PASSWORD.

Les variables d’environnement définies dans le script n’existent que dans le périmètre du script. Dans certains cas, il peut être nécessaire d’ajouter des variables d’environnement système qui persisteront après la fin du script. Pour ajouter des variables d’environnement à l’échelle du système, ajoutez la variable à /etc/environment. Par exemple, l’instruction suivante ajoute HADOOP_CONF_DIR:

echo "HADOOP_CONF_DIR=/etc/hadoop/conf" | sudo tee -a /etc/environment

Accès aux emplacements où sont stockés les scripts personnalisés

Les scripts utilisés pour personnaliser un cluster doivent être stockés dans l’un des emplacements suivants :

  • Un compte stockage Azure associé au cluster.

  • Un compte de stockage supplémentaire associé au cluster.

  • Un URI accessible au public. Par exemple, une URL vers des données stockées sur OneDrive, Dropbox ou un autre service d’hébergement de fichiers.

  • Un compte Azure Data Lake Storage associé au cluster HDInsight. Pour plus d’informations sur l’utilisation d’Azure Data Lake Storage avec HDInsight, voir Quickstart : Configurer des clusters dans HDInsight.

    Note

    Le principal de service utilisé par HDInsight pour accéder à Data Lake Storage doit avoir un accès en lecture au script.

Les ressources utilisées par le script doivent également être accessibles au public.

Le stockage des fichiers dans un compte Stockage Azure ou Azure Data Lake Storage fournit un accès rapide, car tous deux se trouvent sur le réseau Azure.

Note

Le format URI utilisé pour référencer le script varie selon le service utilisé. Pour les comptes de stockage associés au cluster HDInsight, utilisez wasb:// ou wasbs://. Pour les URI lisibles publiquement, utilisez http:// ou https://. Pour Data Lake Storage, utilisez adl://.

Liste de contrôle pour déployer une action de script

Voici les étapes à suivre lors de la préparation du déploiement d’un script :

  • Placez les fichiers contenant les scripts personnalisés dans un endroit accessible par les nœuds du cluster pendant le déploiement. Par exemple, le stockage par défaut du cluster. Les fichiers peuvent également être stockés dans des services d’hébergement accessibles au public.
  • Vérifiez que le script est idempotent. Cela permet d’exécuter le script plusieurs fois sur le même nœud.
  • Utilisez un répertoire temporaire /tmp pour conserver les fichiers téléchargés utilisés par les scripts, puis nettoyez-les après l’exécution des scripts.
  • Si les paramètres au niveau du système d’exploitation ou les fichiers de configuration des services Hadoop sont modifiés, vous pouvez vouloir redémarrer les services HDInsight.

Comment exécuter une action de script

Vous pouvez utiliser des actions de script pour personnaliser les clusters HDInsight en utilisant les méthodes suivantes :

  • Azure portal
  • Azure PowerShell
  • Modèles Azure Resource Manager
  • Le SDK .NET HDInsight.

Pour plus d’informations sur l’utilisation de chaque méthode, voir Comment utiliser l’action script.

Exemples de scripts personnalisés

Microsoft propose des scripts d’exemple pour installer des composants sur un cluster HDInsight. Voir Installer et utiliser Hue sur les clusters HDInsight comme exemple d’action de script.

Troubleshooting

Voici des erreurs que vous pourriez rencontrer en utilisant des scripts que vous avez développés :

Erreur : $'\r': command not found. Parfois suivie de syntax error: unexpected end of file.

Cause : Cette erreur survient lorsque les lignes d’un script se terminent par CRLF. Les systèmes Unix utilisent uniquement LF comme fin de ligne.

Ce problème survient le plus souvent lorsque le script est créé sur un environnement Windows, car CRLF est une fin de ligne courante pour de nombreux éditeurs de texte sous Windows.

Résolution : Si c’est une option dans votre éditeur de texte, sélectionnez le format Unix ou LF pour la fin de la ligne. Vous pouvez également utiliser les commandes suivantes sur un système Unix pour changer le CRLF en LF :

Note

Les commandes suivantes sont à peu près équivalentes en ce qu’elles devraient changer les fins de ligne CRLF en LF. Sélectionnez-en un en fonction des utilitaires disponibles sur votre système.

Command Notes
unix2dos -b INFILE Le fichier original est sauvegardé avec une extension . BAK
tr -d '\r' < INFILE > OUTFILE OUTFILE contient une version avec uniquement des terminaisons LF
perl -pi -e 's/\r\n/\n/g' INFILE Modifie directement le fichier
sed 's/$'"/`echo \\\r`/" INFILE > OUTFILE OUTFILE contient une version avec uniquement des terminaisons LF.

Erreur : line 1: #!/usr/bin/env: No such file or directory.

Cause : Cette erreur survient lorsque le script a été enregistré en UTF-8 avec un Byte Order Mark (BOM).

Résolution : Sauvegardez le fichier soit en ASCII, soit en UTF-8 sans BOM. Vous pouvez également utiliser la commande suivante sur un système Linux ou Unix pour créer un fichier sans la marque d’ordre des octets (BOM) :

awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE

Remplacez INFILE par le fichier contenant la marque d’ordre d’octet. OUTFILE doit être un nouveau nom de fichier contenant le script sans la nomenclature.

Étapes suivantes