ambari集成第三方应用

背景:最近遇到一个需求,公司运维人员可以通过ambari界面addservice按钮添加、启动、停止我们公司的系统,就花时间研究了一下ambari的集成。

步骤:万事皆套路,ambari集成也同样,一是告诉ambari我加添加什么服务,二是告诉ambari我的服务在哪并且怎么加载的。下面我就按照这两个步骤来说明详细过程。

一、告诉ambari我添加什么服务。

首先要在/var/lib/ambari-server/resources/stacks/HDP/3.1/services路径下添加服务名称,新建一个服务名称文件夹名称为要添加的服务的名称,如下图新建APISERVICE服务

然后添加说明文件metainfo.xml,

文件内容为xml格式,包括服务名称、版本、相对路径:

 

二、告诉ambari我的服务在哪并且怎么加载的。

首先在/var/lib/ambari-server/resources/common-services文件夹下面定义服务的操作步骤,如图所示,也是同样要创建一个服务名称的文件夹。

创建上文xml中定义的路径如:APISERVICE/1.0这个文件夹。

在这个文件夹1.0下面就是要按照套路来创建相应名称的目录或者文件了,如下图所示:

这里面metainfo.xml、master.py、params.py是必须的而且目录结构必须是这样的。

下面来看一下metainfo.xml里面的内容:

<?xml version="1.0"?>
<metainfo>
    <schemaVersion>2.0</schemaVersion>
    <services>
        <service>
            <name>APISERVICE</name>
            <displayName>API Service</displayName>
            <comment>api service</comment>
            <version>1.0</version>
            <components>
                <component>
                    <name>APICOMPONENT</name>
                    <displayName>API Component</displayName>
                    <category>MASTER</category>
                    <cardinality>1</cardinality>
                    <commandScript>
                        <script>scripts/master.py</script>
                        <scriptType>PYTHON</scriptType>
                        <timeout>600</timeout>
                    </commandScript>
                </component>
            </components>
            <osSpecifics>
                <osSpecific>
                  <osFamily>any</osFamily>
                </osSpecific>
            </osSpecifics>
            <monitoringService>false</monitoringService>
        </service>
    </services>
</metainfo>

这里规定了服务的名称,以及该服务拥有组件的名称还有添加组件要执行的python脚本。

这里的master.py脚本也是固定的要实现几个方法,比如配置、安装、启动、停止等方法。

#!/usr/bin/env python

"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import sys
import os
import glob
import pwd
import grp
import signal
import time
from resource_management import *
from api_common import kill_process

class Master(Script):

    # Install apisearch
    def install(self, env):
        # Import properties defined in -config.xml file from the params class
        import params

        # This allows us to access the params.api_pid_file property as
        # format('{api_pid_file}')
        env.set_params(params)

        # Install dependent packages
        self.install_packages(env)

        # Create user and group for api if they don't exist
        try: grp.getgrnam(params.api_group)
        except KeyError: Group(group_name=params.api_group)

        try: pwd.getpwnam(params.api_user)
        except KeyError: User(username=params.api_user,
                              gid=params.api_group,
                              groups=[params.api_group],
                              ignore_failures=True
                              )

        # Create api directories
        Directory([params.api_base_dir, params.api_pid_dir],
                  mode=0755,
                  cd_access='a',
                  owner=params.api_user,
                  group=params.api_group,
                  create_parents=True
                  )


        # Download apisearch
        cmd = format("cd {api_base_dir}; wget {api_download} -O api.tar.gz")
        Execute(cmd, user="root")

        cmd1 = format("cd {api_base_dir}; tar -zvxf api.tar.gz")
        Execute(cmd1, user="root")

        cmd2 = format("cd {api_base_dir}; rm api.tar.gz")
        Execute(cmd2, user=params.api_user)

        Execute('echo "Install complete"')


    def configure(self, env):
        # Import properties defined in -config.xml file from the params class
        import params

        # This allows us to access the params.api_pid_file property as
        # format('{api_pid_file}')
        env.set_params(params)

        Execute('echo "Configuration complete"')

    def stop(self, env):
        # Import properties defined in -config.xml file from the params class
        import params

        # Import properties defined in -env.xml file from the status_params class
        import status_params

        # This allows us to access the params.api_pid_file property as
        #  format('{api_pid_file}')
        env.set_params(params)

        # Stop apisearch
        kill_process(params.api_pid_file, user="root")
        #cmd = format("kill `cat {api_pid_file}`")
        #Execute(cmd, user=params.api_user, only_if=format("test -f {api_pid_file}"))


    def start(self, env):
        # Import properties defined in -config.xml file from the params class
        import params

        # This allows us to access the params.api_pid_file property as
        #  format('{api_pid_file}')
        env.set_params(params)

        # Configure apisearch
        self.configure(env)

        # Start apisearch
        cmd = format("cd {api_base_dir};sh apiservice.sh {api_pid_file} {api_zk}")
        Execute(cmd, user="root")


    def status(self, env):
        # Import properties defined in -env.xml file from the status_params class
        import status_params

        # This allows us to access the params.api_pid_file property as
        #  format('{api_pid_file}')
        env.set_params(status_params)

        #try:
        #    pid_file = glob.glob(status_params.api_pid_file)[0]
        #except IndexError:
        #    pid_file = ''

        # Use built-in method to check status using pidfile
        check_process_status(status_params.api_pid_file)

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

这里有个apiservice.sh是我自己用shell脚本实现的启动脚本,其实很简单,一共三部分,第一部分执行要不就是执行Java -jar/-cp或者就是执行sh xx.sh脚本,第二部分就是或者App的进程id,第三部分就是把进程id写到文件里,待停止的时候利用。

#!/bin/sh
unzip xx.zip
dir=`unzip -l xx.zip | awk 'NR==4{print $4}'`
(cd $dir"bin";nohup ./api -z $2 &)
sleep 5 &
wait
pid=`ps -ef | grep $dir | grep -v grep | awk '{print $2}' | awk NR==1`
echo $pid > $1

params.py的内容:

#!/usr/bin/env python

"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from resource_management import *
import os

# config object that holds the configurations declared in the -config.xml file
config = Script.get_config()

java64_home = config['hostLevelParams']['java_home']

hostname = config['hostname']

api_user = config['configurations']['api-env']['api_user']
api_group = config['configurations']['api-env']['api_group']

api_base_dir = config['configurations']['api-env']['api_base_dir']

api_pid_dir = config['configurations']['api-env']['api_pid_dir']
api_pid_file = format("{api_pid_dir}/api.pid")

api_download = 'http://127.0.0.1/tarapi.tar.gz'
api_zk = config['configurations']['api-env']['zk']

注意一点,这里的api-env就是configration/api-env.xml文件的内容,ambari启动的时候回加载这个文件到它自己的字典中,用的时候直接取就可以了。

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at
       http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
-->
<configuration>

  <property>
    <name>api_user</name>
    <value>ams</value>
    <property-type>USER</property-type>
    <description>user</description>
  </property>

  <property>
    <name>api_group</name>
    <value>hadoop</value>
    <property-type>GROUP</property-type>
    <description>group</description>
  </property>

  <property>
    <name>api_base_dir</name>
    <value>/opt/api</value>
    <description>api base directory</description>
  </property>

  <property>
    <name>api_pid_dir</name>
    <value>/var/run/api</value>
    <description>api PID directory</description>
  </property>

  <property>
    <name>zk</name>
    <value>127.0.0.1:2181</value>
    <description>zookeeper address:port </description>
  </property>


</configuration>

最后就是执行ambari-server restart重启加载。然后在ambari-web中点击addservice就可以看到我们的服务名称了,添加的过程与ambari已经集成Hadoop组件完全相同。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章