Utveckling av skriptåtgärder med HDInsight

Lär dig hur du anpassar ditt HDInsight-kluster med hjälp av Bash-skript. Skriptåtgärder är ett sätt att anpassa HDInsight under eller efter skapandet av klustret.

Vad är skriptåtgärder?

Skriptåtgärder är Bash-skript som Azure kör på klusternoderna för att göra konfigurationsändringar eller installera programvara. En skriptåtgärd körs som rot och ger fullständig åtkomstbehörighet till klusternoderna.

Skriptåtgärder kan tillämpas via följande metoder:

Använd den här metoden för att använda ett skript... När klustret skapas... I ett kluster som körs...
Azure Portal
Azure PowerShell
Klassisk Azure CLI  
HDInsight .NET SDK
Azure Resource Manager-mall  

Mer information om hur du använder dessa metoder för att tillämpa skriptåtgärder finns i Anpassa HDInsight-kluster med hjälp av skriptåtgärder.

Metodtips för skriptutveckling

När du utvecklar ett anpassat skript för ett HDInsight-kluster finns det flera metodtips att tänka på:

Viktigt

Skriptåtgärder måste slutföras inom 60 minuter, annars misslyckas processen. Under nodetablering körs skriptet samtidigt med andra konfigurations- och konfigurationsprocesser. Konkurrens om resurser som cpu-tid eller nätverksbandbredd kan göra att skriptet tar längre tid att slutföra än i utvecklingsmiljön.

Rikta in dig på Apache Hadoop-versionen

Olika versioner av HDInsight har olika versioner av Hadoop-tjänster och -komponenter installerade. Om skriptet förväntar sig en viss version av en tjänst eller komponent bör du bara använda skriptet med den version av HDInsight som innehåller nödvändiga komponenter. Du hittar information om komponentversioner som ingår i HDInsight med hjälp av versionsdokumentet för HDInsight-komponenten .

Kontrollera operativsystemversionen

Olika versioner av HDInsight förlitar sig på specifika versioner av Ubuntu. Det kan finnas skillnader mellan operativsystemversioner som du måste söka efter i skriptet. Du kan till exempel behöva installera en binär fil som är kopplad till versionen av Ubuntu.

Om du vill kontrollera os-versionen använder du lsb_release. Följande skript visar till exempel hur du refererar till en specifik tar-fil beroende på operativsystemversionen:

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

Rikta operativsystemets version

HDInsight baseras på Ubuntu Linux-distributionen. Olika versioner av HDInsight förlitar sig på olika versioner av Ubuntu, vilket kan ändra hur skriptet fungerar. HdInsight 3.4 och tidigare baseras till exempel på Ubuntu-versioner som använder Uppstart. Version 3.5 och senare baseras på Ubuntu 16.04, som använder Systemd. Systemd och Upstart förlitar sig på olika kommandon, så skriptet bör skrivas för att fungera med båda.

En annan viktig skillnad mellan HDInsight 3.4 och 3.5 är att det JAVA_HOME nu pekar på Java 8. Följande kod visar hur du avgör om skriptet körs på Ubuntu 14 eller 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

Du hittar det fullständiga skriptet som innehåller dessa kodfragment på https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh.

Den version av Ubuntu som används av HDInsight finns i dokumentet om HDInsight-komponentens version .

Information om skillnaderna mellan Systemd och Upstart finns i Systemd för uppstartsanvändare.

Tillhandahålla stabila länkar till skriptresurser

Skriptet och de associerade resurserna måste vara tillgängliga under hela klustrets livslängd. Dessa resurser krävs om nya noder läggs till i klustret under skalningsåtgärder.

Det bästa sättet är att ladda ned och arkivera allt i ett Azure Storage-konto i din prenumeration.

Viktigt

Lagringskontot som används måste vara standardlagringskontot för klustret eller en offentlig, skrivskyddad container på något annat lagringskonto.

Exempel som tillhandahålls av Microsoft lagras till exempel i lagringskontot https://hdiconfigactions.blob.core.windows.net/ . Den här platsen är en offentlig, skrivskyddad container som underhålls av HDInsight-teamet.

Använda förkompilerade resurser

Undvik åtgärder som kompilerar resurser från källkoden för att minska tiden det tar att köra skriptet. Du kan till exempel förkompilera resurser och lagra dem i en Azure Storage-kontoblob i samma datacenter som HDInsight.

Kontrollera att skriptet för klusteranpassning är idempotent

Skript måste vara idempotent. Om skriptet körs flera gånger bör klustret återgå till samma tillstånd varje gång.

Ett skript som ändrar konfigurationsfiler bör till exempel inte lägga till dubblettposter om det kördes flera gånger.

Säkerställa hög tillgänglighet för klusterarkitekturen

Linux-baserade HDInsight-kluster tillhandahåller två huvudnoder som är aktiva i klustret och skriptåtgärder körs på båda noderna. Om de komponenter du installerar bara förväntar sig en huvudnod ska du inte installera komponenterna på båda huvudnoderna.

Viktigt

Tjänster som tillhandahålls som en del av HDInsight är utformade för att redundansväxla mellan de två huvudnoderna efter behov. Den här funktionen utökas inte till anpassade komponenter som installeras via skriptåtgärder. Om du behöver hög tillgänglighet för anpassade komponenter måste du implementera din egen redundansmekanism.

Konfigurera de anpassade komponenterna så att de använder Azure Blob Storage

Komponenter som du installerar i klustret kan ha en standardkonfiguration som använder HdFS-lagring (Apache Hadoop Distributed File System). HDInsight använder antingen Azure Storage eller Data Lake Storage som standardlagring. Båda tillhandahåller ett HDFS-kompatibelt filsystem som bevarar data även om klustret tas bort. Du kan behöva konfigurera komponenter som du installerar för att använda WASB eller ADL i stället för HDFS.

För de flesta åtgärder behöver du inte ange filsystemet. Följande kopierar till exempel filen hadoop-common.jar från det lokala filsystemet till klusterlagringen:

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

I det här exemplet hdfs använder kommandot transparent standardklusterlagringen. För vissa åtgärder kan du behöva ange URI:n. Till exempel adl:///example/jars för Azure Data Lake Storage Gen1, abfs:///example/jars för Data Lake Storage Gen2 eller wasb:///example/jars för Azure Storage.

Skriva information till STDOUT och STDERR

HDInsight loggar skriptutdata som skrivs till STDOUT och STDERR. Du kan visa den här informationen med hjälp av Ambari-webbgränssnittet.

Anteckning

Apache Ambari är bara tillgängligt om klustret har skapats. Om du använder en skriptåtgärd när klustret skapas och det inte går att skapa klustret kan du läsa Felsöka skriptåtgärder för andra sätt att komma åt loggad information.

De flesta verktyg och installationspaket skriver redan information till STDOUT och STDERR, men du kanske vill lägga till ytterligare loggning. Om du vill skicka text till STDOUT använder du echo. Ett exempel:

echo "Getting ready to install Foo"

Som standard echo skickar strängen till STDOUT. Om du vill dirigera den till STDERR lägger du till >&2 före echo. Ett exempel:

>&2 echo "An error occurred installing Foo"

Detta omdirigerar information som skrivs till STDOUT till STDERR (2) i stället. Mer information om I/O-omdirigering finns i https://www.tldp.org/LDP/abs/html/io-redirection.html.

Mer information om hur du visar information som loggas av skriptåtgärder finns i Felsöka skriptåtgärder.

Spara filer som ASCII med LF-radslut

Bash-skript ska lagras som ASCII-format, med rader som avslutas av LF. Filer som lagras som UTF-8 eller använder CRLF som radslut kan misslyckas med följande fel:

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

Använda omprövningslogik för att återställa från tillfälliga fel

När du laddar ned filer, installerar paket med apt-get eller andra åtgärder som överför data via Internet kan åtgärden misslyckas på grund av tillfälliga nätverksfel. Fjärrresursen som du kommunicerar med kan till exempel vara i färd med att växla över till en säkerhetskopieringsnod.

Om du vill göra skriptet motståndskraftigt mot tillfälliga fel kan du implementera omprövningslogik. Följande funktion visar hur du implementerar omprövningslogik. Den försöker utföra åtgärden igen tre gånger innan den misslyckas.

#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
}

Följande exempel visar hur du använder den här funktionen.

retry ls -ltr foo

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

Hjälpmetoder för anpassade skript

Hjälpmetoder för skriptåtgärder är verktyg som du kan använda när du skriver anpassade skript. Dessa metoder finns i skriptet https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh . Använd följande för att ladda ned och använda dem som en del av skriptet:

# 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

Följande hjälpkomponenter är tillgängliga för användning i skriptet:

Hjälpanvändning Beskrivning
download_file SOURCEURL DESTFILEPATH [OVERWRITE] Laddar ned en fil från käll-URI:n till den angivna filsökvägen. Som standard skriver den inte över en befintlig fil.
untar_file TARFILE DESTDIR Extraherar en tar-fil (med hjälp av -xf) till målkatalogen.
test_is_headnode Om skriptet kördes på en klusterhuvudnod returnerar du 1. annars 0.
test_is_datanode Om den aktuella noden är en datanod (arbetsnod) returnerar du en 1. annars 0.
test_is_first_datanode Om den aktuella noden är den första datanoden (arbetsnoden) (med namnet workernode0) returneras en 1. annars 0.
get_headnodes Returnera det fullständigt kvalificerade domännamnet för huvudnoderna i klustret. Namnen avgränsas med kommatecken. En tom sträng returneras vid fel.
get_primary_headnode Hämtar det fullständigt kvalificerade domännamnet för den primära huvudnoden. En tom sträng returneras vid fel.
get_secondary_headnode Hämtar det fullständigt kvalificerade domännamnet för den sekundära huvudnoden. En tom sträng returneras vid fel.
get_primary_headnode_number Hämtar det numeriska suffixet för den primära huvudnoden. En tom sträng returneras vid fel.
get_secondary_headnode_number Hämtar det numeriska suffixet för den sekundära huvudnoden. En tom sträng returneras vid fel.

Vanliga användningsmönster

Det här avsnittet innehåller vägledning om hur du implementerar några av de vanliga användningsmönster som du kan stöta på när du skriver ett eget anpassat skript.

Skicka parametrar till ett skript

I vissa fall kan skriptet kräva parametrar. Du kan till exempel behöva administratörslösenordet för klustret när du använder Ambari REST API.

Parametrar som skickas till skriptet kallas positionsparametrar och tilldelas till $1 för den första parametern, $2 för den andra och så vidare. $0 innehåller namnet på själva skriptet.

Värden som skickas till skriptet som parametrar ska omges av enkla citattecken ('). Detta säkerställer att det överförda värdet behandlas som en literal.

Ställa in miljövariabler

Inställningen av en miljövariabel utförs med följande instruktion:

VARIABLENAME=value

I föregående exempel VARIABLENAME är namnet på variabeln. Använd för att komma åt variabeln $VARIABLENAME. Om du till exempel vill tilldela ett värde som tillhandahålls av en positionsparameter som en miljövariabel med namnet PASSWORD använder du följande instruktion:

PASSWORD=$1

Efterföljande åtkomst till informationen kan sedan använda $PASSWORD.

Miljövariabler som anges i skriptet finns bara inom skriptets omfång. I vissa fall kan du behöva lägga till systemomfattande miljövariabler som bevaras när skriptet har slutförts. Om du vill lägga till systemomfattande miljövariabler lägger du till variabeln i /etc/environment. Följande instruktion lägger till exempel till HADOOP_CONF_DIR:

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

Åtkomst till platser där de anpassade skripten lagras

Skript som används för att anpassa ett kluster måste lagras på någon av följande platser:

  • Ett Azure Storage-konto som är associerat med klustret.

  • Ytterligare ett lagringskonto som är associerat med klustret.

  • En offentligt läsbar URI. Till exempel en URL till data som lagras på OneDrive, Dropbox eller någon annan filvärdtjänst.

  • Ett Azure Data Lake Storage konto som är associerat med HDInsight-klustret. Mer information om hur du använder Azure Data Lake Storage med HDInsight finns i Snabbstart: Konfigurera kluster i HDInsight.

    Anteckning

    Tjänstens huvudnamn HDInsight använder för att komma åt Data Lake Storage måste ha läsbehörighet till skriptet.

Resurser som används av skriptet måste också vara offentligt tillgängliga.

Lagring av filerna i ett Azure Storage-konto eller Azure Data Lake Storage ger snabb åtkomst, som båda i Azure-nätverket.

Anteckning

Det URI-format som används för att referera till skriptet varierar beroende på vilken tjänst som används. För lagringskonton som är associerade med HDInsight-klustret använder du wasb:// eller wasbs://. För offentligt läsbara URI:er använder du http:// eller https://. För Data Lake Storage använder du adl://.

Checklista för att distribuera en skriptåtgärd

Här följer stegen när du förbereder distributionen av ett skript:

  • Placera filerna som innehåller de anpassade skripten på en plats som är tillgänglig för klusternoderna under distributionen. Till exempel standardlagringen för klustret. Filer kan också lagras i offentligt läsbara värdtjänster.
  • Kontrollera att skriptet är idempotent. På så sätt kan skriptet köras flera gånger på samma nod.
  • Använd en tillfällig filkatalog /tmp för att behålla de nedladdade filerna som används av skripten och rensa dem sedan när skripten har körts.
  • Om inställningarna på operativsystemnivå eller konfigurationsfilerna för Hadoop-tjänsten ändras kanske du vill starta om HDInsight-tjänsterna.

Så här kör du en skriptåtgärd

Du kan använda skriptåtgärder för att anpassa HDInsight-kluster med hjälp av följande metoder:

  • Azure Portal
  • Azure PowerShell
  • Azure Resource Manager-mallar
  • The HDInsight .NET SDK.

Mer information om hur du använder varje metod finns i Så här använder du skriptåtgärd.

Exempel på anpassade skript

Microsoft tillhandahåller exempelskript för att installera komponenter i ett HDInsight-kluster. Se Installera och använda Hue på HDInsight-kluster som ett exempel på en skriptåtgärd.

Felsökning

Följande är fel som du kan stöta på när du använder skript som du har utvecklat:

Fel: $'\r': command not found. Ibland följt av syntax error: unexpected end of file.

Orsak: Det här felet uppstår när raderna i ett skript slutar med CRLF. Unix-system förväntar sig endast LF när linjen slutar.

Det här problemet uppstår oftast när skriptet skapas i en Windows-miljö, eftersom CRLF är en vanlig rad som slutar för många textredigerare i Windows.

Lösning: Om det är ett alternativ i textredigeraren väljer du Unix-format eller LF för radslutet. Du kan också använda följande kommandon i ett Unix-system för att ändra CRLF till en LF:

Anteckning

Följande kommandon är ungefär likvärdiga eftersom de bör ändra CRLF-radsluten till LF. Välj en baserat på de verktyg som är tillgängliga i systemet.

Kommando Kommentarer
unix2dos -b INFILE Den ursprungliga filen säkerhetskopieras med en . BAK-tillägg
tr -d '\r' < INFILE > OUTFILE OUTFILE innehåller en version med endast LF-slut
perl -pi -e 's/\r\n/\n/g' INFILE Ändrar filen direkt
sed 's/$'"/`echo \\\r`/" INFILE > OUTFILE OUTFILE innehåller en version med endast LF-slut.

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

Orsak: Det här felet uppstår när skriptet sparades som UTF-8 med en BOM (Byte Order Mark).

Lösning: Spara filen antingen som ASCII eller som UTF-8 utan bom. Du kan också använda följande kommando i ett Linux- eller Unix-system för att skapa en fil utan BOM:

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

Ersätt INFILE med filen som innehåller bommen. OUTFILE ska vara ett nytt filnamn som innehåller skriptet utan bommen.

Nästa steg