Ambari 二次开发

本文的结构
1. Ambari 的工作原理
2. 一个简单的自定义 service
3. 添加 mertrics 到service
4. 发送数据给 metrics
5. 添加 config 到 service
6. 添加 alert 到 service
7. 其他需要修改源码实现的部分


Ambari 的工作原理

先看两张图,下面有对应的说明


ambari_工作过程.jpg

Ambari server 启动之后的的资源目录

service.png
  • 当用 Ambari server 启动的时候,Ambari Server 传送三类文件到 Ambari Agent上,分别是

    1. Stack 配置文件
    2. Service 的配置文件
    3. Service 生命周期的控制脚本(安装,配置,启动,停止,查询状态)
  • Agent 拿到配置文件后,会下载安装软件包。

  • 安装完成后,Ambari Server 会通知 Agent 去启动 Service。

  • Ambari Server 会定期发送命令到 Agent上, 来检查 Service 的状态; Agent 上报service数据给 Server,并呈现在 Ambari 的 GUI 上。

  • Ambari Server 支持 Rest API,这样可以很容易的扩展和定制 Ambari功能。


一个简单的自定义 Service

自定义service放在 /var/lib/ambari-server/resources/stacks/HDP/2.6/services目录下,这个目录下面有很多实例可以参考,还可以参考 公共service ,公共service的目录在/var/lib/ambari-server/resources/common-services

下面是我写的一个实例,先运行看一下,然后我们再分析配置的实现
  1. 这里先使用一个简单的实例---- HELLO_SERVICE(点开链接到 github上下载) ,将这个文件放在/var/lib/ambari-server/resources/stacks/HDP/2.6/services目录下。

  2. sudo ambari-server restart
    这个操作会将HELLO_SERVICE 传到agent上,至于传多少agent,就要看设置。

3.登录 ambari-server 界面,如图所示,添加service

add_service.png

4.选择 My Service test ,点击next,然后一路next 直到结束

My Service test.png

5.添加自定义service 之后的效果

添加自定义service 效果.png

6.自定义service的配置分析

  • 配置目录概览
 dotheright@master:/var/lib/ambari-server/resources/stacks/HDP/2.6/services/HELLO_SERVICE$ tree
├── metainfo.xml
└── package
   ├── archive.zip
    └── scripts
        ├── master.py
        └── slave.py
  • metainfo.xml 分析 ,见原文注释部分
dotheright@master:/var/lib/ambari-server/resources/stacks/HDP/2.6/services/HELLO_SERVICE$ cat metainfo.xml 
<?xml version="1.0" encoding="utf-8"?>
<metainfo> 
  <schemaVersion>2.0</schemaVersion>  
  <services> 
    <service> 
      <name>TEST</name>                      <!---服务名 -->
      <displayName>My service test</displayName>  
      <comment>My service test v1</comment>  
      <version>1.0</version>  
      <components> 
        <component> 
          <name>mymaster</name>              <!-- 给timeline使用的名字,要唯一 -->
          <displayName>my master</displayName>  
          <category>MASTER</category>     <!--表示在master上安装-->
          <cardinality>1</cardinality>  
          <commandScript> 
            <script>scripts/master.py</script>   <!-- master上使用的脚本 -->
            <scriptType>PYTHON</scriptType>  
            <timeout>3000</timeout> 
          </commandScript> 
        </component>  
        <component> 
          <name>myslave</name>            <!-- 给timeline使用的名字,要唯一 -->
          <displayName>my slave</displayName>  
          <category>SLAVE</category>   <!--表示在slave上安装-->
          <cardinality>1+</cardinality>      <!--表示至少在一个slave上安装--> 
          <commandScript> 
            <script>scripts/slave.py</script>  
            <scriptType>PYTHON</scriptType>  
            <timeout>3000</timeout> 
          </commandScript> 
        </component> 
      </components>  
      <osSpecifics> 
        <osSpecific> 
          <osFamily>redhat6,debian7,ubuntu12,ubuntu14,ubuntu16</osFamily>    <!-- 支持的 OS  -->
        </osSpecific> 
      </osSpecifics> 
    </service> 
  </services> 
</metainfo>
  • archive.zip 这个是发送前压缩的不用关注
  • master.py 文件包含安装,配置,启动,停止,各个状态中的具体代码需要根据实际需求来写
import os
import sys
from resource_management import Script

class Slave(Script):
    def install(self, env):
        print 'Install the Sample Slave';
        return 0;
    def stop(self, env):
        print 'Stop the Sample Slave';
        return 0;
    def start(self, env):
        print 'Start the Sample Slave';
        return 0;
    def status(self, env):
        print 'Status of the Sample Slave';
        return 0;
    def configure(self, env):
        print 'Configure the Sample Slave';
        return 0;

if __name__ == "__main__":
    Slave().execute()

  • slave.py 文件包含安装,配置,启动,停止,各个状态中的具体代码需要根据实际需求来写
import os
import sys
from resource_management import Script

class Master(Script):
    def install(self, env):
        print 'Install the Srv Master';
        return 0;
    def stop(self, env):
        print 'Stop the Srv Master';
        return 0;
    def start(self, env):
        print 'Start the Srv Master';
        return 0;
    def status(self, env):
        print 'Status of the Srv Master';
        return  0;
    def configure(self, env):
        print 'Configure the Srv Master';
        return  0;

if __name__ == "__main__":
    Master().execute()

添加 mertrics 到service

1 . 先看下目录结构

root@master:/var/lib/ambari-server/resources/stacks/HDP/2.6/services/HELLO_SERVICE# tree
.
├── metainfo.xml
├── metrics.json
├── package
│   ├── archive.zip
│   └── scripts
│       ├── master.py
│       └── slave.py
├── send.sh
└── widgets.json

相对于一个service增加的是 widgets.json ,metrics.json两个文件,修改了 metainfo.xml,send.sh 脚本是发送数据使用的。

  1. widgets.json 解析
root@master:/var/lib/ambari-server/resources/stacks/HDP/2.6/services/HELLO_SERVIroot@master:/var/lib/ambari-server/resources/stacks/HDP/2.6/services/HELLO_SERVICE# cat widgets.json 
{
    "layouts": [
        {
            "layout_name": "default_test_dashboard",
            "display_name": "Standard TEST Dashboard",
            "section_name": "TEST_SUMMARY",
            "widgetLayoutInfo": [
                {
                    "widget_name": "test_widget",
                    "description": "test widget",
                    "widget_type": "GRAPH",
                    "is_visible": true,
                    "metrics": [
                        {
                            "name": "test1",
                            "metric_path": "metrics/test1",
                            "service_name": "TEST",
                            "component_name": "myslave"
                        }
                    ],
                    "values": [
                        {
                            "name": "test1",
                            "value": "${test1}"
                        }
                    ],
                    "properties": {
                        "graph_type": "LINE",
                        "time_range": "1"
                    }
                }
            ]
        }
    ]
}

widget_type 可以配置的有三种类型:
1. GRAPH 时间序列图。
2. NUMBER 显示一个数值
3.GAUGE 显示百分比

不同的widgets.png

service_name: 和前面的service要对应
3.metrics.json 解析

root@master:/var/lib/ambari-server/resources/stacks/HDP/2.6/services/HELLO_SERVICE# cat metrics.json 
{
    "myslave": {
        "Component": [
            {
                "type": "ganglia",
                "metrics": {
                    "default": {
                        "metrics/test1": {
                            "metric": "test1",
                            "pointInTime": true,
                            "temporal": true
                        },
                        "metrics/test2": {
                            "metric": "test2",
                            "pointInTime": true,
                            "temporal": true
                        },
                        "metrics/test3": {
                            "metric": "test3",
                            "pointInTime": true,
                            "temporal": true
                        },
                        "metrics/test4": {
                            "metric": "test4",
                            "pointInTime": true,
                            "temporal": true
                        }
                    }
                }
            }
        ]
    }
}

4.metainfo.xml 上添加 timelineAppid

  <cardinality>1</cardinality>  
          <timelineAppid>myTLappid</timelineAppid>

5.重启 ambari-server 能看到对应的wedgit 已经添加成功。
重启:# ambari-server restart
添加成功的wedgit,但是此时的wegit 没有数据。


发送数据给 metrics

这里使用 send.sh脚本,对应的脚本内容

#!/bin/sh
url=http://$1:6188/ws/v1/timeline/metrics
while [ 1 ]
do
millon_time=$(( $(date +%s%N) / 1000000 ))
random=$(( $(date +%s) % 1000 ))
json="{
 \"metrics\": [
 {
 \"metricname\": \"$2\",
 \"appid\": \"$3\",
 \"hostname\": \"$1\",
 \"timestamp\": ${millon_time},
 \"starttime\": ${millon_time},
 \"metrics\": {
 \"${millon_time}\": ${random}
 }
 }
 ]
}"
  
echo $json 
curl -i -X POST -H "Content-Type: application/json" -d "${json}" ${url}
sleep 5
done
# ./send.sh master test1 myTLappid
# cd /var/lib/ambari-server/resources/stacks/HDP/2.6/services/HELLO_SERVICE

在 /var/lib/ambari-server/resources/stacks/HDP/2.6/services/HELLO_SERVICE
目录下,执行 ./send.sh master test1 myTLappid 。这个三个参数分别是,master:主机名,test1:mertrics 名,myTLappid :timeline的appid名称。然后能在widgets上看到有数据的图形。
注意:

在发送数据到metrics上之前,一定要保证 Metrics Collector service 开启


添加 config 到 service

1.添加config之后的目录结构

root@master:/var/lib/ambari-server/resources/stacks/HDP/2.6/services/HELLO_SERVICE# tree
.
├── configuration
│   └── ambari-server-env.xml
├── metainfo.xml
├── metrics.json
├── package
│   ├── archive.zip
│   └── scripts
│       ├── master.py
│       └── slave.py
├── send.sh
└── widgets.json

在service 目录下面增加了 configuration 目录,和配置文件ambari-server-env.xml

  1. config的配置文件
root@master:/var/lib/ambari-server/resources/stacks/HDP/2.6/services/HELLO_SERVICE# cat configuration/ambari-server-env.xml 
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration  supports_final="false">
    <property require-input="false">
        <name>AMBARI_USER</name>
        <value>admin</value>
        <description>Ambari Server user name</description>
        <on-ambari-upgrade add="true"/>
    </property>
    <property>
        <name>AMBARI_USER_PASSWORD</name>
        <value></value>
        <description>Ambari Server user password</description>
        <property-type>PASSWORD</property-type>
        <on-ambari-upgrade add="true"/>
    </property>
    <property brequire-input="false">
        <name>AMBARI_CLUSTER_NAME</name>
        <value>mycluster</value>
        <description>Ambari Cluster name</description>
        <on-ambari-upgrade add="true"/>
    </property>
    <property require-input="false">
        <name>AMBARI_SERVER_HOST</name>
        <value>master</value>
        <description>Ambari Server host name. Symphony will communicate with this host for integration</description>
        <on-ambari-upgrade add="true"/>
    </property>
    <property>
        <name>AMBARI_WEB_LISTEN_PORT</name>
        <value>8080</value>
        <description>Ambari WEB Server listen port. Symphony uses this port for communication with Ambari</description>
        <on-ambari-upgrade add="true"/>
    </property>
</configuration>

require-input="false" 可以取默认值,默认是true ,上面配置中 AMBARI_USER_PASSWORD 就是必须配置的,在service添加的时候,会有提醒,见下面安装service配置的效果图。

  1. 配置文件之后对应的python脚本也需要修改
    需要在启动的时候解析配置文件
def start(self, env):  # analysis service config 
    config = Script.get_config()
    AMBARI_USER =config['configurations']['ambari-server-env']['AMBARI_USER'] 
    AMBARI_USER_PWD =config['configurations']['ambari-server-env']['AMBARI_USER_PASSWORD'] 
    AMBARI_SERVER_HOST =config['configurations']['ambari-server-env']['AMBARI_SERVER_HOST'] 
    AMBARI_WEB_LISTEN_PORT = config['configurations']['ambari-server-env']['AMBARI_WEB_LISTEN_PORT'] 
    print "Ambari User:" + AMBARI_USER + " \nAmbari user password: " + AMBARI_USER_PWD + "\nServer: " +AMBARI_SERVER_HOST + "\nLinsten port " + str(AMBARI_WEB_LISTEN_PORT) 
    cmd = "mkdir -p /var/run/guoqingyao" 
    os.system(cmd) 
    print "start the service" 
    def stop(self, env): 
        cmd ="rm -rf /var/run/guoqingyao" 
        os.system(cmd) 
        print "stop the service" 
    def status(self, env):
        cmd = "echo 'check one time' > /tmp/my.log" 
        os.system(cmd) 
        cmd = "ls /var/run/guoqingyao" 
        result = os.system(cmd) 
        if result != 0: 
            print "The component is not runing"
  1. 。xml 文件也需要修改 在services 下面加入
    <configuration-dependencies>
    <config-type>ambari-server-env</config-type>
    </configuration-dependencies>

再次安装自定义服务的时候就需要输入相关的配置了。

Add_service_config.png

服务启动之后可以看到 配置文件

service_config.png

添加 alert 到 service

1.在service 目录下面添加 dotheright@master:~/mylovelycodes/ambari/Alert_SAMPLE$ cat alerts.json

{
    "ALERT_TEST": {
        "service": [],
        "MyKubernetes": [
            {
                "name": "MyKubernetes",
                "label": "My Kubernetes Alert",
                "description": "This is my Kubernetes alert.",
                "interval": 1,
                "scope": "ANY",
                "enabled": true,
                "source": {
                    "type": "PORT",
                    "uri": "{{slave:18888}}",
                    "default_port": 18888,
                    "reporting": {
                        "ok": {
                            "text": "TCP OK - {0:.3f}s response on port {1}"
                        },
                        "warning": {
                            "text": "TCP OK -{0:.3f}s response on port {1}",
                            "value": 1.5
                        },
                        "critical": {
                            "text": "Connection failed: {0} to {1}:{2}",
                            "value": 5.0
                        }
                    }
                }
            }
        ]
    } 
} 
  1. alert的效果
alert_效果.png
alert_detail.png

其他需要修改源码实现的部分

  1. dashbaord 里面添加metrics需要在源码中实现。
    对应的代码目录是 ambari-web/app/views/main/dashboard/widgets/,里面有很多已经实现的实例,比如

hbase_average_load.js
hbase_links.js
hbase_master_heap.js
hdfs_capacity.js
hdfs_links.js
links_widget.js
metrics_cpu.js

  1. hosts的metrics需要修改源码实现。
    hosts的metrics 是从dashbaord中指定的。
host_metrics.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,672评论 18 139
  • Ambari安装 1 Ambari简介 Apache Ambari项目的目的是通过开发软件来配置、监控和管理had...
    CobubRazor阅读 4,928评论 2 3
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,827评论 6 342
  • 七月与安生。 踩着一个人的影子走, 就永远不会走远。 今天南昌刮大风,晚上去看了七月与安生,昏昏沉沉睡到下...
    人间和酒阅读 558评论 0 1
  • 岁月的弧线不经意撵开了记忆的闸门,遇见只一瞬的光阴却在那一刻快门被按下的瞬间留作永恒的纪念!胶片可以留住记忆,记忆...
    子墨兰轩阅读 180评论 0 1