Управление кластерами HDInsight с помощью Apache Ambari REST API

Узнайте, как использовать Apache Ambari REST API для отслеживания и администрирования кластеров Apache Hadoop в Azure HDInsight.

Что такое Apache Ambari?

Apache Ambari упрощает управление кластером Hadoop и его мониторинг за счет удобного пользовательского веб-интерфейса и интерфейсов REST API. Ambari предоставляется по умолчанию с кластерами HDInsight на платформе Linux.

Предварительные требования

Базовый универсальный идентификатор ресурса для API-интерфейса REST Ambari

Базовый универсальный идентификатор ресурса (URI) для REST API Ambari в HDInsight — https://CLUSTERNAME.azurehdinsight.net/api/v1/clusters/CLUSTERNAME, где CLUSTERNAME — это имя вашего кластера. Имена кластеров в URI задаются с учетом регистра. Хотя имя кластера в полном доменном имени в URI (CLUSTERNAME.azurehdinsight.net) указывается без учета регистра, в других вхождениях этого URI регистр учитывается.

Аутентификация

Подключение к Ambari в HDInsight выполняется по протоколу HTTPS. Используйте имя учетной записи администратора (по умолчанию — admin) и пароль, указанные при создании кластера.

Для кластеров Корпоративного пакета безопасности вместо admin используйте полное имя пользователя, например username@domain.onmicrosoft.com.

Примеры

Установка (сохранение учетных данных)

Вы можете сохранить свои учетные данные, чтобы не вводить их повторно для каждого примера. Имя кластера будет сохранено на отдельном шаге.

A. Bash
Отредактируйте приведенный ниже скрипт, заменив в нем PASSWORD фактическим паролем. Затем введите команду.

export password='PASSWORD'

Б. PowerShell

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

Укажите имя кластера в правильном регистре.

Фактический регистр имени кластера может отличаться от предполагаемого. В действиях в этом примере показан правильный регистр, и это значение сохраняется в переменной для всех последующих примеров.

Отредактируйте приведенные ниже скрипты, заменив CLUSTERNAME именем своего кластера. Затем введите команду. (Имя кластера в FQDN не учитывает регистр.)

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

Анализ данных JSON

В примере ниже для анализа документа ответа JSON и отображения из результатов только сведений health_report используется программа jq или ConvertFrom-Json.

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

Получение полного доменного имени для узлов кластера

Вам может потребоваться полное доменное имя (FQDN) узла кластера. FQDN можно легко получить для разных узлов в кластере с помощью следующих команд.

Все узлы

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

Головные узлы

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

Рабочие узлы

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

Узлы 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

Получение внутреннего IP-адреса узлов кластера

IP-адреса, возвращенные в примерах из этого раздела, недоступны напрямую через Интернет. Они доступны только в пределах виртуальной сети Azure, содержащей кластер HDInsight.

Подробные сведения об использовании HDInsight и виртуальных сетей см. в статье Планирование виртуальной сети для HDInsight.

Чтобы найти IP-адрес, необходимо знать внутренние полные доменные имена (FQDN) узлов кластера. Если у вас есть полное доменное имя, вы можете получить IP-адрес узла. В следующих примерах у Ambari сначала запрашивается полное доменное имя для всех узлов, а затем — IP-адрес каждого узла.

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

Получение хранилища по умолчанию

Для кластеров HDInsight в качестве хранилища по умолчанию необходимо использовать учетную запись хранения Azure или Data Lake Storage. Для получения этой информации после создания кластера можно использовать Ambari. Например, если нужно выполнить операции чтения или записи в контейнере за пределами HDInsight.

Следующие примеры извлекают конфигурацию хранилища, используемого в кластере по умолчанию.

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'

Важно!

Эти примеры возвращают первую конфигурацию, применяемую к серверу (service_config_version=1), который содержит эти сведения. Чтобы получить значение, которое было изменено после создания кластера, может потребоваться перечислить версии конфигурации и получить последнюю из них.

Возвращаемое значение будет выглядеть, как один из следующих примеров:

  • wasbs://CONTAINER@ACCOUNTNAME.blob.core.windows.net — это значение указывает, что кластер использует учетную запись хранения Azure в качестве хранилища по умолчанию. Значение ACCOUNTNAME — имя учетной записи хранилища. Часть CONTAINER — это имя контейнера больших двоичных объектов в учетной записи хранения. Контейнер является корнем совместимого хранилища HDFS для кластера.

  • abfs://CONTAINER@ACCOUNTNAME.dfs.core.windows.net — это значение указывает, что кластер использует Azure Data Lake Storage 2-го поколения в качестве хранилища по умолчанию. Значения ACCOUNTNAME и CONTAINER те же, что и для службы хранилища Azure, как объяснялось выше.

  • adl://home — это значение указывает, что кластер использует Azure Data Lake Storage 1-го поколения в качестве хранилища по умолчанию.

    Чтобы найти имя учетной записи Data Lake Storage, используйте следующие примеры.

    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'
    

    Возвращается похожее значение: ACCOUNTNAME.azuredatalakestore.net, где ACCOUNTNAME — имя учетной записи Data Lake Storage.

    Чтобы найти каталог в Data Lake Storage, содержащий хранилище кластера, используйте следующие примеры.

    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'
    

    Вернется похожее значение: /clusters/CLUSTERNAME/. Это значение представляет путь в учетной записи Data Lake Storage. Путь является корнем совместимой файловой системы HDFS для кластера.

Примечание

Командлет Get-AzHDInsightCluster, доступный в Azure PowerShell, также возвращает сведения о хранилище для кластера.

Получение всех конфигураций

Получите конфигурации, которые доступны для кластера.

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

Этот пример возвращает документ JSON, содержащий текущую конфигурацию для установленных компонентов. См. значение тега. Ниже приведен пример фрагмента данных, возвращаемых из типа кластера Spark.

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

Получение конфигурации для определенного компонента

Извлеките конфигурацию для интересующего вас компонента. В следующем примере замените INITIAL значением тега, возвращенным из предыдущего запроса.

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

Этот пример возвращает документ JSON, содержащий текущую конфигурацию для компонента livy2-conf.

Обновление конфигурации

  1. Создайте newconfig.json.
    Измените и введите следующие команды:

    • Замените livy2-conf на новый компонент.

    • Замените INITIAL на фактическое значение, полученное для tag в разделе Получение всех конфигураций.

      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
      

      Б. PowerShell
      В скрипте PowerShell используется jq. Отредактируйте C:\HD\jq\jq-win64 ниже и укажите фактический путь и версию 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 используется для преобразования данных, извлеченных из HDInsight в новый шаблон конфигурации. В частности, этот пример выполняет следующие действия:

    • Создает уникальное значение, содержащее строку version и дату, хранящуюся в newtag.

    • Создает корневой документ для новой конфигурации.

    • Возвращает содержимое массива .items[] и добавляет его в элемент desired_config.

    • Удаляет элементы href, version и Config, так как они не нужны для отправки новой конфигурации.

    • Добавляет элемент tag со значением version#################. Числовая часть основана на текущей дате. Каждая конфигурация должна иметь уникальное значение tag.

      Наконец, данные сохраняются в документе newconfig.json. Структура документа должна выглядеть следующим образом:

      {
        "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. Измените newconfig.json.
    Откройте документ newconfig.json и измените или добавьте значения в объекте properties. Следующий пример изменяет значение "livy.server.csrf_protection.enabled" с "true" на "false".

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

    После завершения работы сохраните файл.

  3. Отправьте файл newconfig.json.
    Выполните следующие команды, чтобы отправить обновленную конфигурацию в 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
    

    Эти команды передают содержимое файла newconfig.json в кластер в качестве новой конфигурации. Запрос возвращает документ JSON. Элемент versionTag в этом документе должен совпадать с отправленной версией, а объект configs содержит запрошенные изменения конфигурации.

Перезапуск компонента службы

На этом этапе в веб-интерфейсе Ambari отображается сообщение о том, что вам необходимо перезапустить службу Spark, чтобы новая конфигурация вступила в силу. Для перезапуска службы выполните приведенные ниже действия.

  1. Выполните следующую команду, чтобы перевести службу 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. Проверка режима обслуживания

    Эти команды отправляют документ JSON на сервер, который включает режим обслуживания. Проверить, находится ли служба в этом режиме, можно с помощью следующего запроса.

    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
    

    Возвращается значение ON.

  3. Затем выполните следующую команду, чтобы отключить службу 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
    

    Ответ будет выглядеть примерно так:

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

    Важно!

    Значение href , возвращенное этим универсальным кодом ресурса (URI), использует внутренний IP-адрес узла кластера. Чтобы использовать его извне кластера, замените часть 10.0.0.18:8080 на полное доменное имя кластера.

  4. Проверьте запрос.
    Отредактируйте команду ниже и замените 29 фактическим значением id, полученным на предыдущем шаге. Например, следующие команды получают состояние запроса:

    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
    

    Ответ COMPLETED указывает, что запрос завершен.

  5. После завершения предыдущего запроса используйте следующую команду для запуска службы 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
    

    Теперь служба использует новую конфигурацию.

  6. Наконец, используйте следующую команду для отключения режима обслуживания.

    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"}}}'
    

Дальнейшие действия

Полный справочник по REST API см. здесь. Также см. статью Предоставление пользователям доступа к представлениям Apache Ambari