概述
背景
Stack 定义位于源代码树中的 <a href="https://github.com/apache/ambari/tree/trunk/ambari-server/src/main/resources/stacks">/ambari-server/src/main/resources/stacks</a>。安装 Ambari Server 后,Stack 定义位于 /var/lib/ambari-server/resources/stacks
结构
Stack 定义的结构如下:
|_ stacks
|_
|_
metainfo.xml
|_ hooks
|_ repos
repoinfo.xml
|_ services
|_
metainfo.xml
metrics.json
|_ configuration
{configuration files}
|_ package
{files, scripts, templates}
定义服务和组件
服务中的 metainfo.xml 文件描述服务、服务组件以及用于执行命令的管理脚本。服务组件可以属于 MASTER、SLAVE 或 CLIENT 类别。
For each Component you specify the <commandScript> to use when executing commands. There is a defined set of default commands the component must support.
| 组件类别 | 默认生命周期命令 |
|---|---|
| MASTER | install, start, stop, configure, status |
| SLAVE | install, start, stop, configure, status |
| CLIENT | install, configure, status |
Ambari 支持使用 PYTHON 编写的命令脚本。该类型用于确定如何执行命令脚本。如果组件需要支持默认生命周期命令之外的命令,也可以创建自定义命令。
例如,YARN 服务在 metainfo.xml:
<component>
<name>RESOURCEMANAGER</name>
<category>MASTER</category>
<commandScript>
<script>scripts/resourcemanager.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
<customCommands>
<customCommand>
<name>DECOMMISSION</name>
<commandScript>
<script>scripts/resourcemanager.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</customCommand>
</customCommands>
</component>
ResourceManager 是 MASTER 组件,其命令脚本为 <a href="https://github.com/apache/ambari/blob/trunk/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/resourcemanager.py">scripts/resourcemanager.py</a>, ,它位于 services/YARN/package 目录中。该命令脚本是 PYTHON,并以 Python 方法实现默认生命周期命令。以下是默认 INSTALL 命令的 install 方法:
class Resourcemanager(Script):
def install(self, env):
self.install_packages(env)
self.configure(env)
还可以看到定义了 DECOMMISSION 自定义命令,这意味着该 Python 命令脚本中也有 decommission 方法:
def decommission(self, env):
import params
...
Execute(yarn_refresh_cmd,
user=yarn_user
)
pass
使用 Stack 继承
Stack 可以 扩展 其他 Stack,以共享命令脚本和配置。这可以通过以下方式减少不同 Stack 之间的代码重复:
- 为子 Stack 定义仓库
- 在子 Stack 中添加新服务(不在父 Stack 中)
- 覆盖父服务的命令脚本
- 覆盖父服务的配置
例如,HDP 2.1 Stack 扩展 HDP 2.0.6 Stack,因此该定义中仅包含适用于 HDP 2.1 Stack 的更改。此扩展在 HDP 2.1 Stack 的 metainfo.xml 中定义:
<metainfo>
<versions>
<active>true</active>
</versions>
<extends>2.0.6</extends>
</metainfo>
示例:实现自定义服务
在本示例中,我们将创建名为 “SAMPLESRV” 的自定义服务,并将其添加到现有 Stack 定义中。该服务包含 MASTER、SLAVE 和 CLIENT 组件。
Create and Add the Service
- 在 Ambari Server 上,转到
/var/lib/ambari-server/resources/stacks/HDP/2.0.6/services目录。本例中,我们将转到 HDP 2.0 Stack 定义。
cd /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services
- 创建目录
/var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/<strong>SAMPLESRV</strong>,用于存放 SAMPLESRV 的服务定义。
mkdir /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/SAMPLESRV
cd /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/SAMPLESRV
- 转到新创建的
SAMPLESRV目录,创建描述新服务的metainfo.xml文件。例如:
<?xml version="1.0"?>
<metainfo>
<schemaVersion>2.0</schemaVersion>
<services>
<service>
<name>SAMPLESRV</name>
<displayName>New Sample Service</displayName>
<comment>A New Sample Service</comment>
<version>1.0.0</version>
<components>
<component>
<name>SAMPLESRV_MASTER</name>
<displayName>Sample Srv Master</displayName>
<category>MASTER</category>
<cardinality>1</cardinality>
<commandScript>
<script>scripts/master.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</component>
<component>
<name>SAMPLESRV_SLAVE</name>
<displayName>Sample Srv Slave</displayName>
<category>SLAVE</category>
<cardinality>1+</cardinality>
<commandScript>
<script>scripts/slave.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</component>
<component>
<name>SAMPLESRV_CLIENT</name>
<displayName>Sample Srv Client</displayName>
<category>CLIENT</category>
<cardinality>1+</cardinality>
<commandScript>
<script>scripts/sample_client.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</component>
</components>
<osSpecifics>
<osSpecific>
<osFamily>any</osFamily> <!-- note: use osType rather than osFamily for Ambari 1.5.0 and 1.5.1 -->
</osSpecific>
</osSpecifics>
</service>
</services>
</metainfo>
- 在上面的配置中,服务名称为 " SAMPLESRV", ,其中包含:
- 一个 MASTER 组件 " SAMPLESRV_MASTER"
- 一个 SLAVE 组件 " SAMPLESRV_SLAVE"
- 一个 CLIENT 组件 " SAMPLESRV_CLIENT"
- 接下来创建命令脚本。创建命令脚本目录
/var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/SAMPLESRV/**package/scripts**,该目录已在服务元信息中指定。
mkdir -p /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/SAMPLESRV/package/scripts
cd /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/SAMPLESRV/package/scripts
- 转到脚本目录并创建
.py命令脚本文件。例如master.py文件:
import sys
from resource_management import *
class Master(Script):
def install(self, env):
print 'Install the Sample Srv Master';
def stop(self, env):
print 'Stop the Sample Srv Master';
def start(self, env):
print 'Start the Sample Srv Master';
def status(self, env):
print 'Status of the Sample Srv Master';
def configure(self, env):
print 'Configure the Sample Srv Master';
if __name__ == "__main__":
Master().execute()
例如 slave .py 文件:
import sys
from resource_management import *
class Slave(Script):
def install(self, env):
print 'Install the Sample Srv Slave';
def stop(self, env):
print 'Stop the Sample Srv Slave';
def start(self, env):
print 'Start the Sample Srv Slave';
def status(self, env):
print 'Status of the Sample Srv Slave';
def configure(self, env):
print 'Configure the Sample Srv Slave';
if __name__ == "__main__":
Slave().execute()
例如 sample_client .py 文件:
import sys
from resource_management import *
class SampleClient(Script):
def install(self, env):
print 'Install the Sample Srv Client';
def configure(self, env):
print 'Configure the Sample Srv Client';
if __name__ == "__main__":
SampleClient().execute()
- 现在,重启 Ambari Server,使新的服务定义分发到集群中的所有代理。
ambari-server restart
安装服务(通过 Ambari Web“添加服务”)
通过 Ambari Web 添加自定义服务是 Ambari 1.7.0 的新功能。
-
在 Ambari Web 中转到“服务”,然后点击左侧服务导航区域中的 Actions 按钮。
-
“添加服务”向导启动。您将看到包含“My Sample Service”的选项(这是服务
metainfo.xml文件中定义的<displayname></displayname>)。 -
Select "My Sample Service" and click Next.
-
Assign the "Sample Srv Master" and click Next.
-
选择要安装“Sample Srv Client”的主机,然后点击“下一步”。
-
完成后,“My Sample Service”将显示在服务导航区域中。
-
如果要将“Sample Srv Client”添加到主机,可转到“主机”,导航到特定主机,然后点击“+ 添加”。
Example: Implementing a Custom Client-only Service
在本示例中,我们将创建名为“TESTSRV”的自定义服务,将其添加到现有 Stack 定义,并使用 Ambari API 安装/配置该服务。此服务是 CLIENT,因此包含两个命令:install 和 configure。
Create and Add the Service
- 在 Ambari Server 上,转到
/var/lib/ambari-server/resources/stacks/HDP/2.0.6/services目录。本例中,我们将转到 HDP 2.0 Stack 定义。
cd /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services
- 创建目录
/var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/<strong>TESTSRV</strong>that will contain the service definition for TESTSRV.
mkdir /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTSRV
cd /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTSRV
- Browse to the newly created
TESTSRVdirectory, create ametainfo.xmlfile that describes the new service. For example:
<?xml version="1.0"?>
<metainfo>
<schemaVersion>2.0</schemaVersion>
<services>
<service>
<name>TESTSRV</name>
<displayName>New Test Service</displayName>
<comment>A New Test Service</comment>
<version>0.1.0</version>
<components>
<component>
<name>TEST_CLIENT</name>
<displayName>New Test Client</displayName>
<category>CLIENT</category>
<cardinality>1+</cardinality>
<commandScript>
<script>scripts/test_client.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
<customCommands>
<customCommand>
<name>SOMETHINGCUSTOM</name>
<commandScript>
<script>scripts/test_client.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</customCommand>
</customCommands>
</component>
</components>
<osSpecifics>
<osSpecific>
<osFamily>any</osFamily> <!-- note: use osType rather than osFamily for Ambari 1.5.0 and 1.5.1 -->
</osSpecific>
</osSpecifics>
</service>
</services>
</metainfo>
-
在上面的配置中,服务名称为 " TESTSRV", and it contains one component " TEST_CLIENT" that is of component category " CLIENT". That client is managed via the command script
scripts/test_client.py. Next, let's create that command script. -
Create a directory for the command script
/var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTSRV/package/scripts,该目录已在服务元信息中指定。
mkdir -p /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTSRV/package/scripts
cd /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTSRV/package/scripts
- Browse to the scripts directory and create the
test_client.pyfile. For example:
import sys
from resource_management import *
class TestClient(Script):
def install(self, env):
print 'Install the client';
def configure(self, env):
print 'Configure the client';
def somethingcustom(self, env):
print 'Something custom';
if __name__ == "__main__":
TestClient().execute()
- 现在,重启 Ambari Server,使新的服务定义分发到集群中的所有代理。
ambari-server restart
安装服务(通过 Ambari REST API)
- 将服务添加到集群。
POST
/api/v1/clusters/MyCluster/services
{
"ServiceInfo": {
"service_name":"TESTSRV"
}
}
- 将组件添加到服务。本例中,将 TEST_CLIENT 添加到 TESTSRV。
POST
/api/v1/clusters/MyCluster/services/TESTSRV/components/TEST_CLIENT
- 在所有目标主机上安装组件。例如,要在
c6402.ambari.apache.org和c6403.ambari.apache.org上安装,首先使用 POST 在主机上创建 host_component 资源。
POST
/api/v1/clusters/MyCluster/hosts/c6402.ambari.apache.org/host_components/TEST_CLIENT
POST
/api/v1/clusters/MyCluster/hosts/c6403.ambari.apache.org/host_components/TEST_CLIENT
- 现在让 Ambari 在所有主机上安装组件。此单个命令会指示 Ambari 安装与服务相关的所有组件,并在每台主机上调用命令脚本中的
install()方法。
PUT
/api/v1/clusters/MyCluster/services/TESTSRV
{
"RequestInfo": {
"context": "Install Test Srv Client"
},
"Body": {
"ServiceInfo": {
"state": "INSTALLED"
}
}
}
- 或者,可以不同时安装所有组件,而是显式安装每个主机组件。本例中,我们将显式在
c6402.ambari.apache.org上安装 TEST_CLIENT:
PUT
/api/v1/clusters/MyCluster/hosts/c6402.ambari.apache.org/host_components/TEST_CLIENT
{
"RequestInfo": {
"context":"Install Test Srv Client"
},
"Body": {
"HostRoles": {
"state":"INSTALLED"
}
}
}
- 使用以下方式在主机上配置客户端。这最终会调用命令脚本中的
configure()方法。
POST
/api/v1/clusters/MyCluster/requests
{
"RequestInfo" : {
"command" : "CONFIGURE",
"context" : "Config Test Srv Client"
},
"Requests/resource_filters": [{
"service_name" : "TESTSRV",
"component_name" : "TEST_CLIENT",
"hosts" : "c6403.ambari.apache.org"
}]
}
- 如需查看组件安装在哪些主机上。
GET
/api/v1/clusters/MyCluster/components/TEST_CLIENT
安装服务(通过 Ambari Web“添加服务”)
通过 Ambari Web 添加自定义服务是 Ambari 1.7.0 的新功能。
-
在 Ambari Web 中转到“服务”,然后点击左侧服务导航区域中的 Actions 按钮。
-
“添加服务”向导启动。您将看到包含“My Test Service”的选项(这是服务
metainfo.xml文件中定义的<displayname></displayname>)。 -
选择“My Test Service”,然后点击“下一步”。
-
选择要安装“New Test Client”的主机,然后点击“下一步”。
-
完成后,“My Test Service”将显示在服务导航区域中。
-
如果要将“New Test Client”添加到主机,可转到“主机”,导航到特定主机,然后点击“+ 添加”。
示例:实现自定义客户端服务(带配置)
在本示例中,我们将创建名为“TESTCONFIGSRV”的自定义服务,并将其添加到现有 Stack 定义。此服务是 CLIENT,因此包含两个命令:install 和 configure。该服务还包含配置类型“test-config”。
创建服务并将其添加到 Stack
- 在 Ambari Server 上,转到
/var/lib/ambari-server/resources/stacks/HDP/2.0.6/services目录。本例中,我们将转到 HDP 2.0 Stack 定义。
cd /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services
- 创建目录
/var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/<strong>TESTCONFIGSRV</strong>,用于存放 TESTCONFIGSRV 的服务定义。
mkdir /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTCONFIGSRV
cd /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTCONFIGSRV
- 转到新创建的
TESTCONFIGSRV目录,创建描述新服务的metainfo.xml文件。例如:
2.0
TESTCONFIGSRV
New Test Config Service
A New Test Config Service
0.1.0
TESTCONFIG_CLIENT
New Test Config Client
CLIENT
1+
scripts/test_client.py
PYTHON
600
any
-
在上面的配置中,服务名称为“TESTCONFIGSRV”,包含一个组件“TESTCONFIG_CLIENT”,其组件类别为“CLIENT”。该客户端通过命令脚本
scripts/test_client.py管理。接下来创建该命令脚本。 -
创建服务元信息
<commandscript></commandscript>中指定的命令脚本目录/var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTCONFIGSRV/package/scripts。
mkdir -p /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTCONFIGSRV/package/scripts
cd /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTCONFIGSRV/package/scripts
- 转到脚本目录并创建
test_client.py文件。例如:
import sys
from resource_management import *
class TestClient(Script):
def install(self, env):
print 'Install the config client';
def configure(self, env):
print 'Configure the config client';
if __name__ == "__main__":
TestClient().execute()
- 现在为此服务定义配置类型。为配置字典文件创建目录
/var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTCONFIGSRV/configuration。
mkdir -p /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTCONFIGSRV/configuration
cd /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/TESTCONFIGSRV/configuration
- 转到配置目录并创建
test-config.xml文件。例如:
some.test.property
this.is.the.default.value
This is a kool description.
- 现在,重启 Ambari Server,使新的服务定义分发到集群中的所有代理。
ambari-server restart