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組件完全相同。

 

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