一、Elasticsearch服务脚本

  1. ELASTICSEARCH服务脚本解压后放入ambari主节点的/var/lib/ambari-server/resources/stacks/HDP/2.6/services/目录下。

  2. Elasticsearch源码 (version:6.2.4) 放入待装该服务的主机/usr/hdp/2.6.4.0-91/elasticsearch/目录下(elasticsearch目录需要新建)

  3. 重启ambari-server。

二、执行过程

  1. 首先,master主机会根据用户的选择确认在哪一台主机进行Elasticsearch服务。

  2. 会将py安装脚本包发送到该服务主机的/var/lib/ambari-agent/cache/stacks/HDP/2.6/services/ELASTICSEARCH/

  3. py脚本在该服务主机上开始执行。会在数据表clusterservices中添加该服务的具体信息。

    master.py具体执行过程如下:

    • 将源码在/usr/hdp/2.6.4.0-91/elasticsearch/解压,然后执行changeOsConfToES.sh脚本来配置其环境变量,然后启动Elasticsearch服务。
  4. 自定义服务说明:

    • discovery_zen_ping_unicast_hosts值为ambari所有主机ip,以英文”,”隔开。
    • elasticsearch_host值为该服务所在的主机ip
    • master_host值为ambari主节点的ip
  5. 每个 Service 都会有 start、stop、status、configure 这样的命令,我们称之为生命周期的控制命令。在amabri页面上进行服务起停。master通知该服务主机,该服务主机会执行/var/lib/ambari-agent/cache/stacks/HDP/2.6/services/ELASTICSEARCH/package/scripts/目录下的master.py文件内的start、stop方法。

  6. 删除服务。ambari会删除数据库信息,使Elasticearch服务在服务列表中消失。

三、修改服务的配置信息

  1. 访问http://172.16.0.142:8080/#/main/services/ELASTICSEARCH/configs,修改服务配置项并保存时,会在数据库中添加信息,主要是其三个表:

  1. 在ambari页面更改elastic-config 属性,比如将端口号改为9203,就会点击保存,然后重启该组件,属性就会被应用。

    在服务所在主机上,打开/usr/hdp/2.6.4.0-91/elasticsearch/config/elasticsearch.yml文件,就会发现配置项已被改变。

    但是,,,打开快速链接,默认的端口号还是以9200打开,而且页面肯定显示失败。这是由于quicklinks.json文件在主节点上且没有被改变,于是打开/var/lib/ambari-server/resources/stacks/HDP/2.6/services/ELASTICSEARCH/quicklinks/quicklinks.json,手动修改端口号92009203,然后重启ambari-server。再次打开快速链接,就会显示ip:9203,且获取到该服务的版本信息。

    这里不知道如何实现自动修改quicklinks.json文件里面的端口号???????????????

四、服务脚本解读

目录结构:

  • configuration文件夹

    • 内含xml文件,里面有服务的配置信息,被py文件调用。举个例子:
    1
    2
    config = Script.get_config()
    config['configurations']['elastic-env']['es_tar_host']

    来获取xml文件name对应的value值。

  • package/scripts文件夹

    • changOsConfToES.sh文件是配置elasticsearch的环境变量

    • elastic_common.py内含停止服务的方法,供master.py调取

    • params.py和status_params.py是配置项,供master.py调取

    • master.py内含install,configure,start,stop,status等方法。

      • install(self, env)的self,即本身的意思,代表当前类的实例。env将配置文件导入该py文件进行配置读取

        1
        2
        3
        4
        5
        def install(self, env):
        import params
        env.set_params(params)
        ...
        # 这样params.py里面的值才可以在该文件内使用。
      • py执行shell语句示例:

        1
        2
        cmd = format("cd {elastic_base_dir}; wget {elastic_download} -O elasticsearch.tar.gz -a {elastic_install_log}")
        Execute(cmd, user=params.elastic_user)

        format包含shell语句,Execute用来指定user来执行shell语句,user可选填,不填默认为root用户执行。

      • 执行语句

        1
        2
        if __name__ == "__main__":
        Master().execute()
    • metainfo.xml

      • 内含服务整体的配置信息
      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
      <?xml version="1.0"?>
      <metainfo>
      <schemaVersion>2.0</schemaVersion>
      <services>
      <service>
      <!--service的名称,该名称必须保障在stack services中是唯一的,建议大写-->
      <name>ELASTICSEARCH</name>
      <!--添加服务时显示的服务名称,服务简介,服务版本-->
      <displayName>ElasticSearch</displayName>
      <comment>ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。</comment>
      <version>6.2.4</version>

      <components>
      <component>
      <!--组件的名称-->
      <name>MASTER</name>
      <!--该组件的显示名称-->
      <displayName>ElasticSearch</displayName>
      <!--该组件的类型:MASTER/SLAVE/CLIENT-->
      <category>MASTER</category>
      <!--允许/期待实例化数量-->
      <cardinality>1+</cardinality>
      <!--执行py脚本-->
      <commandScript>
      <!--该script的相对路径-->
      <script>scripts/master.py</script>
      <!--该script的类型,当前仅支持PYTHON-->
      <scriptType>PYTHON</scriptType>
      <!--该script的执行超时时间-->
      <timeout>1800</timeout>
      </commandScript>
      </component>
      </components>

      <!--该service针对OS的特定package信息,该命令会在component实例中执行-->
      <osSpecifics>
      <osSpecific>
      <osFamily>any</osFamily>
      </osSpecific>
      </osSpecifics>

      <!--执行service_check脚本,在web页面的服务操作项中会增加“运行服务检查项”-->
      <commandScript>
      <script>scripts/service_check.py</script>
      <scriptType>PYTHON</scriptType>
      <timeout>600</timeout>
      </commandScript>

      <!--该service所依赖的配置文件(被其他services拥有的config也要在该列表中指定)-->
      <configuration-dependencies>
      <config-type>elastic-env</config-type>
      <config-type>elastic-config</config-type>
      </configuration-dependencies>

      <!--是否在rack变更后重启-->
      <restartRequiredAfterChange>false</restartRequiredAfterChange>

      <!--存放快速链接定义文件的目录,默认是quicklinks-->
      <quickLinksConfigurations>
      <quickLinksConfiguration>
      <!--快速链接json文件名-->
      <fileName>quicklinks.json</fileName>
      <default>true</default>
      </quickLinksConfiguration>
      </quickLinksConfigurations>
      </service>
      </services>
      </metainfo>

      metainfo.xml文件详情请参考:https://blog.csdn.net/crispy_rice/article/details/79354769

    • quicklinks文件夹

      • 内含json文件,用来设置服务的快速链接

      • 如果添加快速链接功能需要在metainfo.xml文件的service标签内添加一下代码:

        1
        2
        3
        4
        5
        6
        <quickLinksConfigurations>
        <quickLinksConfiguration>
        <fileName>quicklinks.json</fileName>
        <default>true</default>
        </quickLinksConfiguration>
        </quickLinksConfigurations>
      • 摘取quicklinks.json文件的一段信息:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        "links": [
        {
        "name": "elasticsearch_ui",
        "label": "Elasticsearch UI", # 页面快速链接的显示名称
        "requires_user_name": "false",
        "component_name": "MASTER", # 需要与metainfo.xml内的component的name值相同
        "url":"%@://%@:%@", # 第一个%@代表大环境是采取的http还是https,比如ambari是采取的http协议,那么这里第一个%@就是http;第二个%@是代表ip;第三个%@代表端口号
        "port":{
        "http_property": "http_port", # 和/configuration/elastic-config.xml文件中的http_port对应
        "http_default_port": "9200", # 端口号
        "https_property": "http_port",
        "https_default_port": "9200",
        "regex": "\\w*:(\\d+)",
        "site": "elastic-config"
        }
        }
        ]
    • 说明

Ambari 的 Service 目录中,存在很多个叫做 role_command_order.json 的文件。在这个文件中定义了状态之间以及 Action 的依赖。在 resource 目录下的 role_command_order.json 定义着全局的的依赖。每个 Stack 目录下也会存在 role_command_order.json。相同的配置,Stack 下面的会覆盖全局的(overwrite)。对于不同的配置,Ambari 会拼接在一起(merge)。高版本的 Stack 会继承低版本的配置。相同的也会 overwrite,不同的也会 merge。

五、参考资料

【1】Ambari自定义服务集成实战教学(完结):https://www.yuque.com/create17/ambari/miyk6c