使用 Apache Ambari REST API 管理 HDInsight 群集
了解如何使用 Apache Ambari REST API 管理和监视 Azure HDInsight 中的 Apache Hadoop 群集。
什么是 Apache Ambari
Apache Ambari 提供基于 REST API 的简单易用型 Web UI 来简化 Hadoop 群集的管理和监视。 基于 Linux 的 HDInsight 群集已按默认提供 Ambari。
先决条件
HDInsight 上的 Hadoop 群集。 请参阅 Linux 上的 HDInsight 入门。
Windows 10 版 Bash on Ubuntu。 本文中的示例使用 Windows 10 上的 Bash shell。 有关安装步骤,请参阅适用于 Linux 的 Windows 子系统安装指南 - Windows 10。 其他 Unix shell 也适用。 这些示例在经过轻微的修改后,可在 Windows 命令提示符下运行。 或者,可以使用 Windows PowerShell。
jq,一个命令行 JSON 处理程序。 请参阅 https://stedolan.github.io/jq/。
Windows PowerShell。 或者可以使用 Bash。
Ambari REST API 的基本统一资源标识符
HDInsight 上 Ambari REST API 的基本统一资源标识符 (URI) 为 https://CLUSTERNAME.azurehdinsight.cn/api/v1/clusters/CLUSTERNAME
,其中 CLUSTERNAME
是群集的名称。 URI 中的群集名称区分大小写。 虽然 URI (CLUSTERNAME.azurehdinsight.cn
) 的完全限定域名 (FQDN) 部分中的群集名称不区分大小写,但 URI 中的其他部分是区分大小写的。
身份验证
连接到 HDInsight 上的 Ambari 需要 HTTPS。 使用在群集创建过程中提供的管理员帐户名称(默认值是 admin)和密码。
对于企业安全性套餐群集,请使用完全限定的用户名(如 username@domain.partner.onmschina.cn
)而非 admin
。
示例
设置(保留凭据)
请保留凭据,以免在每个示例中重复输入。 群集名称在单独的步骤中保留。
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.cn/api/v1/clusters" | jq -r '.items[].Clusters.cluster_name')
echo $clusterName
# Identify properly cased cluster name
$resp = Invoke-WebRequest -Uri "https://CLUSTERNAME.azurehdinsight.cn/api/v1/clusters" `
-Credential $creds -UseBasicParsing
$clusterName = (ConvertFrom-Json $resp.Content).items.Clusters.cluster_name;
# Show cluster name
$clusterName
分析 JSON 数据
以下示例使用 jq 或 ConvertFrom-Json 来分析 JSON 响应文档并仅显示结果中的 health_report
信息。
curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName" \
| jq '.Clusters.health_report'
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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.cn/api/v1/clusters/$clusterName/hosts" \
| jq -r '.items[].Hosts.host_name'
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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.cn/api/v1/clusters/$clusterName/services/HDFS/components/NAMENODE" \
| jq -r '.host_components[].HostRoles.host_name'
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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.cn/api/v1/clusters/$clusterName/services/HDFS/components/DATANODE" \
| jq -r '.host_components[].HostRoles.host_name'
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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.cn/api/v1/clusters/$clusterName/services/ZOOKEEPER/components/ZOOKEEPER_SERVER" \
| jq -r ".host_components[].HostRoles.host_name"
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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 地址不可直接通过 Internet 进行访问。 它们只可在包含 HDInsight 群集的 Azure 虚拟网络内访问。
有关使用 HDInsight 和虚拟网络的详细信息,请参阅为 HDInsight 规划虚拟网络。
要查找 IP 地址,必须知道群集节点的内部完全限定的域名 (FQDN)。 拥有 FQDN 后即可获取主机的 IP 地址。 下面的示例首先从 Ambari 查询所有主机节点的 FQDN。 然后从 Ambari 查询每个主机的 IP 地址。
for HOSTNAME in $(curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/hosts" | jq -r '.items[].Hosts.host_name')
do
IP=$(curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/hosts/$HOSTNAME" | jq -r '.Hosts.ip')
echo "$HOSTNAME <--> $IP"
done
$uri = "https://$clusterName.azurehdinsight.cn/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.cn/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.cn/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.chinacloudapi.cn
- 此值指示群集正在将 Azure 存储帐户用于默认存储。 值ACCOUNTNAME
是存储帐户的名称。CONTAINER
部分是存储帐户中 Blob 容器的名称。 容器是群集的 HDFS 兼容存储的根。abfs://CONTAINER@ACCOUNTNAME.dfs.core.chinacloudapi.cn
- 此值表示群集使用 Azure Data Lake Storage Gen2 作为默认存储。ACCOUNTNAME
和CONTAINER
值对于前面提到的 Azure 存储而言意义相同。若要查找 Data Lake Storage 帐户名称,请使用以下示例:
curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.cn/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.cn/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.cn/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.cn/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 cmdlet 也返回群集的存储信息。
获取所有配置
获取可用于群集的配置。
curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName?fields=Clusters/desired_configs"
$respObj = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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.cn/api/v1/clusters/$clusterName/configurations?type=livy2-conf&tag=INITIAL"
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/configurations?type=livy2-conf&tag=INITIAL" `
-Credential $creds -UseBasicParsing
$resp.Content
此示例返回的 JSON 文档包含 livy2-conf
组件的当前配置。
更新配置
创建
newconfig.json
。
进行修改,然后按如下所示输入命令:将
livy2-conf
替换为新组件。请将
INITIAL
替换为在获取所有配置中检索到的tag
实际值。A. Bash
curl -u admin:$password -sS -G "https://$clusterName.azurehdinsight.cn/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
,以反映 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.cn/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
元素,因为提交新配置时不需要这些元素。添加一个值为
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", .... }, }, } }
编辑
newconfig.json
。
打开newconfig.json
文档并在properties
对象中修改/添加值。 以下示例将"livy.server.csrf_protection.enabled"
的值从"true"
更改为"false"
。"livy.server.csrf_protection.enabled": "false",
完成修改后,保存该文件。
提交
newconfig.json
。
使用以下命令将更新的配置提交到 Ambari。curl -u admin:$password -sS -H "X-Requested-By: ambari" -X PUT -d @newconfig.json "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName"
$newConfig = Get-Content .\newconfig.json $resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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 服务才能使新配置生效。 使用以下步骤重新启动该服务。
使用以下命令启用 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.cn/api/v1/clusters/$clusterName/services/SPARK2"
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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"}}}'
验证维护模式
这些命令将 JSON 文档发送到启用了维护模式的服务器。 可以使用以下请求来验证服务当前是否处于维护模式:
curl -u admin:$password -sS -H "X-Requested-By: ambari" \ "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/services/SPARK2" \ | jq .ServiceInfo.maintenance_state
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/services/SPARK2" ` -Credential $creds -UseBasicParsing $respObj = ConvertFrom-Json $resp.Content $respObj.ServiceInfo.maintenance_state
返回值为
ON
。接下来,使用以下命令关闭 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.cn/api/v1/clusters/$clusterName/services/SPARK2"
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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
值正在使用群集节点的内部 IP 地址。 要从群集外部使用该地址,请将10.0.0.18:8080
部分替换为群集的 FQDN。验证请求。
编辑以下命令,将29
替换为上一步骤返回的id
实际值。 以下命令检索请求的状态:curl -u admin:$password -sS -H "X-Requested-By: ambari" \ "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/requests/29" \ | jq .Requests.request_status
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/requests/29" ` -Credential $creds -UseBasicParsing $respObj = ConvertFrom-Json $resp.Content $respObj.Requests.request_status
响应
COMPLETED
指示请求已完成。完成前一个请求后,使用以下命令启动 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.cn/api/v1/clusters/$clusterName/services/SPARK2"
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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
服务现在正在使用新配置。
最后,使用以下命令关闭维护模式。
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.cn/api/v1/clusters/$clusterName/services/SPARK2"
$resp = Invoke-WebRequest -Uri "https://$clusterName.azurehdinsight.cn/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 视图