Programowanie akcji skryptu w usłudze HDInsight

Dowiedz się, jak dostosować klaster usługi HDInsight przy użyciu skryptów powłoki Bash. Akcje skryptu to sposób dostosowywania usługi HDInsight podczas tworzenia klastra lub po jego utworzeniu.

Co to są akcje skryptu

Akcje skryptu to skrypty powłoki Bash uruchamiane na węzłach klastra w celu wprowadzenia zmian konfiguracji lub zainstalowania oprogramowania. Akcja skryptu jest wykonywana jako katalog główny i zapewnia pełne prawa dostępu do węzłów klastra.

Akcje skryptu można stosować za pomocą następujących metod:

Użyj tej metody, aby zastosować skrypt... Podczas tworzenia klastra... W uruchomionym klastrze...
Azure Portal
Azure PowerShell
Klasyczny interfejs wiersza polecenia platformy Azure  
HDInsight .NET SDK
Szablon usługi Azure Resource Manager  

Aby uzyskać więcej informacji na temat używania tych metod do stosowania akcji skryptu, zobacz Dostosowywanie klastrów usługi HDInsight przy użyciu akcji skryptu.

Najlepsze rozwiązania dotyczące tworzenia skryptów

Podczas tworzenia niestandardowego skryptu dla klastra usługi HDInsight należy pamiętać o kilku najlepszych rozwiązaniach:

Ważne

Akcje skryptu muszą zostać wykonane w ciągu 60 minut lub proces zakończy się niepowodzeniem. Podczas aprowizacji węzła skrypt jest uruchamiany współbieżnie z innymi procesami konfiguracji i konfiguracji. Rywalizacja o zasoby, takie jak czas procesora CPU lub przepustowość sieci, może spowodować, że ukończenie skryptu trwa dłużej niż w środowisku projektowym.

Określanie docelowej wersji platformy Apache Hadoop

Różne wersje usługi HDInsight mają zainstalowane różne wersje usług Hadoop i składników. Jeśli skrypt oczekuje określonej wersji usługi lub składnika, należy użyć skryptu tylko z wersją usługi HDInsight, która zawiera wymagane składniki. Informacje na temat wersji składników zawartych w usłudze HDInsight można znaleźć w dokumencie przechowywania wersji składników usługi HDInsight .

Sprawdzanie wersji systemu operacyjnego

Różne wersje usługi HDInsight opierają się na określonych wersjach systemu Ubuntu. Mogą występować różnice między wersjami systemu operacyjnego, które należy zaewidencjonować w skrycie. Na przykład może być konieczne zainstalowanie pliku binarnego powiązanego z wersją systemu Ubuntu.

Aby sprawdzić wersję systemu operacyjnego, użyj polecenia lsb_release. Na przykład poniższy skrypt pokazuje, jak odwoływać się do określonego pliku tar w zależności od wersji systemu operacyjnego:

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

Określanie docelowej wersji systemu operacyjnego

Usługa HDInsight jest oparta na dystrybucji systemu Ubuntu Linux. Różne wersje usługi HDInsight korzystają z różnych wersji systemu Ubuntu, co może zmienić sposób działania skryptu. Na przykład usługa HDInsight 3.4 i starsze są oparte na wersjach systemu Ubuntu korzystających z programu Upstart. Wersje 3.5 i nowsze są oparte na systemie Ubuntu 16.04, który korzysta z systemu. Systemd i Upstart opierają się na różnych poleceniach, więc skrypt powinien być napisany w celu pracy z obydwoma.

Kolejną ważną różnicą między usługą HDInsight 3.4 i 3.5 jest to, że JAVA_HOME teraz wskazuje na środowisko Java 8. Poniższy kod pokazuje, jak określić, czy skrypt jest uruchomiony w systemie Ubuntu 14 lub 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

Pełny skrypt zawierający te fragmenty kodu można znaleźć pod adresem https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh.

Aby zapoznać się z wersją systemu Ubuntu używaną przez usługę HDInsight, zobacz dokument wersja składnika usługi HDInsight .

Aby zrozumieć różnice między systemem i startem, zobacz Systemd for Upstart users (Systemd for Upstart users).

Zapewnianie stabilnych linków do zasobów skryptu

Skrypt i skojarzone zasoby muszą pozostać dostępne przez cały okres istnienia klastra. Te zasoby są wymagane, jeśli nowe węzły są dodawane do klastra podczas operacji skalowania.

Najlepszym rozwiązaniem jest pobranie i archiwizowanie wszystkich elementów na koncie usługi Azure Storage w ramach subskrypcji.

Ważne

Używane konto magazynu musi być domyślnym kontem magazynu dla klastra lub publicznego kontenera tylko do odczytu na dowolnym innym koncie magazynu.

Na przykład przykłady dostarczone przez firmę Microsoft są przechowywane na koncie https://hdiconfigactions.blob.core.windows.net/ magazynu. Ta lokalizacja jest publicznym kontenerem tylko do odczytu obsługiwanym przez zespół usługi HDInsight.

Używanie wstępnie skompilowanych zasobów

Aby skrócić czas potrzebny na uruchomienie skryptu, należy unikać operacji kompilujących zasoby z kodu źródłowego. Na przykład wstępnie skompiluj zasoby i zapisz je w obiekcie blob konta usługi Azure Storage w tym samym centrum danych co usługa HDInsight.

Upewnij się, że skrypt dostosowywania klastra jest idempotentny

Skrypty muszą być idempotentne. Jeśli skrypt jest uruchamiany wiele razy, powinien zwrócić klaster do tego samego stanu za każdym razem.

Na przykład skrypt modyfikujący pliki konfiguracji nie powinien dodawać zduplikowanych wpisów w przypadku wielokrotnego uruchomienia.

Zapewnianie wysokiej dostępności architektury klastra

Klastry usługi HDInsight oparte na systemie Linux zapewniają dwa węzły główne, które są aktywne w klastrze, a akcje skryptu są uruchamiane w obu węzłach. Jeśli instalowane składniki oczekują tylko jednego węzła głównego, nie instaluj składników w obu węzłach głównych.

Ważne

Usługi udostępniane w ramach usługi HDInsight są przeznaczone do przełączania w tryb failover między dwoma węzłami głównymi zgodnie z potrzebami. Ta funkcja nie jest rozszerzana na składniki niestandardowe zainstalowane za pomocą akcji skryptu. Jeśli potrzebujesz wysokiej dostępności dla składników niestandardowych, musisz zaimplementować własny mechanizm trybu failover.

Konfigurowanie składników niestandardowych do korzystania z usługi Azure Blob Storage

Składniki instalowane w klastrze mogą mieć domyślną konfigurację korzystającą z magazynu rozproszonego systemu plików Apache Hadoop (HDFS). Usługa HDInsight używa usługi Azure Storage lub Data Lake Storage jako magazynu domyślnego. Oba zapewniają zgodny z systemem plików HDFS system plików, który utrwala dane, nawet jeśli klaster zostanie usunięty. Może być konieczne skonfigurowanie składników instalowanych w celu korzystania z usługi WASB lub ADL zamiast systemu plików HDFS.

W przypadku większości operacji nie trzeba określać systemu plików. Na przykład następujące kopie pliku hadoop-common.jar z lokalnego systemu plików do magazynu klastra:

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

W tym przykładzie hdfs polecenie w sposób niewidoczny używa domyślnego magazynu klastra. W przypadku niektórych operacji może być konieczne określenie identyfikatora URI. Na przykład adl:///example/jars w przypadku Azure Data Lake Storage Gen1 abfs:///example/jars dla Data Lake Storage Gen2 lub wasb:///example/jars usługi Azure Storage.

Zapisywanie informacji na temat STDOUT i STDERR

Usługa HDInsight rejestruje dane wyjściowe skryptu zapisywane w usługach STDOUT i STDERR. Te informacje można wyświetlić przy użyciu internetowego interfejsu użytkownika systemu Ambari.

Uwaga

Narzędzie Apache Ambari jest dostępne tylko w przypadku pomyślnego utworzenia klastra. Jeśli używasz akcji skryptu podczas tworzenia klastra i tworzenie zakończy się niepowodzeniem, zobacz Rozwiązywanie problemów z akcjami skryptu , aby uzyskać dostęp do zarejestrowanych informacji.

Większość narzędzi i pakietów instalacyjnych już zapisuje informacje w plikach STDOUT i STDERR, jednak warto dodać dodatkowe rejestrowanie. Aby wysłać tekst do elementu STDOUT, użyj polecenia echo. Przykład:

echo "Getting ready to install Foo"

Domyślnie echo wysyła ciąg do wartości STDOUT. Aby skierować go do narzędzia STDERR, dodaj >&2 element przed echo. Przykład:

>&2 echo "An error occurred installing Foo"

Spowoduje to przekierowanie informacji zapisanych do stDOUT do stDERR (2) zamiast tego. Aby uzyskać więcej informacji na temat przekierowywania we/wy, zobacz https://www.tldp.org/LDP/abs/html/io-redirection.html.

Aby uzyskać więcej informacji na temat wyświetlania informacji rejestrowanych przez akcje skryptu, zobacz Rozwiązywanie problemów z akcjami skryptu.

Zapisywanie plików jako ASCII z końcami wierszy LF

Skrypty powłoki Bash powinny być przechowywane jako format ASCII z wierszami zakończonymi przez LF. Pliki, które są przechowywane jako UTF-8 lub używają crLF jako zakończenie wiersza, może zakończyć się niepowodzeniem z powodu następującego błędu:

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

Używanie logiki ponawiania prób w celu odzyskania sprawności po błędach przejściowych

Podczas pobierania plików, instalowania pakietów przy użyciu polecenia apt-get lub innych akcji, które przesyłają dane przez Internet, akcja może zakończyć się niepowodzeniem z powodu przejściowych błędów sieciowych. Na przykład zasób zdalny, z którym komunikujesz się, może być w trakcie przechodzenia w tryb failover do węzła kopii zapasowej.

Aby skrypt był odporny na błędy przejściowe, można zaimplementować logikę ponawiania prób. Poniższa funkcja pokazuje, jak zaimplementować logikę ponawiania prób. Ponawia próbę wykonania operacji trzy razy przed niepowodzeniem.

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

W poniższych przykładach pokazano, jak używać tej funkcji.

retry ls -ltr foo

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

Metody pomocnika dla skryptów niestandardowych

Metody pomocnika akcji skryptu to narzędzia, których można używać podczas pisania skryptów niestandardowych. Te metody są zawarte w skry skrycie https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh . Użyj poniższych instrukcji, aby pobrać je i użyć w ramach skryptu:

# 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

Następujący pomocnicy dostępni do użycia w skry skrycie:

Użycie pomocnika Opis
download_file SOURCEURL DESTFILEPATH [OVERWRITE] Pobiera plik ze źródłowego identyfikatora URI do określonej ścieżki pliku. Domyślnie nie zastępuje istniejącego pliku.
untar_file TARFILE DESTDIR Wyodrębnia plik tar (przy użyciu polecenia -xf) do katalogu docelowego.
test_is_headnode Jeśli skrypt został uruchomiony w węźle głównym klastra, zwróć wartość 1; w przeciwnym razie, 0.
test_is_datanode Jeśli bieżący węzeł jest węzłem danych (proces roboczy), zwróć wartość 1; w przeciwnym razie, 0.
test_is_first_datanode Jeśli bieżący węzeł jest pierwszym węzłem danych (proces roboczy) (o nazwie workernode0) zwraca wartość 1; w przeciwnym razie, 0.
get_headnodes Zwróć w pełni kwalifikowaną nazwę domeny węzłów głównych w klastrze. Nazwy są rozdzielane przecinkami. Pusty ciąg jest zwracany po błędzie.
get_primary_headnode Pobiera w pełni kwalifikowaną nazwę domeny podstawowego węzła głównego. Pusty ciąg jest zwracany po błędzie.
get_secondary_headnode Pobiera w pełni kwalifikowaną nazwę domeny pomocniczego węzła głównego. Pusty ciąg jest zwracany po błędzie.
get_primary_headnode_number Pobiera sufiks liczbowy podstawowego węzła głównego. Pusty ciąg jest zwracany po błędzie.
get_secondary_headnode_number Pobiera sufiks liczbowy pomocniczego węzła głównego. Pusty ciąg jest zwracany po błędzie.

Typowe wzorce użycia

Ta sekcja zawiera wskazówki dotyczące implementowania niektórych typowych wzorców użycia, które mogą wystąpić podczas pisania własnego skryptu niestandardowego.

Przekazywanie parametrów do skryptu

W niektórych przypadkach skrypt może wymagać parametrów. Na przykład w przypadku korzystania z interfejsu API REST ambari może być konieczne hasło administratora klastra.

Parametry przekazywane do skryptu są znane jako parametry pozycyjne i są przypisywane do $1 pierwszego parametru, $2 dla drugiego i tak dalej. $0 zawiera nazwę samego skryptu.

Wartości przekazywane do skryptu jako parametry powinny być ujęte w apostrofy ('). Dzięki temu przekazana wartość jest traktowana jako literał.

Ustawianie zmiennych środowiskowych

Ustawienie zmiennej środowiskowej jest wykonywane przez następującą instrukcję:

VARIABLENAME=value

W poprzednim przykładzie VARIABLENAME jest nazwą zmiennej. Aby uzyskać dostęp do zmiennej, użyj polecenia $VARIABLENAME. Aby na przykład przypisać wartość dostarczaną przez parametr pozycyjny jako zmienną środowiskową o nazwie PASSWORD, należy użyć następującej instrukcji:

PASSWORD=$1

Następnie można użyć dostępu $PASSWORDdo informacji .

Zmienne środowiskowe ustawione w skrycie istnieją tylko w zakresie skryptu. W niektórych przypadkach może być konieczne dodanie zmiennych środowiskowych dla całego systemu, które będą utrwalane po zakończeniu działania skryptu. Aby dodać zmienne środowiskowe dla całego systemu, dodaj zmienną do /etc/environmentzmiennej . Na przykład następująca instrukcja dodaje polecenie HADOOP_CONF_DIR:

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

Dostęp do lokalizacji, w których są przechowywane skrypty niestandardowe

Skrypty używane do dostosowywania klastra muszą być przechowywane w jednej z następujących lokalizacji:

  • Konto usługi Azure Storage skojarzone z klastrem.

  • Dodatkowe konto magazynu skojarzone z klastrem.

  • Publicznie czytelny identyfikator URI. Na przykład adres URL danych przechowywanych w usłudze OneDrive, Dropbox lub innej usłudze hostingu plików.

  • Konto Azure Data Lake Storage skojarzone z klastrem usługi HDInsight. Aby uzyskać więcej informacji na temat używania Azure Data Lake Storage z usługą HDInsight, zobacz Szybki start: konfigurowanie klastrów w usłudze HDInsight.

    Uwaga

    Jednostka usługi HDInsight używa dostępu do Data Lake Storage musi mieć dostęp do odczytu do skryptu.

Zasoby używane przez skrypt muszą być również publicznie dostępne.

Przechowywanie plików na koncie usługi Azure Storage lub Azure Data Lake Storage zapewnia szybki dostęp w ramach sieci platformy Azure.

Uwaga

Format identyfikatora URI używany do odwoływanie się do skryptu różni się w zależności od używanej usługi. W przypadku kont magazynu skojarzonych z klastrem usługi HDInsight użyj polecenia wasb:// lub wasbs://. W przypadku publicznie czytelnych identyfikatorów URI użyj polecenia http:// lub https://. W przypadku Data Lake Storage użyj polecenia adl://.

Lista kontrolna wdrażania akcji skryptu

Poniżej przedstawiono kroki wykonywane podczas przygotowywania do wdrożenia skryptu:

  • Umieść pliki zawierające skrypty niestandardowe w miejscu dostępnym dla węzłów klastra podczas wdrażania. Na przykład domyślny magazyn dla klastra. Pliki mogą być również przechowywane w publicznie czytelnych usługach hostingu.
  • Sprawdź, czy skrypt jest idempotentny. Dzięki temu skrypt może być wykonywany wiele razy w tym samym węźle.
  • Użyj katalogu plików tymczasowych /tmp, aby zachować pobrane pliki używane przez skrypty, a następnie wyczyścić je po wykonaniu skryptów.
  • Jeśli ustawienia na poziomie systemu operacyjnego lub pliki konfiguracji usługi Hadoop zostaną zmienione, warto ponownie uruchomić usługi HDInsight.

Jak uruchomić akcję skryptu

Za pomocą akcji skryptu można dostosować klastry usługi HDInsight przy użyciu następujących metod:

  • Azure Portal
  • Azure PowerShell
  • Szablony usługi Azure Resource Manager
  • Zestaw .NET SDK usługi HDInsight.

Aby uzyskać więcej informacji na temat korzystania z każdej metody, zobacz How to use script action (Jak używać akcji skryptu).

Przykłady skryptów niestandardowych

Firma Microsoft udostępnia przykładowe skrypty do instalowania składników w klastrze usługi HDInsight. Zobacz Instalowanie i używanie platformy Hue w klastrach usługi HDInsight jako przykładowej akcji skryptu.

Rozwiązywanie problemów

Poniżej przedstawiono błędy, które mogą wystąpić podczas używania utworzonych skryptów:

Błąd: $'\r': command not found. Czasami następuje ciąg syntax error: unexpected end of file.

Przyczyna: ten błąd jest spowodowany tym, że wiersze w skrycie kończą się znakiem CRLF. Systemy Unix oczekują tylko LF jako zakończenia linii.

Ten problem występuje najczęściej, gdy skrypt jest utworzony w środowisku systemu Windows, ponieważ CRLF jest typowym wierszem kończącym się dla wielu edytorów tekstów w systemie Windows.

Rozwiązanie: jeśli jest to opcja w edytorze tekstów, wybierz pozycję Format systemu Unix lub LF dla zakończenia wiersza. Możesz również użyć następujących poleceń w systemie Unix, aby zmienić CRLF na LF:

Uwaga

Następujące polecenia są w przybliżeniu równoważne, że powinny zmienić zakończenia wiersza CRLF na LF. Wybierz jedną na podstawie narzędzi dostępnych w systemie.

Polecenie Uwagi
unix2dos -b INFILE Kopia zapasowa oryginalnego pliku jest tworzona za pomocą polecenia . Rozszerzenie BAK
tr -d '\r' < INFILE > OUTFILE OUTFILE zawiera wersję zawierającą tylko zakończenia LF
perl -pi -e 's/\r\n/\n/g' INFILE Modyfikuje plik bezpośrednio
sed 's/$'"/`echo \\\r`/" INFILE > OUTFILE OUTFILE zawiera wersję z tylko zakończeniami LF.

Błąd: line 1: #!/usr/bin/env: No such file or directory.

Przyczyna: ten błąd występuje, gdy skrypt został zapisany jako UTF-8 z znakiem zamówienia bajtów (BOM).

Rozwiązanie: zapisz plik jako ASCII lub UTF-8 bez modelu BOM. Możesz również użyć następującego polecenia w systemie Linux lub Unix, aby utworzyć plik bez modelu BOM:

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

Zastąp INFILE element plikiem zawierającym model BOM. OUTFILE powinna być nową nazwą pliku, która zawiera skrypt bez modelu BOM.

Następne kroki