Partilhar via


Desenvolvimento de ações de script com o HDInsight

Saiba como personalizar seu cluster HDInsight usando scripts Bash. As ações de script são uma maneira de personalizar o HDInsight durante ou após a criação do cluster.

O que são ações de script

As ações de script são scripts Bash que o Azure executa nos nós do cluster para fazer alterações de configuração ou instalar software. Uma ação de script é executada como raiz e fornece direitos de acesso total aos nós do cluster.

As ações de script podem ser aplicadas através dos seguintes métodos:

Use este método para aplicar um script... Durante a criação do cluster... Em um cluster em execução...
Portal do Azure
Azure PowerShell
CLI Clássica do Azure  
SDK de .NET do HDInsight
Modelo do Azure Resource Manager  

Para obter mais informações sobre como usar esses métodos para aplicar ações de script, consulte Personalizar clusters HDInsight usando ações de script.

Práticas recomendadas para desenvolvimento de scripts

Quando você desenvolve um script personalizado para um cluster HDInsight, há várias práticas recomendadas a serem lembradas:

Importante

As ações de script devem ser concluídas dentro de 60 minutos ou o processo falhará. Durante o provisionamento do nó, o script é executado simultaneamente com outros processos de instalação e configuração. A competição por recursos como tempo de CPU ou largura de banda de rede pode fazer com que o script demore mais para ser concluído do que em seu ambiente de desenvolvimento.

Direcionar a versão do Apache Hadoop

Versões diferentes do HDInsight têm versões diferentes dos serviços e componentes do Hadoop instalados. Se o script espera uma versão específica de um serviço ou componente, você só deve usar o script com a versão do HDInsight que inclui os componentes necessários. Você pode encontrar informações sobre as versões de componentes incluídas no HDInsight usando o documento de controle de versão de componentes do HDInsight.

Verificando a versão do sistema operacional

Diferentes versões do HDInsight dependem de versões específicas do Ubuntu. Pode haver diferenças entre as versões do sistema operacional que você deve verificar em seu script. Por exemplo, você pode precisar instalar um binário que está vinculado à versão do Ubuntu.

Para verificar a versão do SO, utilize lsb_release. Por exemplo, o script a seguir demonstra como fazer referência a um arquivo tar específico, dependendo da versão do sistema operacional:

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

Direcionar a versão do sistema operacional

O HDInsight é baseado na distribuição Ubuntu Linux. Diferentes versões do HDInsight dependem de diferentes versões do Ubuntu, o que pode mudar o comportamento do seu script. Por exemplo, o HDInsight 3.4 e versões anteriores são baseados em versões do Ubuntu que usam Upstart. As versões 3.5 e superiores são baseadas no Ubuntu 16.04, que usa Systemd. Systemd e Upstart dependem de comandos diferentes, então seu script deve ser escrito para funcionar com ambos.

Outra diferença importante entre o HDInsight 3.4 e 3.5 é que JAVA_HOME agora aponta para o Java 8. O código a seguir demonstra como determinar se o script está sendo executado no 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

Você pode encontrar o script completo que contém esses trechos em https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh.

Para obter a versão do Ubuntu usada pelo HDInsight, consulte o documento de versão do componente HDInsight.

Para entender as diferenças entre Systemd e Upstart, consulte Systemd para usuários Upstart.

Fornecer links estáveis para recursos de script

O script e os recursos associados devem permanecer disponíveis durante todo o tempo de vida do cluster. Esses recursos são necessários se novos nós forem adicionados ao cluster durante as operações de dimensionamento.

A prática recomendada é baixar e arquivar tudo em uma conta de Armazenamento do Azure em sua assinatura.

Importante

A conta de armazenamento usada deve ser a conta de armazenamento padrão para o cluster ou um contêiner público somente leitura em qualquer outra conta de armazenamento.

Por exemplo, os exemplos fornecidos pela Microsoft são armazenados na conta de https://hdiconfigactions.blob.core.windows.net/ armazenamento. Esse local é um contêiner público somente leitura mantido pela equipe do HDInsight.

Usar recursos pré-compilados

Para reduzir o tempo necessário para executar o script, evite operações que compilam recursos do código-fonte. Por exemplo, pré-compile recursos e armazene-os em um blob de conta do Armazenamento do Azure no mesmo data center do HDInsight.

Verifique se o script de personalização do cluster é idempotente

Os scripts devem ser idempotentes. Se o script for executado várias vezes, ele deverá retornar o cluster ao mesmo estado todas as vezes.

Se o script for executado várias vezes, o script que modifica os arquivos de configuração não deverá adicionar entradas duplicadas.

Garantir alta disponibilidade da arquitetura de cluster

Os clusters HDInsight baseados em Linux fornecem dois nós principais que estão ativos dentro do cluster e as ações de script são executadas em ambos os nós. Se os componentes instalados esperarem apenas um nó principal, não instale os componentes em ambos os nós principais.

Importante

Os serviços fornecidos como parte do HDInsight são projetados para failover entre os dois nós principais, conforme necessário. Essa funcionalidade não é estendida a componentes personalizados instalados por meio de ações de script. Se você precisar de alta disponibilidade para componentes personalizados, deverá implementar seu próprio mecanismo de failover.

Configurar os componentes personalizados para usar o armazenamento de Blob do Azure

Os componentes instalados no cluster podem ter uma configuração padrão que usa o armazenamento Apache Hadoop Distributed File System (HDFS). O HDInsight usa o Armazenamento do Azure ou o Armazenamento Data Lake como o armazenamento padrão. Ambos fornecem um sistema de arquivos compatível com HDFS que persiste os dados mesmo se o cluster for excluído. Talvez seja necessário configurar os componentes instalados para usar WASB ou ADL em vez de HDFS.

Para a maioria das operações, não é necessário especificar o sistema de arquivos. Por exemplo, o seguinte copia o arquivo hadoop-common.jar do sistema de arquivos local para o armazenamento em cluster:

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

Neste exemplo, o hdfs comando usa de forma transparente o armazenamento de cluster padrão. Para algumas operações, talvez seja necessário especificar o URI. Por exemplo, adl:///example/jars para o Azure Data Lake Storage Gen1, abfs:///example/jars para o Data Lake Storage Gen2 ou wasb:///example/jars para o Armazenamento do Azure.

Escreva informações para STDOUT e STDERR

O HDInsight registra a saída de script gravada em STDOUT e STDERR. Você pode visualizar essas informações usando a interface do usuário da Web do Ambari.

Nota

O Apache Ambari só estará disponível se o cluster for criado com êxito. Se você usar uma ação de script durante a criação do cluster e a criação falhar, consulte Solucionar problemas de ações de script para outras maneiras de acessar informações registradas.

A maioria dos utilitários e pacotes de instalação já gravam informações em STDOUT e STDERR, no entanto, você pode querer adicionar log adicional. Para enviar texto para STDOUT, use echo. Por exemplo:

echo "Getting ready to install Foo"

Por padrão, echo envia a cadeia de caracteres para STDOUT. Para direcioná-lo para STDERR, adicione >&2 antes de echo. Por exemplo:

>&2 echo "An error occurred installing Foo"

Em vez disso, redireciona as informações gravadas para STDOUT para STDERR (2). Para obter mais informações sobre o redirecionamento de E/S, consulte https://www.tldp.org/LDP/abs/html/io-redirection.html.

Para obter mais informações sobre como exibir informações registradas por ações de script, consulte Solucionar problemas de ações de script.

Salvar arquivos como ASCII com terminações de linha LF

Os scripts Bash devem ser armazenados no formato ASCII, com linhas terminadas por LF. Arquivos armazenados como UTF-8 ou usar CRLF como terminação de linha podem falhar com o seguinte erro:

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

Use a lógica de repetição para se recuperar de erros transitórios

Quando você baixa arquivos, instala pacotes usando apt-get ou outras ações que transmitem dados pela internet, a ação pode falhar devido a erros de rede transitórios. Por exemplo, o recurso remoto com o qual você está se comunicando pode estar em processo de failover para um nó de backup.

Para tornar seu script resiliente a erros transitórios, você pode implementar a lógica de repetição. A função a seguir demonstra como implementar a lógica de repetição. Ele tenta novamente a operação três vezes antes de falhar.

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

Os exemplos a seguir demonstram como usar essa função.

retry ls -ltr foo

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

Métodos auxiliares para scripts personalizados

Os métodos auxiliares de ação de script são utilitários que você pode usar ao escrever scripts personalizados. Esses métodos estão contidos no https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh script. Use o seguinte para baixá-los e usá-los como parte do seu 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

Os seguintes auxiliares disponíveis para uso em seu script:

Utilização do ajudante Description
download_file SOURCEURL DESTFILEPATH [OVERWRITE] Baixa um arquivo do URI de origem para o caminho do arquivo especificado. Por padrão, ele não substitui um arquivo existente.
untar_file TARFILE DESTDIR Extrai um arquivo tar (usando -xf) para o diretório de destino.
test_is_headnode Se o script foi executado em um nó principal de cluster, retorne 1; caso contrário, 0.
test_is_datanode Se o nó atual for um nó de dados (trabalhador), retorne um 1; caso contrário, 0.
test_is_first_datanode Se o nó atual for o primeiro nó de dados (trabalhador) (chamado workernode0) retornará um 1; caso contrário, 0.
get_headnodes Retornar o nome de domínio totalmente qualificado dos nós principais no cluster. Os nomes são delimitados por vírgula. Uma cadeia de caracteres vazia é retornada em caso de erro.
get_primary_headnode Obtém o nome de domínio totalmente qualificado do nó principal. Uma cadeia de caracteres vazia é retornada em caso de erro.
get_secondary_headnode Obtém o nome de domínio totalmente qualificado do nó principal secundário. Uma cadeia de caracteres vazia é retornada em caso de erro.
get_primary_headnode_number Obtém o sufixo numérico do nó principal primário. Uma cadeia de caracteres vazia é retornada em caso de erro.
get_secondary_headnode_number Obtém o sufixo numérico do nó principal secundário. Uma cadeia de caracteres vazia é retornada em caso de erro.

Padrões de utilização comuns

Esta seção fornece orientação sobre como implementar alguns dos padrões de uso comuns que você pode encontrar ao escrever seu próprio script personalizado.

Passando parâmetros para um script

Em alguns casos, o script pode exigir parâmetros. Por exemplo, você pode precisar da senha de administrador para o cluster ao usar a API REST do Ambari.

Os parâmetros passados para o script são conhecidos como parâmetros posicionais e são atribuídos para $1 o primeiro parâmetro, $2 para o segundo e assim por diante. $0 contém o nome do próprio script.

Os valores passados para o script como parâmetros devem ser colocados entre aspas simples ('). Isso garante que o valor passado seja tratado como um literal.

Definindo variáveis de ambiente

A definição de uma variável de ambiente é executada pela seguinte instrução:

VARIABLENAME=value

No exemplo anterior, VARIABLENAME é o nome da variável. Para acessar a variável, use $VARIABLENAME. Por exemplo, para atribuir um valor fornecido por um parâmetro posicional como uma variável de ambiente chamada PASSWORD, você usaria a seguinte instrução:

PASSWORD=$1

O acesso subsequente à informação poderia então utilizar $PASSWORD.

As variáveis de ambiente definidas no script só existem dentro do escopo do script. Em alguns casos, talvez seja necessário adicionar variáveis de ambiente em todo o sistema que persistirão após a conclusão do script. Para adicionar variáveis de ambiente em todo o sistema, adicione a variável ao /etc/environment. Por exemplo, a seguinte instrução adiciona:HADOOP_CONF_DIR

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

Acesso a locais onde os scripts personalizados são armazenados

Os scripts usados para personalizar um cluster precisam ser armazenados em um dos seguintes locais:

  • Uma conta de Armazenamento do Azure associada ao cluster.

  • Uma conta de armazenamento adicional associada ao cluster.

  • Um URI legível publicamente. Por exemplo, uma URL para dados armazenados no OneDrive, Dropbox ou outro serviço de hospedagem de arquivos.

  • Uma conta do Armazenamento do Azure Data Lake associada ao cluster HDInsight. Para obter mais informações sobre como usar o Armazenamento do Azure Data Lake com o HDInsight, consulte Guia de início rápido: configurar clusters no HDInsight.

    Nota

    A entidade de serviço que o HDInsight usa para acessar o Armazenamento Data Lake deve ter acesso de leitura ao script.

Os recursos usados pelo script também devem estar disponíveis publicamente.

Armazenar os arquivos em uma conta de Armazenamento do Azure ou no Armazenamento do Azure Data Lake fornece acesso rápido, como ambos na rede do Azure.

Nota

O formato URI usado para fazer referência ao script difere dependendo do serviço que está sendo usado. Para contas de armazenamento associadas ao cluster HDInsight, use wasb:// ou wasbs://. Para URIs legíveis publicamente, use http:// ou https://. Para o Armazenamento Data Lake, use adl://.

Lista de verificação para implantar uma ação de script

Aqui estão as etapas executadas ao se preparar para implantar um script:

  • Coloque os arquivos que contêm os scripts personalizados em um local acessível pelos nós do cluster durante a implantação. Por exemplo, o armazenamento padrão para o cluster. Os arquivos também podem ser armazenados em serviços de hospedagem legíveis publicamente.
  • Verifique se o script é idempotente. Isso permite que o script seja executado várias vezes no mesmo nó.
  • Use um diretório de arquivo temporário /tmp para manter os arquivos baixados usados pelos scripts e, em seguida, limpá-los após a execução dos scripts.
  • Se as configurações no nível do sistema operacional ou os arquivos de configuração do serviço Hadoop forem alterados, convém reiniciar os serviços do HDInsight.

Como executar uma ação de script

Você pode usar ações de script para personalizar clusters HDInsight usando os seguintes métodos:

  • Portal do Azure
  • Azure PowerShell
  • Modelos do Azure Resource Manager
  • O SDK do HDInsight .NET.

Para obter mais informações sobre como usar cada método, consulte Como usar a ação de script.

Exemplos de script personalizados

A Microsoft fornece scripts de exemplo para instalar componentes em um cluster HDInsight. Consulte Instalar e usar o Hue em clusters HDInsight como um exemplo de ação de script.

Resolução de Problemas

A seguir estão os erros que você pode encontrar ao usar scripts que você desenvolveu:

Erro: $'\r': command not found. Às vezes seguido por syntax error: unexpected end of file.

Causa: Este erro é causado quando as linhas em um script terminam com CRLF. Os sistemas Unix esperam apenas LF como o final da linha.

Esse problema ocorre com mais freqüência quando o script é criado em um ambiente Windows, como CRLF é uma terminação de linha comum para muitos editores de texto no Windows.

Resolução: Se for uma opção no seu editor de texto, selecione o formato Unix ou LF para o final da linha. Você também pode usar os seguintes comandos em um sistema Unix para alterar a CRLF para um LF:

Nota

Os comandos a seguir são aproximadamente equivalentes, pois devem alterar as terminações de linha CRLF para LF. Selecione um com base nos utilitários disponíveis no seu sistema.

Comando Notas
unix2dos -b INFILE O backup do arquivo original é feito com um arquivo . Extensão BAK
tr -d '\r' < INFILE > OUTFILE OUTFILE contém uma versão com apenas terminações LF
perl -pi -e 's/\r\n/\n/g' INFILE Modifica o arquivo diretamente
sed 's/$'"/`echo \\\r`/" INFILE > OUTFILE OUTFILE contém uma versão com apenas terminações LF.

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

Causa: Este erro ocorre quando o script foi salvo como UTF-8 com uma marca de ordem de bytes (BOM).

Resolução: salve o arquivo como ASCII ou UTF-8 sem uma lista técnica. Você também pode usar o seguinte comando em um sistema Linux ou Unix para criar um arquivo sem a BOM:

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

Substitua INFILE pelo arquivo que contém a lista técnica. OUTFILE deve ser um novo nome de arquivo, que contém o script sem a lista técnica.

Próximos passos