Gerir clusters do HDInsight com a API REST do Apache Ambari
Saiba como utilizar a API REST do Apache Ambari para gerir e monitorizar clusters do Apache Hadoop no Azure HDInsight.
O que é o Apache Ambari
O Apache Ambari simplifica a gestão e monitorização de clusters do Hadoop ao fornecer uma IU Web fácil de utilizar com as respetivas APIs REST. O Ambari é fornecido por predefinição com clusters do HDInsight baseados em Linux.
Pré-requisitos
Um cluster do Hadoop no HDInsight. Veja Introdução ao HDInsight no Linux.
Bash no Ubuntu no Windows 10. Os exemplos neste artigo utilizam a shell do Bash no Windows 10. Veja o Guia de Instalação do Subsistema Windows para Linux para obter Windows 10 para obter os passos de instalação. Outras shells Unix também funcionarão. Os exemplos, com algumas modificações ligeiras, podem funcionar numa linha de comandos do Windows. Em alternativa, pode utilizar Windows PowerShell.
jq, um processador JSON de linha de comandos. Consulte https://stedolan.github.io/jq/.
Windows PowerShell. Em alternativa, pode utilizar o Bash.
Identificador de Recursos Uniforme Base para a API REST do Ambari
O URI (Uniform Resource Identifier) base para a API REST do Ambari no HDInsight é https://CLUSTERNAME.azurehdinsight.net/api/v1/clusters/CLUSTERNAME
, onde CLUSTERNAME
é o nome do cluster. Os nomes dos clusters em URIs são sensíveis a maiúsculas e minúsculas. Embora o nome do cluster na parte do nome de domínio completamente qualificado (FQDN) do URI (CLUSTERNAME.azurehdinsight.net
) não seja sensível a maiúsculas e minúsculas, outras ocorrências no URI são sensíveis a maiúsculas e minúsculas.
Autenticação
A ligação ao Ambari no HDInsight requer HTTPS. Utilize o nome da conta de administrador (a predefinição é administrador) e a palavra-passe que forneceu durante a criação do cluster.
Para clusters do Pacote de Segurança Empresarial, em vez de admin
, utilize um nome de utilizador completamente qualificado como username@domain.onmicrosoft.com
.
Exemplos
Configuração (Preservar credenciais)
Preserve as suas credenciais para evitar reintroduzi-las para cada exemplo. O nome do cluster será preservado num passo separado.
A. Bash
Edite o script abaixo ao substituir PASSWORD
pela palavra-passe real. Em seguida, introduza o comando .
export password='PASSWORD'
B. PowerShell
$creds = Get-Credential -UserName "admin" -Message "Enter the HDInsight login"
Identificar o nome do cluster corretamente maiúsculas e minúsculas
O invólucro real do nome do cluster pode ser diferente do esperado. Os passos aqui irão mostrar o invólucro real e, em seguida, armazená-lo numa variável para todos os exemplos posteriores.
Edite os scripts abaixo para substituir CLUSTERNAME
pelo nome do cluster. Em seguida, introduza o comando . (O nome do cluster do FQDN não é sensível a maiúsculas e minúsculas.)
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
Analisar dados JSON
O exemplo seguinte utiliza jq ou ConvertFrom-Json para analisar o documento de resposta JSON e apresentar apenas as health_report
informações dos resultados.
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
Obter o FQDN dos nós de cluster
Poderá ter de saber o nome de domínio completamente qualificado (FQDN) de um nó de cluster. Pode obter facilmente o FQDN para os vários nós no cluster com os seguintes exemplos:
Todos os nós
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
Nós principais
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
Nós de trabalho
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
Nós do 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
Obter o endereço IP interno dos nós de cluster
Os endereços IP devolvidos pelos exemplos nesta secção não são diretamente acessíveis através da Internet. Só estão acessíveis no Azure Rede Virtual que contém o cluster do HDInsight.
Para obter mais informações sobre como trabalhar com o HDInsight e redes virtuais, veja Planear uma rede virtual para o HDInsight.
Para localizar o endereço IP, tem de saber o nome de domínio completamente qualificado interno (FQDN) dos nós de cluster. Assim que tiver o FQDN, pode obter o endereço IP do anfitrião. Os exemplos seguintes consultam primeiro o Ambari para o FQDN de todos os nós de anfitrião. Em seguida, consulta o Ambari para o endereço IP de cada anfitrião.
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"
}
Obter o armazenamento predefinido
Os clusters do HDInsight têm de utilizar uma Conta de Armazenamento do Azure ou Data Lake Storage como armazenamento predefinido. Pode utilizar o Ambari para obter estas informações após a criação do cluster. Por exemplo, se quiser ler/escrever dados no contentor fora do HDInsight.
Os exemplos seguintes obtêm a configuração de armazenamento predefinida do 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
Estes exemplos devolvem a primeira configuração aplicada ao servidor (service_config_version=1
) que contém estas informações. Se obter um valor que tenha sido modificado após a criação do cluster, poderá ter de listar as versões de configuração e obter a mais recente.
O valor devolvido é semelhante a um dos seguintes exemplos:
wasbs://CONTAINER@ACCOUNTNAME.blob.core.windows.net
- Este valor indica que o cluster está a utilizar uma conta de Armazenamento do Azure para armazenamento predefinido. OACCOUNTNAME
valor é o nome da conta de armazenamento. ACONTAINER
parte é o nome do contentor de blobs na conta de armazenamento. O contentor é a raiz do armazenamento compatível com HDFS para o cluster.abfs://CONTAINER@ACCOUNTNAME.dfs.core.windows.net
- Este valor indica que o cluster está a utilizar Azure Data Lake Storage Gen2 para armazenamento predefinido. OsACCOUNTNAME
valores eCONTAINER
têm os mesmos significados que para o Armazenamento do Azure mencionado anteriormente.adl://home
- Este valor indica que o cluster está a utilizar Azure Data Lake Storage Gen1 para armazenamento predefinido.Para localizar o nome da conta Data Lake Storage, utilize os seguintes exemplos:
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'
O valor devolvido é semelhante a
ACCOUNTNAME.azuredatalakestore.net
, em queACCOUNTNAME
é o nome da conta Data Lake Storage.Para localizar o diretório no Data Lake Storage que contém o armazenamento do cluster, utilize os seguintes exemplos:
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'
O valor devolvido é semelhante a
/clusters/CLUSTERNAME/
. Este valor é um caminho dentro da conta Data Lake Storage. Este caminho é a raiz do sistema de ficheiros compatível com HDFS para o cluster.
Nota
O cmdlet Get-AzHDInsightCluster fornecido pelo Azure PowerShell também devolve as informações de armazenamento do cluster.
Obter todas as configurações
Obtenha as configurações que estão disponíveis para o 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
Este exemplo devolve um documento JSON que contém a configuração atual dos componentes instalados. Veja o valor da etiqueta . O exemplo seguinte é um excerto dos dados devolvidos de um tipo de cluster do Spark.
"jupyter-site" : {
"tag" : "INITIAL",
"version" : 1
},
"livy2-client-conf" : {
"tag" : "INITIAL",
"version" : 1
},
"livy2-conf" : {
"tag" : "INITIAL",
"version" : 1
},
Obter a configuração para um componente específico
Obtenha a configuração do componente no qual está interessado. No exemplo seguinte, substitua INITIAL
pelo valor da etiqueta devolvido do pedido anterior.
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
Este exemplo devolve um documento JSON que contém a configuração atual do livy2-conf
componente.
Configuração da atualização
Criar
newconfig.json
.
Modifique e, em seguida, introduza os comandos abaixo:Substitua
livy2-conf
pelo novo componente.Substitua pelo
INITIAL
valor real obtido paratag
de Obter todas as configurações.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
O script do PowerShell utiliza jq. EditeC:\HD\jq\jq-win64
abaixo para refletir o caminho real e a versão do 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
O Jq é utilizado para transformar os dados obtidos do HDInsight num novo modelo de configuração. Especificamente, estes exemplos fazem as seguintes ações:
Cria um valor exclusivo que contém a cadeia "versão" e a data, que é armazenada no
newtag
.Cria um documento de raiz para a nova configuração.
Obtém o conteúdo da
.items[]
matriz e adiciona-o no elemento desired_config .Elimina os
href
elementos ,version
eConfig
, uma vez que estes elementos não são necessários para submeter uma nova configuração.Adiciona um
tag
elemento com um valor deversion#################
. A parte numérica baseia-se na data atual. Cada configuração tem de ter uma etiqueta exclusiva.Por fim, os dados são guardados no
newconfig.json
documento. A estrutura do documento deve ser semelhante ao seguinte exemplo:{ "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", .... }, }, } }
Editar
newconfig.json
.
Abra onewconfig.json
documento e modifique/adicione valores noproperties
objeto. O exemplo seguinte altera o valor de de"livy.server.csrf_protection.enabled"
"true"
para"false"
."livy.server.csrf_protection.enabled": "false",
Guarde o ficheiro quando terminar de efetuar modificações.
Submeta
newconfig.json
.
Utilize os seguintes comandos para submeter a configuração atualizada para o 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
Estes comandos submetem o conteúdo do ficheiro newconfig.json para o cluster como a nova configuração. O pedido devolve um documento JSON. O elemento versionTag neste documento deve corresponder à versão que submeteu e o objeto configs contém as alterações de configuração pedidas.
Reiniciar um componente de serviço
Neste momento, a IU da Web do Ambari indica que o serviço Spark tem de ser reiniciado antes de a nova configuração poder entrar em vigor. Utilize os seguintes passos para reiniciar o serviço.
Utilize o seguinte para ativar o modo de manutenção para o serviço 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"}}}'
Verificar o modo de manutenção
Estes comandos enviam um documento JSON para o servidor que ativa o modo de manutenção. Pode verificar se o serviço está agora no modo de manutenção com o seguinte pedido:
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
O valor devolvido é
ON
.Em seguida, utilize o seguinte para desativar o serviço 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
A resposta é semelhante ao seguinte exemplo:
{ "href" : "http://10.0.0.18:8080/api/v1/clusters/CLUSTERNAME/requests/29", "Requests" : { "id" : 29, "status" : "Accepted" } }
Importante
O
href
valor devolvido por este URI está a utilizar o endereço IP interno do nó de cluster. Para utilizá-la de fora do cluster, substitua a10.0.0.18:8080
parte pelo FQDN do cluster.Verifique o pedido.
Edite o comando abaixo ao substituir29
pelo valor real paraid
devolvido do passo anterior. Os seguintes comandos obtêm o estado do pedido: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
Uma resposta de
COMPLETED
indica que o pedido foi concluído.Depois de concluído o pedido anterior, utilize o seguinte para iniciar o serviço 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
O serviço está agora a utilizar a nova configuração.
Por fim, utilize o seguinte para desativar o modo de manutenção.
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"}}}'
Passos seguintes
Para obter uma referência completa da API REST, veja Referência da API do Apache Ambari V1. Veja também Autorizar utilizadores para as Vistas do Apache Ambari