Apache Ranger学习总结2

  |   0 评论   |   0 浏览

前言:

ranger大数据领域的一个集中式安全管理框架,它可以对诸如hdfs、hive、kafka、storm等组件进行细粒度的权限控制。比如它可以控制用户读取hdfs文件的权限,甚至可以控制某个用户对hive某个列访问的权限。

ranger的权限模型

Ranger的权限模型一条条的权限策略组成的,权限策略主要由3个方面组成,即用户、资源、权限。
图片2.png
用户:ranger可以对用户进行分组,一个用户可以属于多个分组。Ranger支持对用户或者用户组配置某资源的相关权限。

资源:对于各个不同的组件,资源的表述都不相同。比如在HDFS中,文件路径就是资源,而在Hive中,资源可以指Database、Table甚至Column。

权限:ranger可以对各个资源的读、写、访问进行限制,具体可以配置白名单、白名单排除、黑名单、黑名单排除等条目。

ranger管理员配置好组件的相关策略后,并且将ranger插件安装到具体的大数据组件中,ranger就可以开始生效了。这时用户访问ranger就会进行权限的校验过程了,校验过程如下:
图片3.png
当用户要请求某个资源时,会先获取和这个资源有关联的所有配置的策略,之后遍历这些策略,然后根据黑白名单判断该用户是否有权限访问该资源。从上面的流程图可以看出,黑名单、黑名单排除、白名单、白名单排除匹配的优先级如下:

黑名单优先级高于白名单

黑名单排除的优先级高于黑名单

白名单排除的优先级高于白名单

决策下放

如果没有policy能决策访问,一般情况是认为没有权限拒绝访问,然而Ranger还可以选择将决策下放给系统自身的访问控制层。

Ranger架构

图片4.png

Plugin

那么ranger是如何实现对大数据组件的权限控制访问呢?这就和ranger实现的一个个plugin有关系了。

因为几乎所有的大数据组件都有提供一个抽象的验证接口,ranger就是根据这些接口为各个大数据组件实现了对应的plugin,plugin的工作主要是从Ranger-Admin处拉取该组件配置的所有策略,然后缓存到本地,然后当有用户来请求时提供鉴权服务。

Ranger的架构主要就是Ranger-Admin和各个组件的Plugin,其代码也大多都是偏业务逻辑的。

  1. 关于组件策略的缓存

由于组件的多样性以及策略的复杂性,在ranger的数据库中,和策略相关的表就多达10来张。也就是说,一个组件要来Ranger-Admin拉取其相关的所有策略时,需要查询这十多张表,然后将其组织成组件需要的数据结构,再转成json返回。这是一个相对耗时较长的操作,另外,不止组件会获取这些策略,web界面或者sdk也可能调用相关接口获取所有策略。

为了提高获取策略的性能,ranger以Service为单位,来缓存这些已经组织好的数据。当数据被缓存起来后,后续的请求只需从内存中获取相关数据即可。—— service可以理解为一个具体的大数据组件

使用缓存会引发另一个问题,怎么判定缓存已经失效?为了解决这个问题,Ranger在Service表中添加了一个字段:policy_version,只要和这个service的策略有关的属性发生了变化,就更新policy_version。当用户请求策略时,发现policy_version和缓存的不一致,就会重新拉取数据,然后更新缓存。

当然,这种缓存策略也很容易引发bug,比如ranger之前有一个bug,它在更新用户组信息时,不会更新该service的policy_version,导致组件拉取到的策略数据还是旧数据。

因此,虽说做这种缓存可以很大程度提高性能,但同时也要格外关注这些缓存的更新问题。

  1. 插件类加载器的实现

ranger实现大数据组件的授权接口时,一般需要把打包好的jar包放到对应大数据组件的classpath下供组件加载。同时,ranger在实现授权接口时难免会用到其他的一些第三方库,这时问题就来了:如果把这些第三方库的jar包也放到大数据组件的classpath下,引发的版本冲突该如何解决?

举个例子,比如Hive用到了apache-common-1.0.0,ranger编写hive插件时也用到了apache-common-2.0.0,这时候版本就发生了冲突。如果要完全去兼容hive的第三方库版本是一件很累的事情,同时给hive引入过多的第三方库也会导致一些潜在的隐患。

为了解决这个问题,Ranger定义了自己的一个类加载器,用于加载它使用的那些第三方库。在介绍ranger的自定义类加载器之前,我们先简单回顾一下java中的类加载器的一些概念。

首先我们需要明白一件事,在java中,一个类的唯一性并不是由包名+类名来决定的,还要根据类加载器。也就是说,比如有一个类com.Test,分别有两个不同的类加载器加载,那么它们加载出的两个类就不是相等的。
双亲委派类加载机制:

在java世界中,有一个双亲委派机制,是说要加载一个类的时候,先交给父级类加载器加载,父级类加载器无法加载时,自己才能去加载这个类。
图片5.png
这是我们在实现自己的类加载器时,普遍要遵守的一个机制。但是Ranger实现的类加载器破坏了双亲委派机制,从而将自己使用的第三方库和组件使用的第三方库隔离。由于ranger使用的第三方插件的所有类都是自己定义的类加载器加载的,因此不用担心第三方库冲突的问题。
图片6.png


标题:Apache Ranger学习总结2
作者:gao1feng
地址:http://gao1feng.top/articles/2020/02/14/1581663926992.html