Gestire i cluster HDInsight mediante l'API REST Apache Ambari

Informazioni sull'uso dell'API REST Apache Ambari per gestire e monitorare i cluster Apache Hadoop in Azure HDInsight.

Che cos'è Apache Ambari

Apache Ambari semplifica la gestione e il monitoraggio dei cluster Hadoop offrendo un'interfaccia utente Web facile da usare supportata dalle API REST. Ambari viene fornito per impostazione predefinita con i cluster HDInsight basati su Linux.

Prerequisiti

Identificatore di risorsa uniforme di base per l'API REST di Ambari

L'URI (Uniform Resource Identifier) di base per l'API REST Ambari in HDInsight è https://CLUSTERNAME.azurehdinsight.net/api/v1/clusters/CLUSTERNAME, dove CLUSTERNAME è il nome del cluster. I nomi dei cluster negli URI fanno distinzione tra maiuscole e minuscole. Mentre il nome del cluster nella parte del nome di dominio completo (FQDN) dell'URI (CLUSTERNAME.azurehdinsight.net) non fa distinzione tra maiuscole e minuscole, altre occorrenze nell'URI fanno distinzione tra maiuscole e minuscole.

Authentication

La connessione ad Ambari su HDInsight richiede HTTPS. Usare il nome dell'account amministratore (il valore predefinito è admin) e la password forniti durante la creazione del cluster.

Per i cluster Enterprise Security Package, invece di admin, usare un nome utente completo, ad esempio username@domain.onmicrosoft.com.

Esempio

Programma di installazione (mantieni le credenziali)

Conservare le credenziali per evitare di immetterle nuovamente per ogni esempio. Il nome del cluster verrà mantenuto in un passaggio separato.

A. Bash
Modificare lo script seguente sostituendo PASSWORD con la password effettiva. Immettere quindi il comando .

export password='PASSWORD'

B. PowerShell

$creds = Get-Credential -UserName "admin" -Message "Enter the HDInsight login"

Identificare correttamente il nome del cluster con maiuscole e minuscole

L'uso effettivo delle maiuscole e minuscole del nome del cluster può essere diverso da quello previsto. La procedura seguente mostra l'uso effettivo delle maiuscole e minuscole e quindi la archivia in una variabile per tutti gli esempi successivi.

Modificare gli script seguenti per sostituire CLUSTERNAME con il nome del cluster. Immettere quindi il comando . Il nome del cluster per il nome di dominio completo non fa distinzione tra maiuscole e minuscole.

export clusterName=$(curl -u admin:$password -sS -G "https://CLUSTERNAME.azurehdinsight.net/api/v1/clusters" | jq -r '.items[].Clusters.cluster_name')
echo $clusterName
# Identify properly cased cluster name
$resp = Invoke-WebRequest -Uri "https://CLUSTERNAME.azurehdinsight.net/api/v1/clusters" `
    -Credential $creds -UseBasicParsing
$clusterName = (ConvertFrom-Json $resp.Content).items.Clusters.cluster_name;

# Show cluster name
$clusterName

Analisi dei dati JSON

L'esempio seguente usa jq o ConvertFrom-Json per analizzare il documento di risposta JSON e visualizzare solo le informazioni dei health_report risultati.

curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName" \
| jq '.Clusters.health_report'
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName" `
    -Credential $creds -UseBasicParsing
$respObj = ConvertFrom-Json $resp.Content
$respObj.Clusters.health_report

Ottenere il nome di dominio completo dei nodi del cluster

Potrebbe essere necessario conoscere il nome di dominio completo (FQDN) di un nodo del cluster. È possibile recuperare con facilità l'FQDN per i diversi nodi del cluster usando gli esempi seguenti:

Tutti i nodi

curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/hosts" \
| jq -r '.items[].Hosts.host_name'
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/hosts" `
    -Credential $creds -UseBasicParsing
$respObj = ConvertFrom-Json $resp.Content
$respObj.items.Hosts.host_name

Nodi head

curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/HDFS/components/NAMENODE" \
| jq -r '.host_components[].HostRoles.host_name'
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/HDFS/components/NAMENODE" `
    -Credential $creds -UseBasicParsing
$respObj = ConvertFrom-Json $resp.Content
$respObj.host_components.HostRoles.host_name

Nodi del ruolo di lavoro

curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/HDFS/components/DATANODE" \
| jq -r '.host_components[].HostRoles.host_name'
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/HDFS/components/DATANODE" `
    -Credential $creds -UseBasicParsing
$respObj = ConvertFrom-Json $resp.Content
$respObj.host_components.HostRoles.host_name

Nodi Zookeeper

curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/ZOOKEEPER/components/ZOOKEEPER_SERVER" \
| jq -r ".host_components[].HostRoles.host_name"
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/ZOOKEEPER/components/ZOOKEEPER_SERVER" `
    -Credential $creds -UseBasicParsing
$respObj = ConvertFrom-Json $resp.Content
$respObj.host_components.HostRoles.host_name

Ottenere l'indirizzo IP interno dei nodi del cluster

Gli indirizzi IP restituiti dagli esempi in questa sezione non sono direttamente accessibili tramite Internet. Sono accessibili solo all'interno del Rete virtuale di Azure che contiene il cluster HDInsight.

Per altre informazioni sull'uso di HDInsight e reti virtuali, vedere Pianificare una rete virtuale per HDInsight.

Per trovare l'indirizzo IP, è necessario conoscere il nome di dominio completo (FQDN) interno dei nodi del cluster. Quando è stato ottenuto l'FQDN è possibile ottenere l'indirizzo IP dell'host. Gli esempi seguenti eseguono prima query su Ambari per il nome di dominio completo di tutti i nodi host. Esegue quindi una query su Ambari per l'indirizzo IP di ogni host.

for HOSTNAME in $(curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/hosts" | jq -r '.items[].Hosts.host_name')
do
    IP=$(curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/hosts/$HOSTNAME" | jq -r '.Hosts.ip')
  echo "$HOSTNAME <--> $IP"
done
$uri = "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/hosts" 
$resp = Invoke-WebRequest -Uri $uri -Credential $creds -UseBasicParsing
$respObj = ConvertFrom-Json $resp.Content
foreach($item in $respObj.items) {
    $hostName = [string]$item.Hosts.host_name
    $hostInfoResp = Invoke-WebRequest -Uri "$uri/$hostName" `
        -Credential $creds -UseBasicParsing
    $hostInfoObj = ConvertFrom-Json $hostInfoResp
    $hostIp = $hostInfoObj.Hosts.ip
    "$hostName <--> $hostIp"
}

Ottenere l'archiviazione predefinita

I cluster HDInsight devono usare un account di archiviazione di Azure o Data Lake Storage come risorsa di archiviazione predefinita. È possibile usare Ambari per recuperare queste informazioni dopo la creazione del cluster, ad esempio se si desidera leggere o scrivere dati nel contenitore all'esterno di HDInsight.

Negli esempi seguenti viene recuperata la configurazione di archiviazione predefinita dal cluster:

curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/configurations/service_config_versions?service_name=HDFS&service_config_version=1" \
| jq -r '.items[].configurations[].properties["fs.defaultFS"] | select(. != null)'
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/configurations/service_config_versions?service_name=HDFS&service_config_version=1" `
    -Credential $creds -UseBasicParsing
$respObj = ConvertFrom-Json $resp.Content
$respObj.items.configurations.properties.'fs.defaultFS'

Importante

Questi esempi restituiscono la prima configurazione applicata al server (service_config_version=1) che contiene queste informazioni. Se si recupera un valore che è stato modificato dopo la creazione del cluster, potrebbe essere necessario elencare le versioni della configurazione e recuperare la versione più recente.

Il valore restituito è simile a uno degli esempi seguenti:

  • wasbs://CONTAINER@ACCOUNTNAME.blob.core.windows.net - Questo valore indica che il cluster usa un account di archiviazione di Azure come risorsa di archiviazione predefinita. Il valore ACCOUNTNAME è il nome dell'account di archiviazione. La porzione CONTAINER corrisponde al nome del contenitore BLOB nell'account di archiviazione. Il contenitore è la radice della risorsa di archiviazione compatibile con HDFS per il cluster.

  • abfs://CONTAINER@ACCOUNTNAME.dfs.core.windows.net - Questo valore indica che il cluster usa Azure Data Lake Storage Gen2 come risorsa di archiviazione predefinita. I valori ACCOUNTNAME e CONTAINER hanno gli stessi significati descritti per Archiviazione di Azure in precedenza.

  • adl://home - Questo valore indica che il cluster usa Azure Data Lake Storage Gen1 come risorsa di archiviazione predefinita.

    Per trovare il nome dell'account Data Lake Storage, usare gli esempi seguenti:

    curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/configurations/service_config_versions?service_name=HDFS&service_config_version=1" \
    | jq -r '.items[].configurations[].properties["dfs.adls.home.hostname"] | select(. != null)'
    
    $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/configurations/service_config_versions?service_name=HDFS&service_config_version=1" `
        -Credential $creds -UseBasicParsing
    $respObj = ConvertFrom-Json $resp.Content
    $respObj.items.configurations.properties.'dfs.adls.home.hostname'
    

    Il valore restituito è simile a ACCOUNTNAME.azuredatalakestore.net, dove ACCOUNTNAME è il nome dell'account Data Lake Storage.

    Per trovare la directory all'interno di Data Lake Storage contenente la risorsa di archiviazione per il cluster, usare gli esempi seguenti:

    curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/configurations/service_config_versions?service_name=HDFS&service_config_version=1" \
    | jq -r '.items[].configurations[].properties["dfs.adls.home.mountpoint"] | select(. != null)'
    
    $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/configurations/service_config_versions?service_name=HDFS&service_config_version=1" `
        -Credential $creds -UseBasicParsing
    $respObj = ConvertFrom-Json $resp.Content
    $respObj.items.configurations.properties.'dfs.adls.home.mountpoint'
    

    Il valore restituito è simile a /clusters/CLUSTERNAME/. Questo valore è un percorso all'interno dell'account Data Lake Storage. Questo percorso è la radice del file system compatibile con HDFS per il cluster.

Nota

Il cmdlet Get-AzHDInsightCluster fornito da Azure PowerShell restituisce anche le informazioni di archiviazione per il cluster.

Ottenere tutte le configurazioni

Consente di ottenere le configurazioni disponibili per il cluster.

curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName?fields=Clusters/desired_configs"
$respObj = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName`?fields=Clusters/desired_configs" `
    -Credential $creds -UseBasicParsing
$respObj.Content

In questo esempio viene restituito un documento JSON contenente la configurazione corrente per i componenti installati. Vedere il valore del tag . L'esempio di seguito rappresenta un estratto dei dati restituiti da un tipo di cluster Spark.

"jupyter-site" : {
  "tag" : "INITIAL",
  "version" : 1
},
"livy2-client-conf" : {
  "tag" : "INITIAL",
  "version" : 1
},
"livy2-conf" : {
  "tag" : "INITIAL",
  "version" : 1
},

Ottenere la configurazione per un componente specifico

Ottenere la configurazione per il componente a cui si è interessati. Nell'esempio seguente, sostituire INITIAL con il valore del tag restituito dalla richiesta precedente.

curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/configurations?type=livy2-conf&tag=INITIAL"
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/configurations?type=livy2-conf&tag=INITIAL" `
    -Credential $creds -UseBasicParsing
$resp.Content

Questo esempio restituisce un documento JSON che contiene la configurazione corrente del componente livy2-conf.

Aggiornare la configurazione

  1. Creare newconfig.json.
    Modificare e quindi immettere i comandi seguenti:

    • Sostituire livy2-conf con il nuovo componente.

    • Sostituire INITIAL con il valore effettivo recuperato per tag da Recupera tutte le configurazioni.

      A. Bash

      curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/configurations?type=livy2-conf&tag=INITIAL" \
      | jq --arg newtag $(echo version$(date +%s%N)) '.items[] | del(.href, .version, .Config) | .tag |= $newtag | {"Clusters": {"desired_config": .}}' > newconfig.json
      

      B. PowerShell
      Lo script di PowerShell usa jq. Modificare C:\HD\jq\jq-win64 di seguito per riflettere il percorso effettivo e la versione di jq.

      $epoch = Get-Date -Year 1970 -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0
      $now = Get-Date
      $unixTimeStamp = [math]::truncate($now.ToUniversalTime().Subtract($epoch).TotalMilliSeconds)
      $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/configurations?type=livy2-conf&tag=INITIAL" `
        -Credential $creds -UseBasicParsing
      $resp.Content | C:\HD\jq\jq-win64 --arg newtag "version$unixTimeStamp" '.items[] | del(.href, .version, .Config) | .tag |= $newtag | {"Clusters": {"desired_config": .}}' > newconfig.json
      

      Jq viene usato per trasformare i dati recuperati da HDInsight in un nuovo modello di configurazione. In particolare, questi esempi eseguono le azioni seguenti:

    • Crea un valore univoco contenente la stringa "version" e la data, che viene archiviato in newtag.

    • Crea un documento radice per la nuova configurazione.

    • Ottiene i contenuti della matrice .items[] e li aggiunge sotto l'elemento desired_config.

    • Elimina gli elementi href, version e Config perché non sono necessari per l'invio di una nuova configurazione.

    • Aggiunge un elemento tag con un valore di version#################. La parte numerica si basa sulla data corrente. Ogni configurazione deve avere un tag univoco.

      Infine i dati vengono salvati nel documento newconfig.json. La struttura del documento deve essere simile all'esempio di seguito:

      {
        "Clusters": {
          "desired_config": {
            "tag": "version1552064778014",
            "type": "livy2-conf",
            "properties": {
              "livy.environment": "production",
              "livy.impersonation.enabled": "true",
              "livy.repl.enableHiveContext": "true",
              "livy.server.csrf_protection.enabled": "true",
                ....
            },
          },
        }
      }
      
  2. Modificare newconfig.json.
    Aprire il documento newconfig.json e modificare o aggiungere i valori nell'oggetto properties. L'esempio seguente modifica il valore di "livy.server.csrf_protection.enabled" da "true" a "false".

    "livy.server.csrf_protection.enabled": "false",
    

    Salvare il file dopo aver apportato modifiche.

  3. Inviare newconfig.json.
    Usare i comandi seguenti per inviare la configurazione aggiornata ad Ambari.

    curl -u admin:$password -sS -H "X-Requested-By: ambari" -X PUT -d @newconfig.json "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName"
    
    $newConfig = Get-Content .\newconfig.json
    $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName" `
        -Credential $creds -UseBasicParsing `
        -Method PUT `
        -Headers @{"X-Requested-By" = "ambari"} `
        -Body $newConfig
    $resp.Content
    

    Questi comandi inviano il contenuto del file newconfig.json al cluster come nuova configurazione. La richiesta restituisce un documento JSON. L'elemento versionTag di questo documento deve corrispondere alla versione inviata, mentre l'oggetto configs conterrà le modifiche di configurazione richieste.

Riavviare un componente del servizio

A questo punto, l'interfaccia utente Web Ambari indica che il servizio Spark deve essere riavviato prima che la nuova configurazione possa essere applicata. Usare la procedura seguente per riavviare il servizio.

  1. Usare quanto segue per abilitare la modalità di manutenzione per il servizio Spark2:

    curl -u admin:$password -sS -H "X-Requested-By: ambari" \
    -X PUT -d '{"RequestInfo": {"context": "turning on maintenance mode for SPARK2"},"Body": {"ServiceInfo": {"maintenance_state":"ON"}}}' \
    "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/SPARK2"
    
    $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/SPARK2" `
        -Credential $creds -UseBasicParsing `
        -Method PUT `
        -Headers @{"X-Requested-By" = "ambari"} `
        -Body '{"RequestInfo": {"context": "turning on maintenance mode for SPARK2"},"Body": {"ServiceInfo": {"maintenance_state":"ON"}}}'
    
  2. Verificare la modalità di manutenzione

    Questi comandi inviano un documento JSON al server che attiva la modalità di manutenzione. È possibile verificare che il servizio sia in modalità di manutenzione usando la richiesta seguente:

    curl -u admin:$password -sS -H "X-Requested-By: ambari" \
    "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/SPARK2" \
    | jq .ServiceInfo.maintenance_state
    
    $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/SPARK2" `
        -Credential $creds -UseBasicParsing
    $respObj = ConvertFrom-Json $resp.Content
    $respObj.ServiceInfo.maintenance_state
    

    Viene restituito il valore ON.

  3. Usare quindi quanto segue per disattivare il servizio Spark2:

    curl -u admin:$password -sS -H "X-Requested-By: ambari" \
    -X PUT -d '{"RequestInfo":{"context":"_PARSE_.STOP.SPARK2","operation_level":{"level":"SERVICE","cluster_name":"CLUSTERNAME","service_name":"SPARK"}},"Body":{"ServiceInfo":{"state":"INSTALLED"}}}' \
    "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/SPARK2"
    
    $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/SPARK2" `
        -Credential $creds -UseBasicParsing `
        -Method PUT `
        -Headers @{"X-Requested-By" = "ambari"} `
        -Body '{"RequestInfo":{"context":"_PARSE_.STOP.SPARK2","operation_level":{"level":"SERVICE","cluster_name":"CLUSTERNAME","service_name":"SPARK"}},"Body":{"ServiceInfo":{"state":"INSTALLED"}}}'
    $resp.Content
    

    La risposta restituita è simile all'esempio seguente:

    {
        "href" : "http://10.0.0.18:8080/api/v1/clusters/CLUSTERNAME/requests/29",
        "Requests" : {
            "id" : 29,
            "status" : "Accepted"
        }
    }
    

    Importante

    Il valore href restituito dall'URI usa l'indirizzo IP interno del nodo del cluster. Per usarlo dall'esterno del cluster, sostituire la 10.0.0.18:8080 parte con il nome di dominio completo del cluster.

  4. Verificare la richiesta.
    Modificare il comando seguente sostituendo 29 con il valore effettivo per id restituito dal passaggio precedente. Il comando seguente recupera lo stato della richiesta:

    curl -u admin:$password -sS -H "X-Requested-By: ambari" \
    "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/requests/29" \
    | jq .Requests.request_status
    
    $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/requests/29" `
        -Credential $creds -UseBasicParsing
    $respObj = ConvertFrom-Json $resp.Content
    $respObj.Requests.request_status
    

    La risposta COMPLETED indica che la richiesta è stata completata.

  5. Al termine della richiesta precedente, usare quanto segue per avviare il servizio Spark2.

    curl -u admin:$password -sS -H "X-Requested-By: ambari" \
    -X PUT -d '{"RequestInfo":{"context":"_PARSE_.START.SPARK2","operation_level":{"level":"SERVICE","cluster_name":"CLUSTERNAME","service_name":"SPARK"}},"Body":{"ServiceInfo":{"state":"STARTED"}}}' \
    "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/SPARK2"
    
    $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/SPARK2" `
        -Credential $creds -UseBasicParsing `
        -Method PUT `
        -Headers @{"X-Requested-By" = "ambari"} `
        -Body '{"RequestInfo":{"context":"_PARSE_.START.SPARK2","operation_level":{"level":"SERVICE","cluster_name":"CLUSTERNAME","service_name":"SPARK"}},"Body":{"ServiceInfo":{"state":"STARTED"}}}'
    $resp.Content
    

    Il servizio ora usa la nuova configurazione.

  6. Infine, usare il codice seguente per disattivare la modalità di manutenzione.

    curl -u admin:$password -sS -H "X-Requested-By: ambari" \
    -X PUT -d '{"RequestInfo": {"context": "turning off maintenance mode for SPARK2"},"Body": {"ServiceInfo": {"maintenance_state":"OFF"}}}' \
    "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/SPARK2"
    
    $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.net/api/v1/clusters/$clusterName/services/SPARK2" `
        -Credential $creds -UseBasicParsing `
        -Method PUT `
        -Headers @{"X-Requested-By" = "ambari"} `
        -Body '{"RequestInfo": {"context": "turning off maintenance mode for SPARK2"},"Body": {"ServiceInfo": {"maintenance_state":"OFF"}}}'
    

Passaggi successivi

Per informazioni tecniche complete sull'API REST, vedere la pagina relativa alle informazioni di riferimento per l'API Apache Ambari V1. Vedere anche Autorizzare gli utenti per le viste Apache Ambari