掌握API建模:基本概念和实践
WebHDFS Rest API 企业实战:大佬手把手带你堵住漏洞,企业实例解析
Apache Hadoop提供了本地库,用于访问HDFS。这些本地库对于在Hadoop集群内运行的应用程序非常有用,只需要配置hadoop客户端的环境就可以使用这些库来直接访问HDFS。
然而,对于外部应用程序来说,如果需要与HDFS集群进行交互。比如常见的创建目录、将文件写入新目录,读取存储在HDFS中的文件内容。甚至设置HDFS文件权限,此时如果程序所在的环境没有Hadoop的本地库,也就无法实现这些需求。这就是为什么您需要使用WEBHDFS REST API的原因。它提供了一种机制,使外部应用程序能够与HDFS数据进行交互。通过使用WEBHDFS REST API,外部应用程序可以通过HTTP请求来执行各种操作,如创建目录、上传文件、读取文件等,从而实现与HDFS的交互。
WEBHDFS是一个 REST API,支持 GET POST、PUT 和 DELETE 等 HTTP 操作。它允许客户端应用程序通过 HTTP 或 HTTPs 访问 HDFS 数据并执行 HDFS 操作。它具有以下功能:
- 读写访问 – REST API 支持HDFS 的完整FileSystem / FileContext接口,包括授予权限、访问块位置、配置复制因子等 。
- HDFS 参数 – 它支持所有 HDFS 参数及其默认值。
- 身份验证 – 此 REST API 使用 Hadoop 和 Kerberos 来验证请求。当安全性开启时,将使用 Kerberos。
- 多语言-允许客户端使用不同语言访问HDFS,而无需安装Hadoop。它还可以与wget、curl等工具配合使用来访问HDFS。
- 开源-它是一个完全开源的工具。
1.配置REST API
启用此功能操作上非常的简单,只需要简单的配置即可,在hdfs-site.xml文件中添加下面的配置项。
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
在CDH中启用:(默认是开启的)
注意:
- 这个虽然是默认开启的,但是在没有启用kerberos等安全认证措施的情况下开启的风险很大,客户端可以模拟任何用户来操作集群,可以删除集群所有数据。
- 直接关闭带来的影响就是无法通过namenode的web页面查看集群数据,或者直接打不开active状态的namenode的web。
端口配置:
WEBHDFS REST API使用的端口是WebHDFS默认端口,通常为50070(HTTP)或50470(HTTPS)。这些端口可以通过Hadoop配置文件进行自定义设置。在配置文件中,dfs.namenode.http-address
指定了HTTP端口,dfs.namenode.https-address
指定了HTTPS端口。具体的端口配置取决于Hadoop集群的设置和管理员的配置。
2.REST API请求方式
支持 FileSystem URIs 和 HTTP URLs
- FileSystem scheme 是”webhdfs://”,格式如下:
webhdfs://<HOST>:<HTTP_PORT>/<PATH>
这个可以和和常用的HDFS的URl对比,格式如下:
hdfs://<HOST>:<RPC_PORT>/<PATH>
两者之间的区别主要在于通信协议和端口:
- HDFS的URL使用的是”hdfs” scheme,而WebHDFS使用的是”webhdfs” scheme。
- HDFS的URL使用的是RPC端口(默认为8020),而WebHDFS使用的是HTTP端口(默认hadoop2是 50070,hadoop3是 9870)。
2.HTTP URl格式是:,请求的方式如下
http://<HOST>:<HTTP_PORT>/webhdfs/v1/<PATH>?op=...
在REST API中,完整的路径中需要插入了前缀”/webhdfs/v1″,并在末尾附加了查询。因此,完整相应的HTTP URL具有以下格式:
http://<namenode>:<port>/webhdfs/v1/<path>?<query>
<namenode>
是HDFS Namenode的主机名或IP地址。<port>
是Namenode的WebHDFS服务运行的端口号(HTTP默认为50070,HTTPS默认为50470)。<path>
是要进行交互的HDFS文件或目录的路径。<query>
是查询参数,用于指定操作、用户、权限等。
例如,要访问根目录中名为 “example.txt” 的文件,则相应的URL可能如下所示:
http://<namenode>:<port>/webhdfs/v1/example.txt?op=OPEN&user.name=<username>
在上面的示例中,<op>
是操作参数,user.name
是指定访问文件的用户的查询参数。请注意,实际的URL和查询参数将根据具体操作和需求而有所不同。
3.REST API具体使用
3.1 文件增删改查
- 查看指定目录的状态
curl -s "http://ds-bigdata-001:9870/webhdfs/v1/tmp?user.name=aqiang&op=GETFILESTATUS" | jq
这个命令使用curl发送HTTP GET请求到指定的URL。URL是http://ds-bigdata-001:9870/webhdfs/v1/tmp?user.name=aqiang&op=GETFILESTATUS
,
其中包括了查询参数user.name
和op
。
-s
选项用于禁用curl的进度条显示。
然后,通过管道将curl的输出传递给jq命令。jq是一个命令行工具,用于处理JSON数据。
运行该命令后,curl会向指定URL发送请求,并获取到JSON响应。然后,这个JSON响应会被传递给jq命令进行处理。jq会对JSON进行解析和格式化,并将格式化后的结果输出到终端上。
2.创建目录
curl -i -X PUT "http://ds-bigdata-001:9870/webhdfs/v1/tmp/test_webhdfs_dir?user.name=aqiang&op=MKDIRS"
这里通过api在/tmp目录下新建一个目录test_webhdfs_dir。
验证已经创建成功;
3.读取文件
curl -L "http://ds-bigdata-001:9870/webhdfs/v1/tmp/test_webhdfs_dir/1.txt?op=OPEN&user.name=aqiang"
这里提前在指定目录下放一个1.txt的文件。下面成功读取到文件的内容。
4.删除文件
curl -i -X DELETE "http://ds-bigdata-001:9870/webhdfs/v1/tmp/test_webhdfs_dir/1.txt?op=DELETE&user.name=aqiang"
3.2 文件权限管理
权限管理上,一般操作比较多的就是文件的ACL条目设置,具体的一些相关操作总结如下:
## 以curl请求为例:
curl -i -X PUT "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=MODIFYACLENTRIES&aclspec=<ACLSPEC>"
curl -i -X PUT "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=REMOVEACLENTRIES&aclspec=<ACLSPEC>"
curl -i -X PUT "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=REMOVEACL"
curl -i -X PUT "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=GETACLSTATUS"
ACLSPEC 格式如下:【ACL权限规范中的每个条目都要符合下面格式要求,多个条目之前使用逗号分隔.】
^(default:)?(user|group|mask|other):[[A-Za-z_][A-Za-z0-9._-]]*:([rwx-]{3})?(,(default:)?(user|group|mask|other):[[A-Za-z_][A-Za-z0-9._-]]*:([rwx-]{3})?)*$
(default:)?:可选的前缀,表示默认权限。
(user|group|mask|other):指定条目的类型,可以是用户、组、掩码或其他。
[[A-Za-z_][A-Za-z0-9._-]]*:条目的名称,可以是字母、数字、下划线、点或破折号组成。
([rwx-]{3})?:可选的权限部分,表示读、写和执行权限。
1. 添加(修改)acl;可以修改已有的acl和添加新的acl权限
curl -i -X PUT "http://ds-bigdata-001:9870/webhdfs/v1/mobtttt?user.name=hdfs&op=MODIFYACLENTRIES&aclspec=user:test555:rwx,user:test6666:rw-,group:mob:r-x"
http://ds-bigdata-001:9870
:WebHDFS服务的地址和端口。/webhdfs/v1/mobtttt
:要修改ACL权限的目录路径。user.name=hdfs
:指定代理用户为hdfs
。op=MODIFYACLENTRIES
:指定操作为修改ACL权限。aclspec=user:test555:rwx,user:test6666:rw-,group:mob:r-x
:指定ACL权限规范,其中包含要修改的ACL条目。user:test555:rwx
:用户test555
具有读、写和执行权限。user:test6666:rw-
:用户test6666
具有读和写权限,但无执行权限。group:mob:r-x
:组mob
的成员具有读和执行权限,但无写权限。
说明:此条指令是同时添加多条acl条目,多条用逗号隔
2.删除指定的acl条目
curl -i -X PUT "http://ds-bigdata-001:9870/webhdfs/v1/mobtttt?user.name=hdfs&op=REMOVEACLENTRIES&aclspec=user:test6666:,group:mob:"
op=REMOVEACLENTRIES
:指定操作为删除ACL权限。aclspec=user:test6666:,group:mob:
:指定ACL权限规范,其中包含要删除的ACL条目。user:test6666:
:删除用户test6666
的ACL条目。group:mob:
:删除组mob
的ACL条目。
说明:可以同时删除一条或者多条,多条用逗号分割。
3.删除所有的acl条目
curl -i -X PUT "http://ds-bigdata-001:9870/webhdfs/v1/mobtttt?user.name=hdfs&op=REMOVEACL"
4.获取acl条目
curl -i -X get http://ds-bigdata-001:9870/webhdfs/v1/mobtttt?op=GETACLSTATUS
tips:WEBHDFS Rest API 一般可以配合自动化脚本等场景来使用。
4.示例分享
在有些场景下,我们可能只需要ACL相关的设置功能,此时可以修改源码或者自定义一个新的接口去实现。下面是一个仅供参考的示例demo。
4.1 自定义接口(python+hdfs shell)
from flask import Flask, request
import subprocess
app = Flask(__name__)
@app.route('/hdfs/acl', methods=['POST'])
def set_acl():
path = request.form.get('path')
acl = request.form.get('acl')
try:
command = ['hdfs', 'dfs', '-setfacl', '-R', '-m', acl, path]
subprocess.run(command, check=True)
print(command)
return 'ACL set successfully'
except subprocess.CalledProcessError as e:
return 'Failed to set ACL: ' + str(e), 500
@app.route('/hdfs/acl', methods=['DELETE'])
def remove_acl():
path = request.form.get('path')
try:
command = ['hdfs', 'dfs', '-setfacl', '-R', '-b', path]
subprocess.run(command, check=True)
print(command)
return 'ACL removed successfully'
except subprocess.CalledProcessError as e:
return 'Failed to remove ACL: ' + str(e), 500
@app.route('/hdfs/acl', methods=['GET'])
def get_acl():
path = request.args.get('path')
try:
command = ['hdfs', 'dfs', '-getfacl', '-R', path]
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
print(command)
return result.stdout
except subprocess.CalledProcessError as e:
return 'Failed to get ACL: ' + str(e), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8099)
接口名称:HDFS ACL 接口
接口描述:该接口用于操作HDFS的ACL,包括设置ACL、删除ACL和获取ACL信息。
接口URL:`http://xxx:8099/hdfs/acl`
接口支持的HTTP方法:
- 设置ACL:POST
- 删除ACL:DELETE
- 获取ACL:GET
参数说明:
1. 设置ACL(POST请求):
- 参数名:
- `path`:HDFS路径,表示要设置ACL的文件或目录的路径。
- `acl`:ACL字符串,表示要设置的ACL规则。ACL规则的格式请参考HDFS ACL规范。
2. 删除ACL(DELETE请求):
- 参数名:
- `path`:HDFS路径,表示要删除ACL的文件或目录的路径。
3. 获取ACL(GET请求):
- 参数名:
- `path`:HDFS路径,表示要获取ACL的文件或目录的路径。
响应格式:
- 设置ACL和删除ACL接口的响应格式为纯文本,包含成功或失败的消息。
- 获取ACL接口的响应格式为ACL信息的文本形式。
访问权限:
- 外部用户需要具有HDFS操作权限,并能够从访问该接口的主机访问到HDFS集群。
说明:在hdfs文件系统的集群的客户端节点,使用hdfs用户启动接口服务。
错误处理:
- 当设置ACL、删除ACL或获取ACL接口发生错误时,会返回适当的错误消息和HTTP状态码。请根据状态码和错误消息进行错误处理。
# CURl 请求示例:
修改目录/test ACL
curl -X POST -d "path=/test&acl=user:test:rwx" http://localhost:8099/hdfs/acl
删除ACL
curl -X DELETE -d "path=/test" http://localhost:8099/hdfs/acl
获取ACL
curl -X GET 'http://localhost:8099/hdfs/acl?path=/test'
本文章转载微信公众号@涤生大数据