Table of Contents
CM简介
Cloudera Manager(简称CM)是Cloudera公司开发的一款大数据集群安装部署利器,这款利器具有集群自动化安装、中心化管理、集群监控、报警等功能,使得安装集群从几天的时间缩短在几小时以内,运维人员从数十人降低到几人以内,极大的提高集群管理的效率。更多打开方式请参考中文官网:https://www.clouderacn.cn/。
Cloudera 产品具有开放的特性,这种开放性的其中一个体现就是CM提供了丰富的API供客户调用。基本上所有在界面上提供的功能通过API都可以完成同样的工作。Cloudera Manager API支持的功能包括配置和服务生命周期管理、服务健康信息和指标,并允许配置 Cloudera Manager本身。API复用Cloudera Manger管理控制台(Cloudera Manager Admin Console)相同的主机和端口,无需额外的操作流程或参数配置。API支持HTTP基本身份验证(HTTP Basic Authentication),接受与Cloudera Manger管理控制台相同的用户和凭据。并且这些API都是标准的RESTAPI,使用HTTP标准的CRUD所有的请求和响应都可以用JSON(JavaScript Object Notation)来表示,基本上所有的业务系统都应该支持,通过这些API能够方便地将CM集成到企业原有的集中管理系统。
cm_api简介
cm_api是cloudera开源的一个RESTful API 客户端,GitHub地址为:https://github.com/cloudera/cm_api,允许用户通过Java或Python轻松构建 Cloudera Manager客户端,本项目包含了日常操作所需的所有源代码、示例和文档。该资源库中的所有源代码均已获得 Apache 许可。
该客户端代码允许用户与 Cloudera Manager通过API的形式进行交互,具备以下功能:
- 管理多个集群
- 启动和停止所有或个别服务或角色
- 升级集群上运行的服务
- 访问系统中任何活动的资源利用率时间序列数据
- 读取系统中所有进程的日志以及 stdout 和 stderr
- 以编程方式配置部署的各个组件
- 收集诊断数据,帮助调试问题
- 运行分布式命令来管理自动故障转移、主机退役等问题
- 查看系统中发生的所有事件和警报
- 从系统中添加和删除用户
背景描述
运维的一个负责Hadoop集群运维的兄弟离职了新员工21号才能入职,所以这段时间的Hadoop集群由我代管。最近发现Azkaban离线任务失败的频率比较高,通过排查发现一个DataNode偶尔会出现异常,由于最近需求比较多准备暂时把节点摘除,等空闲的时候分析下异常原因。
通过交接文档找到了节点摘除脚本(通常情况下本人会通过cm的web ui操作,这次就是单纯想试试这个脚本):
# coding=utf-8 from cm_api.api_client import ApiResource from cm_api.endpoints.cms import ClouderaManager import sys import time sys.path.append("../") reload(sys) sys.setdefaultencoding('utf-8') decom_host = [] decom_host.append(sys.argv[1]) print decom_host #prod 环境 cm_client = ApiResource(server_host="cm_web_host_or_ip", username="prod_account", password="prod_password") if __name__ == '__main__': cms = ClouderaManager(cm_client) cms.hosts_decommission(decom_host) print time.strftime("%Y-%m-%d %H:%M:%S") + " 正在删除" + decom_host[0] + "的节点"
更新脚本的账号和密码,然后通过python2来执行,本来期望能一次性成功但是结果往往让人失望:
[micboy@workstation ~] python2 cm_decommission_host.py hostname_not_ip.com Traceback (most recent call last): File "cm_decommission_host.py", line 24, in <module> cms.hosts_decommission(decom_host) File "/usr/local/lib/python2.7/site-packages/cm_api/endpoints/cms.py", line 235, in hosts_decommission return self._cmd('hostsDecommission', data=host_names) File "/usr/local/lib/python2.7/site-packages/cm_api/endpoints/types.py", line 334, in _cmd data=data, params=params, api_version=api_version) File "/usr/local/lib/python2.7/site-packages/cm_api/endpoints/types.py", line 365, in _post api_version) File "/usr/local/lib/python2.7/site-packages/cm_api/endpoints/types.py", line 383, in _call api_version) File "/usr/local/lib/python2.7/site-packages/cm_api/endpoints/types.py", line 137, in call ret = method(path, data=data, params=params) File "/usr/local/lib/python2.7/site-packages/cm_api/resource.py", line 148, in post self._make_headers(contenttype)) File "/usr/local/lib/python2.7/site-packages/cm_api/resource.py", line 73, in invoke headers=headers) File "/usr/local/lib/python2.7/site-packages/cm_api/http_client.py", line 193, in execute raise self._exc_class(ex) cm_api.api_client.ApiException: (error 404)
通过分析cm_api.api_client中ApiResource代码可以看到,在构建实例的时候version有个默认值。
def __init__(self, server_host, server_port=None, username="admin", password="admin", use_tls=False, version=API_CURRENT_VERSION, ssl_context=None):
初步怀疑是不是API_CURRENT_VERSION存在默认值而且和集群配置不一致,在cm_api.api_client中搜索发现默认版本是16。
我们可以通过REST API获取Cloudera Manager中支持的API 版本:
http://host:port/api/version
可以看到生产环境中使用的版本是19,这个和默认值16差别还不小。
通过搜索CDH论坛历史帖子发现存在相同的案例也印证了确实是版本导致的,对代码进行修正在ApiResource构造方法中新增version参数为19:
cm_client = ApiResource(server_host="cm_web_host_or_ip", version=19, username="prod_account", password="prod_password")
再次执行脚本可以看到,请求解除角色的请求已经成功执行:
[micboy@workstation ~] python2 cm_decommission_host.py hostname_not_ip.com ['hostname_not_ip.com'] 2023-08-14 20:22:24 正在删除hostname_not_ip.com的节点
由于这台机器上有百万个block因此需要数据转移完才算授权解除完成,也才可以通过CM Web UI删除该节点。
参考文档
cm_api仓库地址:https://github.com/cloudera/cm_api
ApiResource说明:https://cloudera.github.io/cm_api/epydoc/5.12.0/cm_api.api_client.ApiResource-class.html
转载请注明:麦童博客 » CDH Rest API cm_api.api_client.ApiException: (error 404)