Apache Ambari REST API を使用した HDInsight クラスターの管理

Apache Ambari REST API を使用して Azure HDInsight の Apache Hadoop クラスターを管理および監視する方法を説明します。

Apache Ambari とは

Apache Ambari は、REST API に支えられた使いやすい Web UI を提供することで、Hadoop クラスターの管理と監視を簡素化します。 Ambari は既定で Linux ベースの HDInsight クラスターに付属しています。

前提条件

Ambari REST API のベース Uniform Resource Identifier

HDInsight の Ambari REST API のベース URI (Uniform Resource Identifier) は、https://CLUSTERNAME.azurehdinsight.net/api/v1/clusters/CLUSTERNAME です。CLUSTERNAME はお使いのクラスターの名前です。 URI のクラスター名では、大文字と小文字が区別されます。 URI (CLUSTERNAME.azurehdinsight.net) の FQDN (完全修飾ドメイン名) 部分のクラスター名では大文字と小文字が区別されませんが、URI の他の部分で出現するときは大文字と小文字が区別されます。

認証

HDInsight の Ambari に接続するには、HTTPS が必要です。 クラスターの作成中に入力した管理者アカウント名 (既定値は admin) とパスワードを使用します。

Enterprise セキュリティ パッケージ クラスターの場合、admin ではなく、username@domain.onmicrosoft.com のように完全修飾ユーザー名を使用します。

セットアップ (資格情報の保存)

各例で再入力しなくて済むように、資格情報を保存します。 クラスター名は別の手順で保存します。

A. Bash
PASSWORD を実際のパスワードに置き換えて、次のスクリプトを編集します。 その後、コマンドを入力します。

export password='PASSWORD'

B. 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 データの解析

次の例では、jq または ConvertFrom-Json を使用して、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) を知ることが必要になる場合があります。 次の例を使用して、クラスター内のさまざまなノードの 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

[Worker nodes]\(ワーカー ノード\)

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 アドレスは、インターネット経由で直接アクセスすることはできません。 HDInsight クラスターが含まれている Azure Virtual Network 内からだけアクセスできます。

HDInsight と仮想ネットワークの操作の詳細については、「Plan a virtual network for HDInsight」 (HDInsight 用の仮想ネットワークの計画) を参照してください。

IP アドレスを検索するには、クラスター ノードの内部完全修飾ドメイン名 (FQDN) が必要です。 FQDN の取得後、ホストの IP アドレスを取得できます。 次の例は、まず、すべてのホスト ノードの FQDN を Ambari に照会します。 次に 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 Storage アカウントまたは 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 Storage アカウントを使用していることを示します。 ACCOUNTNAME 値は、ストレージ アカウントの名前です。 CONTAINER 部分は、ストレージ アカウント内の BLOB コンテナーの名前です。 コンテナーは、クラスターの HDFS 互換ストレージのルートです。

  • abfs://CONTAINER@ACCOUNTNAME.dfs.core.windows.net - この値は、クラスターが既定のストレージとして Azure Data Lake Storage Gen2 を使用していることを示します。 ACCOUNTNAME 値と CONTAINER 値は、前述の Azure Storage の場合と同じ意味です。

  • adl://home - この値は、クラスターが既定のストレージとして Azure Data Lake Storage Gen1 を使用していることを示します。

    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 互換ファイル システムのルートです。

注意

Azure PowerShell に用意されている Get-AzHDInsightCluster コマンドレットも、クラスターのストレージ情報を返します。

すべての構成を取得する

クラスターに使用できる構成を取得します。

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 ドキュメントが返されます。 tag の値を参照してください。 次の例は 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

この例では、livy2-conf コンポーネントの現在の構成を含む JSON ドキュメントが返されます。

構成を更新する

  1. newconfig.json を作成します。
    変更後、次のコマンドを入力します。

    • livy2-conf を新しいコンポーネントで置き換えます。

    • INITIAL を、「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
      

      B. PowerShell
      この PowerShell スクリプトでは、jq を使用しています。 実際のパスと C:\HD\jq\jq-win64 のバージョンを反映するように、次の C:\HD\jq\jq-win64 を編集します。

      $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[] 配列のコンテンツが取得され、.items[] 要素の下に追加されます。

    • 新しい構成の送信に必要ないため、hrefversionConfig の各要素が削除されます。

    • 値を 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 Web UI に、新しい構成を有効にするには 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"
        }
    }
    

    重要

    この URI で返される href 値はクラスター ノードの内部 IP アドレスを利用します。 クラスターの外部からこれを利用するには、10.0.0.18:8080 部分をクラスターの FQDN に置換します。

  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 API リファレンス V1」をご覧ください。 「Apache Ambari ビューに対してユーザーを承認する」も参照してください。