ambari二次开发分享(四)
目录
为自定义服务添加主题配置
自定义服务配置主题步骤
根据这个图片的包含关系可以对应下面我们的内容,最好命名的时候也按照这个规则进行命名,参考下面的配置文件
修改metainfo.xml添加themes元素来定义主题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<themes-dir>themes</themes-dir>
<themes>
<theme>
<fileName>theme_elasticsearch_version_4.json</fileName>
<default>true</default>
</theme>
</themes>
2. theme.json文件主要结构
```json
{
"name": "default",
"description": "Default theme for Elasticsearch service",
"configuration": {
"layouts": [
...
],
"placement": {
...
},
"widgets": [
...
]
}
}这里的layouts主要是设置布局:section、sub-section
placement:将配置项填充或放置到 sub-section 中
widgets:UI 控件。控制着每一个配置的 UI 样式
主题文件解读
自定义服务的主题由 json 文件约束,主要分为三个部分:
- placement:控件填充到页面上。可控制逻辑、多级联动等。
- widgets:每个配置的页面显示样式。
- layouts:页面的控件布局。
placement:将配置项填充或放置到 sub-section 中。着重说一下 configs 的相关信息:
- config:设置自定义服务的配置属性名称。比如:elastic-config/bootstrap_memory_lock,表示添加 elastic-config.xml 文件里的 bootstrap_memory_lock 配置项到子部分里面。
- subsection-name:子部分的名称。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49"placement": {
"configuration-layout": "default",
"configs": [
{
"config": "elastic-config/path_data",
"subsection-name": "subsection-es-dir-col1"
},
{
"config": "elastic-config/gateway_recover_after_nodes",
"subsection-name": "subsection-es-num-col1"
},
{
"config": "elastic-config/node_max_local_storage_nodes",
"subsection-name": "subsection-es-num-col2"
},
{
"config": "elastic-config/bootstrap_memory_lock",
"subsection-name": "subsection-es-memory-col1"
},
{
"config": "elastic-config/bootstrap_system_call_filter",
"subsection-name": "subsection-es-memory-col1"
},
{
"config": "elastic-config/http_cors_enabled",
"subsection-name": "subsection-es-requires-col1"
},
{
"config": "elastic-config/zookeeper.session.timeout",
"subsection-name": "subsection-es-requires-col1"
},
{
"config": "elastic-config/action_destructive_requires_name",
"subsection-name": "subsection-es-various-col1"
},
{
"config": "elastic-config/hbase.hregion.majorcompaction",
"subsection-name": "subsection-es-various-col1"
},
{
"config": "elastic-config/ping_timeout_default",
"subsection-name": "subsection-es-timeout-col1"
},
{
"config": "elastic-config/discovery_zen_ping_timeout",
"subsection-name": "subsection-es-timeout-col2"
}
]
}widgets:主要是约束配置项在页面上的显示样式。
config:设置自定义服务的配置项。比如:elastic-config/bootstrapmemorylock,表示 elastic-config.xml 文件里的 bootstrap_memory_lock 配置项。
widget:
- type:配置项在页面上显示的形式。可以指定样式,类型有:text-field(普通文本框)、toggle(滑块按钮)、directories(目录文本框)、slider(滑杆)、combo(下拉框)、password(密码文本框) 、time-interval-spinner(时间微调器)等等。
对于 slider 来说,还可以设置单位:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93"widgets": [
{
"config": "elastic-config/path_data",
"widget": {
"type": "directories"//目录文本框
}
},
{
"config": "elastic-config/gateway_recover_after_nodes",
"widget": {
"type": "slider",
"units": [
{
"unit-name": "int"
}
]
}
},
{
"config": "elastic-config/node_max_local_storage_nodes",
"widget": {
"type": "slider",
"units": [
{
"unit-name": "int"
}
]
}
},
{
"config": "elastic-config/bootstrap_memory_lock",
"widget": {
"type": "toggle"
}
},
{
"config": "elastic-config/bootstrap_system_call_filter",
"widget": {
"type": "toggle"
}
},
{
"config": "elastic-config/http_cors_enabled",
"widget": {
"type": "toggle"
}
},
{
"config": "elastic-config/zookeeper.session.timeout",
"widget": {
"type": "time-interval-spinner",
"units": [
{
"unit-name": "minutes,seconds"
}
]
}
},
{
"config": "elastic-config/action_destructive_requires_name",
"widget": {
"type": "toggle"
}
},
{
"config": "elastic-config/hbase.hregion.majorcompaction",
"widget": {
"type": "time-interval-spinner",
"units": [
{
"unit-name": "days,hours"
}
]
}
},
{
"config": "elastic-config/ping_timeout_default",
"widget": {
"type": "toggle"
}
},
{
"config": "elastic-config/discovery_zen_ping_timeout",
"widget": {
"type": "slider",
"units": [
{
"unit-name": "int"
}
]
}
}
]
这里的config需要和上面的palcement中的内容保持一致
修改xml配置文件中对应的配置项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<property>
<name>bootstrap_memory_lock</name>
<display-name>Bootstrap memory lock</display-name>
<value>false</value>
<description>Whether memory is locked on elasticsearch startup</description>
<value-attributes>
<overridable>false</overridable>
<type>value-list</type>
<entries>
<entry>
<value>true</value>
<label>ON</label>
</entry>
<entry>
<value>false</value>
<label>OFF</label>
</entry>
</entries>
<selection-cardinality>1</selection-cardinality>
</value-attributes>在property标签下面添加下面的配置:
- toggle(滑块按钮)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<value-attributes>
<overridable>false</overridable>
<type>value-list</type>
<entries>
<entry>
<value>true</value>
<label>ON</label>
</entry>
<entry>
<value>false</value>
<label>OFF</label>
</entry>
</entries>
<selection-cardinality>1</selection-cardinality>
</value-attributes>- directories(目录文本框)
1
2
3<value-attributes>
<type>directories</type>
</value-attributes>- slider(滑杆)
1
2
3
4
5
6<value-attributes>
<type>int</type>
<minimum>0</minimum>
<maximum>6</maximum>
<increment-step>1</increment-step>
</value-attributes>- combo(下拉框)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<value-attributes>
<type>value-list</type>
<entries>
<entry>
<value>sqlite3</value>
<label>SQLite</label>
</entry>
<entry>
<value>Existing MySQL Database</value>
<label>Existing MySQL Database</label>
</entry>
<entry>
<value>oracle</value>
<label>Oracle</label>
</entry>
<entry>
<value>postgresql_psycopg2</value>
<label>PostgreSQL</label>
</entry>
</entries>
<selection-cardinality>1</selection-cardinality>
</value-attributes>- password(密码文本框)
1
2
3
4<property-type>PASSWORD</property-type>
<value-attributes>
<type>password</type>
</value-attributes>- 复选框
1
2
3<value-attributes>
<type>boolean</type>
</value-attributes>- time-interval-spinner 时间间隔微调器
1
2
3
4
5
6
7<value-attributes>
<type>int</type>
<minimum>10000</minimum>
<maximum>180000</maximum>
<unit>milliseconds</unit>
<increment-step>10000</increment-step>
</value-attributes>layout(布局):布局下可以包含多个 tab ,layouts/tabs/layout 里面的 tab-rows 和 tab-columns 控制着整个布局的 高度 和 宽度 。比如值都为 6 ,就表示 6 行、6列。
layouts/tabs/layout 里面的 sections 描述着每个控件的基本信息:
- name:控件的名称,唯一。
- display-name:控件在页面上显示的名称。
- row-index 和 column-index:定义位置。分别表示 行的顺序 和 列的顺序,从 0 开头。
- row-span 和 column-span:定义大小。分别表示该部分占整个布局的 高度 和 宽度。
- section-rows 和 section-columns:定义 subsection 的网格布局。占几行、几列。比如值为 1 和 2 ,就代表占 1 行 2 列。
- subsections:用来描述子控件的基本信息。这里的subseciton-rows 和前面的placement中的subsection-name对应
调试主题配置文件
- 卸载对应组件
- 替换theme.json文件
- 重启ambari-server服务
- 重新安装服务
- 查看当前的主题配置样式
检查服务运行状态以及为服务添加自定义命令
检查服务运行状态(run service check)
在metainfo.xml中添加如下配置
这里的这个commandScript的标签是在service下面的,其他地方还有这种标签,但是这里的标签需要在service下面一级
1
2
3
4
5<commandScript>
<script>scripts/service_check.py</script>
<scriptType>PYTHON</scriptType>
<timeout>1800</timeout>
</commandScript>创建service_check.py文件
这里需要注意的是这里的这个方法名字必须是service_check
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20from resource_management import *
from elastic_common import kill_process
from time import sleep
from resource_management.core.logger import Logger
class service_check(Script):
def service_check(self, env):
import params
env.set_params(params)
Logger.info("******** check elasticsearch process ********")
sleep(15)
# cmd = format('cat {elastic_pid_dir}/elasticsearch.pid')
cmd = format('curl {elasticsearch_service_host}:{elasticsearch_port}')
Execute(cmd, user=params.elastic_user)
Logger.info("check successfully!")
if __name__ == "__main__":
service_check().execute()
这里的逻辑就是去curl一下这个es的port
部署
以 HDP 3.1的 Elasticsearch 服务为例,将其拷贝到 /var/lib/ambari-server/resources/stacks/HDP/3.1/ELASTICSEARCH 中,然后重启 ambari-server 服务。
访问 Ambari Web 页面,在 Elasticsearch 服务面板的右上角 “操作” 按钮上,就增加了 run service check 按钮。
当重新安装 Elasticsearch 服务的时候,在最后的步骤就是 Check Elasticsearch 检查服务运行状态。
添加自定义命令(Test Head Check / Test Master Check)
metainfo.xml中添加如下配置
1
2
3
4
5
6
7
8
9
10<customCommands>
<customCommand>
<name>test_master_check</name>
<background>true</background>
<commandScript>
<script>scripts/master.py</script>
<scriptType>PYTHON</scriptType>
</commandScript>
</customCommand>
</customCommands>这里添加的配置是在组件的下面,每个组件下面添加这个自定义命令
这里的
<commandScript>/<script>
与对应组件的服务主程序的名称需要相同编辑matser.py
在 master.py 文件内添加 test_master_check() 方法
这里的这个方法名与前面配置中的方法名要一致
1
2
3
4
5def test_master_check(self, env):
import params
env.set_params(params)
Logger.info("******** custom process ********")
Logger.info("custom elasticsearch service successfully!")部署
以 Elasticsearch 服务为例,将其拷贝到 /var/lib/ambari-server/resources/stacks/HDP/3.1/ELASTICSEARCH 中,然后重启 ambari-server 服务。
调整各服务,各组件启动顺序
组件之间存在着依赖关系,我们有时候必须先启动哪些组件的服务,才能再启动哪些组件的服务,否则就会出现报错
修改metainfo.xml文件
首先我们需要在metainfo.xml文件中添加如下配置:
1
2
3<requiredServices>
<service>ZOOKEEPER</service>
</requiredServices>这里的意思就是在安装这个组件之前需要先安装一下zookeeper组件
role_command_order.json
这里需要在
/var/lib/ambari-server/resources/common-services
目录下创建一个创建role_command_order.json文件,这个文件中的内容是启动组件的顺序,(必须先启动value值再启动key值),这里以es的这个文件为例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20{
"general_deps": {
"ELASTICSEARCH_SERVICE-INSTALL": [
"ZOOKEEPER_SERVER-INSTALL"
],
"ELASTICSEARCH_HEAD-INSTALL": [
"ELASTICSEARCH_SERVICE-INSTALL"
],
"ELASTICSEARCH_SERVICE-START": [
"ELASTICSEARCH_HEAD-START"
],
"ELASTICSEARCH_HEAD-START": [
"ZOOKEEPER_SERVICE_CHECK-SERVICE_CHECK",
"ZOOKEEPER_QUORUM_SERVICE_CHECK-SERVICE_CHECK"
],
"ELASTICSEARCH_SERVICE_CHECK-SERVICE_CHECK": [
"ELASTICSEARCH_SERVICE-START"
]
}
}这里的意思表示的是:
在执行 ELASTICSEARCH_SERVICE 组件安装之前,需要先完成 ZOOKEEPER_SERVER 组件的安装。
在执行 ELASTICSEARCH_HEAD 组件安装之前,需要先完成 ELASTICSEARCH_SERVICE 组件的安装。
在执行 ELASTICSEARCH_SERVICE 组件启动之前,需要先完成 ZOOKEEPER 和 ZOOKEEPER_QUORUM 服务检测。
在执行 ELASTICSEARCH_HEAD 组件启动之前,需要先完成 ELASTICSEARCH_SERVICE 组件的启动。
在执行 ELASTICSEARCH 服务检测之前,需要先完成 ELASTICSEARCH_HEAD 组件的启动。
COMMAND
目前ambari支持的命令有:
- INSTALL
- UNINSTALL
- START
- RESTART
- STOP
- EXECUTE
- ABORT
- UPGRADE
- SERVICE_CHECK
- CUSTOM_COMMAND
- ACTIONEXECUTE
这里的意思使用到的时候建议查询相关资料,有一些内容目前还没进行测试
部署
- 替换原先的ole_command_order.json
- 删除服务和服务依赖的服务
- 重启ambari-server服务
- 重新安装服务和依赖服务
- 验证