当前位置:   article > 正文

聊聊HDFS中的权限管理

dfs.permissions.enabled

HDFS是一个面向多用户的分布式文件系统。既然是多用户,那么不同用户存储的文件通常需要进行权限隔离,防止被其他用户修改或误删。本文就来聊聊HDFS中的权限管理。

权限校验

要启用权限校验,首先需要在NN中配置开启。

配置项dfs.permissions.enabled控制权限的开关,true表示开启,false表示关闭。

没有开启权限控制时,任何用户都可以对任意文件进行读写删除等操作。

  1. <property>
  2.   <name>dfs.permissions.enabled</name>
  3.   <value>true</value>
  4. </property>

HDFS中的权限方式和linux文件系统中的权限模型是一样的,均采用UGO模型。

U表示User,G表示Group,O表示Other。每个文件的权限都基于UGO来设置。

而权限又包括可读(r),可写(w),可执行(x),三个为一组,对应UGO分别进行设置。

我们来实际验证下:使用hncscwc用户创建/hncscwc目录,并上传文件到该目录中,然后使用root用户删除该文件。

未开启权限校验之前,root用户可以成功删除文件。

开启权限校验之后,root用户无法删除该文件,并提示没有权限。

那么如果想要让root用户可以删除hncscwc上传的文件,有什么办法呢?一种简单粗暴的方式是通过chmod改变文件的权限。例如上面将目录和文件的权限都设置为777后,root用户就可以成功删除文件了。

但显然这种方式是不友好的,因为几乎和没有开启权限校验一样。因此HDFS同样也是实现了类似linux文件系统中ACL。

ACL

和权限校验一样,ACL的开启有对应的配置项,true表示开启,false表示关闭

  1. <property>
  2. <name>dfs.namenode.acls.enabled</name>
  3.     <value>true</value>
  4. </property>

开启ACL之后,可以通过命令设置和获取文件/目录的ACL。

  1. # 获取指定文件/目录的ACL
  2. hdfs dfs -getfacl [-R] <path>
  3. -R: 递归列出所有w文件和目录的ACL
  4. # 设置指定文件/目录的ACL
  5. hdfs dfs -setfacl [-R] [-b|-k -m|-x <acl_spec> <path>] [--set <acl_spec <path>]
  6. -b:    删除基本ACL条目之外的所有条目。保留用户、组和其他的条目
  7. -k:    移除默认的ACL
  8. -R:    递归操作所有文件和目录
  9. -m:    修改ACL,将新条目添加到ACL,并保留现有条目
  10. -x: 删除指定的ACL
  11. --set:    完全t替换ACL,acl_spec必须包含用户,组和其他权限信息
  12. acl_spec:  用逗号分隔的ACL列表
  13. path: 需要设置ACL的文件l路径

这里不展开说明命令的细节,详细参考官方文档。

还是按照上面的场景,对/hncscwc/info设置ACL允许root用户写入。

从上图可以看到,文件设置ACL之后,权限后面会多出一个“+”,表示该文件有设置ACL。

通过命令查看该文件的ACL信息:

接着使用root用户追加写入该文件,此时root用户可以成功追加写入,而使用其他用户追加写入时,写入失败并提示没有权限。

由此可见,ACL生效了,也确实达到了我们想要的效果。

超级用户

在HDFS中,有一个超级用户的概念,该用户可以成功执行任意动作而不需要进行权限校验。

超级用户没有固定的值,而是启动NN的用户就是超级用户。

此外,还可以通过配置来指明一个组为超级用户组,在该组中的所有用户均为超级用户,具体配置为:

  1. <property>
  2. <name>dfs.permissions.superusergroup</name>
  3.     <value>supergroup</value>
  4. </property>

内部实现

在NN内部,权限校验主要有两个类,部分关键代码如下所示:

  1. public abstract class INodeAttributeProvider
  2. {
  3.     //访问控制执行者接口
  4.     public interface AccessControlEnforcer {
  5.         // 省略了参数列表
  6.      public abstract void checkPermission(...)
  7.     }
  8.     
  9.     public abstract void start();
  10.     
  11.     public abstract void stop();
  12.     
  13.     public AccessControlEnforcer getExternalAccessControlEnforcer(AccessControlEnforcer defaultEnforcer) {
  14.      return defaultEnforcer;
  15.     }
  16. }

该类为抽象类,用于HDFS委派授权,该类中定义了一个接口AccessControlEnforcer,并定义方法checkPermission,该方法需要实现类重写,以实现最终的权限校验逻辑。

  1. class FSPermissionChecker implements AccessControlEnforcer {
  2. private AccessControlEnforcer getAccessControlEnforcer() {
  3.         // 这里的attributeProvider就是上面抽象类的具体实现类
  4.         // 如果attributeProvider 则使用自身
  5. return (attributeProvider != null) ?
  6. attributeProvider.getExternalAccessControlEnforcer(this) : this;
  7. }
  8.     // 外部调用接口, 省略了参数列表
  9.     void checkPermission(...) {
  10.      AccessControlEnforcer enforcer = getAccessControlEnforcer();
  11.      enforcer.checkPermission(...)
  12.     }
  13.     
  14.     // 实现AccessControlEnforcer接口的方法实现
  15.     public void checkPermission(...) {
  16.     }
  17. }

简单总结下鉴权流程,如下图所示:

从流程可以看出,通过编写INodeAttributeProvider继承类,和接口AccessControlEnforcer实现,HDFS可以支持外部以插件的方式实现定制的权限控制。而实际上,开源的大数据权限管理项目Ranger,sentry就是利用了这一点,以插件的方式扩展实现了权限校验。

好了,本文就介绍到这里了,原创不易,点赞,在看,分享是最好的支持, 谢谢~

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号