【sentry 到 ranger 系列】sentry 的开篇

前言

  这是系列的第一篇

1、Sentry 架构概述

1.1、Sentry 的权限模型

权限模型
  Sentry 是基于角色的权限模型,权限都挂在 role 上,一个 group 可以有多个 role,一个 user 可以有多个 group,也就是多对多对多对多~ 这部分就不展开细讲了,网上有很多具体的使用案例可以参考

1.2、Sentry 架构图

  一图胜千言( ̄︶ ̄)↗ (应该没那么难看吧)
在这里插入图片描述
  其中蓝色部分为 Sentry 的服务或者插件实现。

1.2、架构剖析

  其实理解 Sentry 的架构和原理笔者认为就是三块儿,一块儿是 Sentry 怎么获取权限数据,第二块儿是 Sentry 是怎么处理数据的,第三块儿是 Sentry 怎么提供鉴权能力的。其中第二点,在本片中会涉及得少一点,因为笔者认为一上来就花很多精力细说 Sentry 内部的内容,其实是没有什么感觉的,反而不如先从 Sentry 进行交互的组件了解到 Sentry 做了哪些事情,然后带有目标性地去了解 Sentry 内部哪一部分是做什么事情的,会更符合笔者的思考方式一点。所以本篇和下一篇,对 Sentry 内部的实现细节都会一笔带过,在后续的篇章里再展开(或者说一篇太长了,写起来太累了哈哈哈哈哈哈狗😸)。
  要说第一点,就得先聊一下 Hive 作为元数据管理角色的地位。哪怕是现在比较流行的数据湖的概念,如 Hudi、Paimon等,大部分的使用场景也是用的 Hive Metastore(以下简称 HMS)来进行元数据管理,而 Sentry 内置的同步元数据功能也是和 Hive 进行深度绑定的。所以其实 Sentry 做的事情就是把 Hive 管理的元数据信息,同步到自己的数据库进行管理,和其他相关的信息如用户、用户组、所拥有的权限等维护映射关系。
  那另一块儿就是 Sentry 提供鉴权的能力。如前面所说,Sentry 已经有了自己的权限数据。然后 Sentry 就可以以接口地形式向外提供权限查询的能力。谁来查,当然就是上图的中各类组件的插件了。Sentry 通过提供各类插件,可插拔地对相关组件地权限进行管理。

2、Sentry 如何收集权限信息

  权限信息的增删改,要么是通过 sql 赋权语句,要么是用过编码 API 的方式来进行管理,来源途径不重要,Sentry 总能够获取到权限数据。怎么办到的呢,在上图中可以看到,在 Hive 内部有 2 处 Sentry 的实现在被动向 Sentry 推送数据,还有一个 Sentry 内部的 HMSFollower 在主动拉数据。

2.1、HMSFollower

  Sentry Server 启动时会启动一个 HMSFollower 主动和 HMS 进行交互

// SentryService
private void runServer() throws Exception {

	startSentryStoreCleaner(conf);
	startHMSFollower(conf);
	...
}

  这个 HMSFllower 可以简单理解成一个线程不断的请求 HMS 的 get_next_notification 接口,签名如下:

public NotificationEventResponse get_next_notification(NotificationEventRequest rqst) throws org.apache.thrift.TExcetion;

  所以这个接口是本身 HMS 就提供好的,是提供给外部系统获取库表等变更信息。要把这一块儿说清楚,其实得先说一下 Hive 这块儿本身的设计。
  都知道 Hive 的 Mysql 库里面存储了关于库表的信息,其实还有专门用来给 get_next_notification 准备的增量权限变更信息日志表。
在这里插入图片描述
  可以看到,这里面记录了增量的变更元数据,涉及的类型在 Hive EventType 定义中可见

public abstract class HCatEventMessage {

/**
* Enumeration of all supported types of Metastore operations.
*/
	public static enum EventType {
	
		CREATE_DATABASE(HCatConstants.HCAT_CREATE_DATABASE_EVENT),
		DROP_DATABASE(HCatConstants.HCAT_DROP_DATABASE_EVENT),
		CREATE_TABLE(HCatConstants.HCAT_CREATE_TABLE_EVENT),
		DROP_TABLE(HCatConstants.HCAT_DROP_TABLE_EVENT),
		ADD_PARTITION(HCatConstants.HCAT_ADD_PARTITION_EVENT),
		DROP_PARTITION(HCatConstants.HCAT_DROP_PARTITION_EVENT),
		ALTER_TABLE(HCatConstants.HCAT_ALTER_TABLE_EVENT),
		ALTER_PARTITION(HCatConstants.HCAT_ALTER_PARTITION_EVENT),
		INSERT(HCatConstants.HCAT_INSERT_EVENT),
		CREATE_FUNCTION(HCatConstants.HCAT_CREATE_FUNCTION_EVENT),
		DROP_FUNCTION(HCatConstants.HCAT_DROP_FUNCTION_EVENT),
		CREATE_INDEX(HCatConstants.HCAT_CREATE_INDEX_EVENT),
		DROP_INDEX(HCatConstants.HCAT_DROP_INDEX_EVENT),
		ALTER_INDEX(HCatConstants.HCAT_ALTER_INDEX_EVENT);
		...

  而第二列的 eventId 就是关键,在 get_next_notification 的 NotificationEventRequest 中,就携带了上次同步的最大 eventId,HMS 只需要从数据库里查出比参数 eventId 大的变更事件日志就可以了,具体逻辑在 Hive ObjectStore 中可以看到,这里 Sentry 是使用了 Datanucleus 框架的 API。

public NotificationEventResponse getNextNotification(NotificationEventRequest rqst) {
	boolean commited = false;
	Query query = null;
	
	NotificationEventResponse result = new NotificationEventResponse();
	result.setEvents(new ArrayList<NotificationEvent>());
	try {
		openTransaction();
		long lastEvent = rqst.getLastEvent();
		query = pm.newQuery(MNotificationLog.class, "eventId > lastEvent");	// 就这里
		query.declareParameters("java.lang.Long lastEvent");
		query.setOrdering("eventId ascending");
		Collection<MNotificationLog> events = (Collection) query.execute(lastEvent);
		commited = commitTransaction();
		if (events == null) {
			return result;
		}
		Iterator<MNotificationLog> i = events.iterator();
		int maxEvents = rqst.getMaxEvents() > 0 ? rqst.getMaxEvents() : Integer.MAX_VALUE;
		int numEvents = 0;
		while (i.hasNext() && numEvents++ < maxEvents) {
			result.addToEvents(translateDbToThrift(i.next()));
		}
		return result;
	}
	...

  然后 Sentry 接收到这些信息后解析后进行对应事件的处理,逻辑其实都比较简单。以一次 drop table 的事件为例,原先赋予在这张表上的角色权限,就得都删掉,因为表都不存在了,自然就不应该维护表的权限了。

2.2、SentryHiveAuthorizationTaskFactoryImply

  然后我们再来聊一下这个 SentryHiveAuthorizationTaskFactoryImply,它其实是实现了 HiveAuthorizationTaskFactory 接口,取代了默认的 HiveAuthorizationTaskFactoryImply。从这个名字能看出来是一个工厂类,作用是在解析 sql 的时候,生成对应 sql 的 org.apache.hadoop.hive.ql.exec.Task。实际要起作用的,就是对赋权有关的语句进行拦截,然后通知 Sentry 执行对应的赋权操作。以一个赋权语句 grant xxx on xx.xx to role xx 为例,SentryHiveAuthorizationTaskFactoryImply 就会创建出 Task 的子类 SentryGrantRevokeTask,其实例对象在执行的时候,就会调 processGrantDDL,最终调到 Sentry 客户端的 alter_Sentry_role_grant_privilege 方法,签名如下:

public TAlterSentryRoleGrantPrivilegeResponse alter_Sentry_role_grant_privilege(TAlterSentryRoleGrantPrivilegeRequest request) throws org.apache.thrift.TException;

  TAlterSentryRoleGrantPrivilegeRequest 里面包含了这条赋权的所有信息,那么 Sentry server收到消息后要做的事情也很简单,就是将角色和权限的映射关系持久化到数据库中,对应的表为 sentry_role_db_privilege_map

2.3、SentryMetaStorePostEventListener

  我们知道,Hive 的 Server2 和 HMS 是可以独立部署的,如果有的消息直接走的 HMS,那么前面的 SentryHiveAuthorizationTaskFactoryImply 可能就捕获不到了,但是,无论怎么样,这些数据必然都会经过 HMS,所以只要在 HMS 这一层做了拦截,那肯定就会万无一失了,所以 SentryMetaStorePostEventListener 就是在做这样的事。
  SentryMetaStorePostEventListener 是 Hive MetaStorePostEventListener 的子类,从名字可以看出来,是 HMS 本身基于监听器模式提供的扩展点。post 关键字说明了,在每一次 HMS 自己处理 event 之前,SentryMetaStorePostEventListener 就会先一步拦截执行相关操作,这部分的逻辑其实和上面的 SentryHiveAuthorizationTaskFactoryImply 类似,都是最终调到 Sentry 客户端对应事件的接口。

  这里顺便提一嘴,这个拓展点可以做的事情有很多,比如元数据采集,就可以自定义一个 listener 来拦截。

3、Sentry 如何提供鉴权能力

  接下来在下一篇博客中会选择几个比较典型的插件的实现,进行实现原理的剖析,就不放在一起了,不然篇幅过长(也许是害怕没墨汁了😼)。先简单聊一下实现原理和使用方式。

3.1、实现原理

  首先必须得说,得益于各个数据组件自身的可插件设计,本身提供了各自的拓展点,才能让各类权限插件能一展身手,无侵入,可插拔式地管理好整个权限生态。
  Sentry 本身提供了不少的组件插件,比如 Hive、HBase、Kafka、Solr、HDSF,虽然没有提供其他比较热门的框架比如 Spark、Presto 等,但其实都有对应的开源实现,也基本属于可以直接开箱即用。
  Sentry 的插件入口,通常是实现了各个组件提供的接口类,各个组件会有一个默认实现,那 Sentry 通过自己的实现类,和 Sentry 服务进行通信,获取到插件正在进行的鉴权动作所需要的权限信息,就能实现鉴权。

3.2、使用方式

  一般来讲,使用玩法通常都差不多,准备好插件包到类路径下,然后修改组件的配置项,把各自组件提供鉴权的拓展点的配置项改为 Sentry 插件里提供的类名,配置信息里还添加上 Sentry 服务的 ip 和端口。重启组件服务后,就会读取配置文件里面的全类名,通过反射的方式加载插件到内存中,按照实现逻辑提供鉴权服务。
  Sentry 对外以 Thrift 的方式暴露接口,插件的 Sentry 客户端就能拿到权限数据。暗示一下这里就和后续会讲到的平滑迁移 Ranger 有关了。


  拜拜ヾ(•ω•`)o~

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
SentryRanger是CDH中常用的细粒度授权管理工具,下面分别介绍它们的使用方法: 1. Sentry的使用 (1)安装和配置Sentry 首先需要在CDH集群中安装和配置Sentry服务。具体安装和配置步骤可以参考CDH文档中的说明。 (2)创建角色和授权 可以使用Sentry提供的命令行工具或Web界面来创建角色和授权。例如,以下命令可以创建一个名为“finance_analyst”的角色,并将其授权访问表“my_table”: ``` $ sentry --command create-role --role finance_analyst $ sentry --command grant --role finance_analyst --privilege "server=server1->db=my_database->table=my_table->action=select" ``` (3)验证授权 创建角色和授权之后,可以使用授权用户的身份来验证授权是否生效。例如,可以使用以下命令来验证用户“user1”是否可以访问表“my_table”: ``` $ beeline -u jdbc:hive2://localhost:10000 -n user1 -e "select * from my_table" ``` 2. Ranger的使用 (1)安装和配置Ranger 首先需要在CDH集群中安装和配置Ranger服务。具体安装和配置步骤可以参考CDH文档中的说明。 (2)创建策略和条件 可以使用Ranger提供的Web界面来创建策略和条件。例如,可以创建一个策略,仅允许特定用户访问表“my_table”。在创建策略时,可以指定访问条件,例如“user=user1”。 (3)验证授权 创建策略之后,可以使用授权用户的身份来验证授权是否生效。例如,可以使用以下命令来验证用户“user1”是否可以访问表“my_table”: ``` $ beeline -u jdbc:hive2://localhost:10000 -n user1 -e "select * from my_table" ``` 综上所述,SentryRanger的使用方法都比较简单,可以根据实际需求选择合适的工具来管理Hive数据表的访问权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫语大数据

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值