亚马逊AWS官方博客

在多主节点的 Amazon EMR 集群中实现用户身份认证与细粒度访问控制(二)Yarn 队列控制与 HBase Simple 认证

1. 介绍

本文衔接 《在多主节点的 Amazon EMR 集群中实现用户身份认证与细粒度访问控制(一)Open LDAP 身份认证与基于 Hive MateStore 的访问控制》,由于 Yarn 队列的权限管理和 HBase 的用户身份认证/数据访问控制不同于使用 Hive MateStore 的组件,因此单独撰写此文为大家介绍在多主节点的 Amazon EMR 集群实现 Yarn 队列的权限控制以及在 HBase 中实现身份认证和数据访问控制的解决方案。

2. Yarn 队列的权限控制

Yarn 队列管理

在 Yarn 中,负责给应用分配资源的是调度器(Scheduler)。Yarn 调度器根据容量、队列等限制条件,将系统中的资源分配给各个正在运行的应用程序。调度器仅根据各个应用程序的资源需求进行资源分配,而资源分配单位是 Container,从而限定每个任务使用的资源量。Scheduler 不负责监控或者跟踪应用程序的状态,也不负责任务因为各种原因而需要的重启(由 ApplicationMaster 负责)。总之,调度器根据应用程序的资源要求,以及集群机器的资源情况,为用程序分配封装在 Container 中的资源。调度器是可插拔的,例如 CapacityScheduler、FairScheduler。

在使用 Amazon EMR 中的运行 Hive 、Spark 应用进行数据处理时,都会依赖 Yarn 作为任务队列的调度服务,Amazon EMR 的 Yarn 默认支持的是 CapacityScheduler 调度器,Capacity 调度器允许多个组织共享整个集群,每个组织可以获得集群的一部分计算能力。通过为每个组织分配专门的队列,然后再为每个队列分配一定的集群资源,这样整个集群就可以通过设置多个队列的方式给多个组织提供服务了。除此之外,队列内部又可以垂直划分,这样一个组织内部的多个成员就可以共享这个队列资源了,在一个队列内部,资源的调度是采用的是先进先出(FIFO)策略。对于有多个团队或者和多个应用向 Amazon EMR 中提交任务时,通过 Capacity Scheduler 作为资源队列的管理,默认只有 root.default 一个队列。当不同用户提交任务时,任务会在这个队列中,按 FIFO 的优先级调度,这很大程度上影响了多个用户同时提交任务时资源的利用率,并且也缺少对不同用户提交任务所使用资源的控制。因此,我们需要在 Yarn 中创建多个队列,并且能根据提交的用户来分配用户所属的队列。

本方案中,我们使用 Apache Ranger 的 Yarn Plugin 来进行队列的权限控制。

2.1 Ranger Yarn Plugin 编译部署

下载源码并编译,这里我们使用 Apache Ranger 2.1 版本

git clone https://github.com/apache/ranger.git --branch ranger-2.1

将编译后的文件包 ranger-2.1.1-SNAPSHOT-yarn-plugin.tar.gz 上传至 Amazon EMR Master 节点,并且解压。

按如下配置,修改配置文件 install.properties

POLICY_MGR_URL=http://<ranger-server>:6080
REPOSITORY_NAME=yarndev

修改文件 vi enable-yarn-plugin.sh

HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}/share/hadoop/hdfs/lib 修改为 HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}

修改完成后执行启用,并且重启 Yarn ResourceManager 服务

sudo ./enable-yarn-plugin.sh
sudo systemctl restart hadoop-yarn-resourcemanager

2.2 创建 Yarn 队列

如下配置,将 root 队列分配给三个子队列 default(40%),alpha(30%),beta(30%)

  • 用户 test05 分配给队列 alpha
  • 用户 example-user-2 分配给队列 beta
  • 用户 example-user-1 分配给队列 default

在 Amazon EMR 的集群配置中添加如下内容:

{
    "Classification": "capacity-scheduler",
    "Properties": {
        "yarn.scheduler.capacity.root.queues": "default,alpha,beta",
        "yarn.scheduler.capacity.root.default.capacity": "40",
        "yarn.scheduler.capacity.root.default.accessible-node-labels.CORE.capacity": "40",
        "yarn.scheduler.capacity.root.alpha.capacity": "30",
        "yarn.scheduler.capacity.root.alpha.accessible-node-labels": "*",
        "yarn.scheduler.capacity.root.alpha.accessible-node-labels.CORE.capacity": "30",
        "yarn.scheduler.capacity.root.beta.capacity": "30",
        "yarn.scheduler.capacity.root.beta.accessible-node-labels": "*",
        "yarn.scheduler.capacity.root.beta.accessible-node-labels.CORE.capacity": "30"
    },
    "Configurations": []
},
{
    "Classification": "yarn-site",
    "Properties": {
        "yarn.scheduler.capacity.queue-mappings": "u:test05:alpha,u:example-user-1:default,u:example-user-2:beta"
    },
    "Configurations": []
}

在 Yarn UI 上查看队列

使用用户 test05,通过 beeline 查询 hive 表的数据。在 yarnUI 观察,test05 提交的作业已经在 alpha 队列中运行。

下面,我们来验证如何通过 Ranger Yarn Plugin 管控 Yarn 的队列。

2.2 验证 Yarn Plugin

在 Ranger UI 中添加插件,Server Name 需要和部署时配置文件的 REPOSITORY_NAME 名称一致,YARN REST URL,使用 Yarn UI 的地址。

在 Ranger 中创建一个策略,设置用户 test05 拥有 alpha 队列的权限,hadoop 用户没有权限。

先用 hadoop 用户提交任务到 alpha 队列,提示 hadoop 用户没有提交任务的权限。

spark-submit —class org.apache.spark.examples.SparkPi \
—proxy-user=hadoop —queue=beta —master yarn —deploy-mode cluster \
—conf spark.driver.memoryOverhead=512 —conf spark.executor.memoryOverhead=512 \
/usr/lib/spark/examples/jars/spark-examples.jar 100

使用 test05 用户提交任务到 alpha 队列,可以正常运行。

spark-submit --class org.apache.spark.examples.SparkPi \
--proxy-user=test05 --queue=beta --master yarn --deploy-mode cluster \
--conf spark.driver.memoryOverhead=512 --conf spark.executor.memoryOverhead=512 \
/usr/lib/spark/examples/jars/spark-examples.jar 100

这样,我们就实现了通过 Apache Ranger 的 Yarn Plugin 来控制用户与队列的权限控制。

3. HBase Simple 用户认证与数据访问控制

HBase 是一种开源、非关系型分布式数据库。它作为 Apache 软件基金会的 Hadoop 项目的一部分开发。HBase 在 Hadoop Distributed File System(HDFS)上运行,为 Hadoop 生态系统提供非关系数据库功能。而在 Amazon EMR 中使用 HBase 时,我们可以将 HBase 的数据直接存放于 S3,成为存算分离的架构,在启动含有 HBase 的 Amazon EMR 集群时,可以从之前创建的 HBase 集群中备份还原。通过这种方式,实现了数据持久性和灾备。

下面,我们来介绍,在 Amazon EMR 中使用 HBase 时,如何进行用户身份认证以及对数据权限进行访问控制。

3.1 关于 HBase 的用户认证与数据访问控制

身份认证

HBase 中有两种身份验证方式,一种使用强身份验证运行 HBase RPC,通过 kerberos,另一种,是简单用户访问(simple)。在 Amazon EMR 中,如果使用多主节点部署,无法使用 kerberos 服务,因此我们选择用 Simple 用户认证的方式来实现。

数据访问控制

在 HBase 客户端和服务器进程和网关之间配置安全身份验证后,需要考虑数据本身的安全性。HBase 提供了基于角色的访问控制(RBAC)使用熟悉的角色范例控制哪些用户或用户组可以读取和写入给定的 HBase 资源或执行协处理器端点。

3.2 配置

在 Amazon EMR 中添加如下配置,开启 HBase 的 Simple 认证

{
    "classification": "hbase-site",
    "properties": {
        "hbase.coprocessor.master.classes": "org.apache.hadoop.hbase.security.access.AccessController",
        "hbase.coprocessor.regionserver.classes": "org.apache.hadoop.hbase.security.access.AccessController",
        "hbase.superuser": "root,hadoop,hbase",
        "hbase.coprocessor.region.classes": "org.apache.hadoop.hbase.security.access.AccessController",
        "hbase.security.authentication": "simple",
        "hbase.security.authorization": "true"
    },
    "configurations": []
}

需要应用到集群所有活动实例(多 master 中所有的 master 与 core 节点配置都是如此),如下:

3.3 HBase 中的权限访问控制

HBase 支持以下 5 种权限

  1. Read( R ) 允许对某个 scope 有读取权限
  2. Write( W ) 允许对某个 scope 有写入权限
  3. Execute( X ) 允许对某个 scope 有执行权限
  4. Create( C ) 允许对某个 scope 有建表、删表权限
  5. Admin( A ) 允许对某个 scope 做管理操作,如 balance、split、snapshot 等

Scope 包含以下几种

类型 说明
superuser 超级用户,一般为 Hbase 用户,有所有的权限
global 全局权限,针对所有的 HBase 表都有权限
namespace namespace下面的所有表权限都有权限
table 表级别权限
columnFamily 列族级别权限
cell 单元格级别权限

HBase 的访问控制相关命令

hbase> grant <user> <permissions> [ @<namespace> [ <table>[ <column family>[ <column qualifier> ] ] ] ]
hbase> revoke <user> <permissions> [ @<namespace> [ <table> [ <column family> [ <column qualifier> ] ] 
hbase> user_permission <table>

授权命令参考

命令 说明
grant 'root','RWXCA' 给 root 用户授权全局的 CA
revoke 'root','RWXCA' 回收 root 用户全局的 CA
grant 'root','RWXCA','@TRAF_1500000' 给 root 用户 namespace 权限
grant 'root','RWXCA','agatha' 给 root 用户 table 权限
user_permission 查看所有用户权限
user_permission 'agatha' 查看某个表的权限
user_permission '@TRAF_1500000' 查看某个 namespace 的权限
create_namespace 'ns1' 创建 namespace
list_namespace 列出所有 namespace
describe_namespace 'ns1' 查看 namespace
drop_namespace 'ns1' 删除 namespace
create 'ns1:testtable', 'cf1','cf2' 在 namespace 下创建表
list_namespace_tables 'ns1' 查看 namespace 下的表

3.4 HBase 权限授权验证

以下介绍在 Amazon EMR Hbase 中的几种授权场景的验证。

3.4.1 测试全局授权

授权前使用 admin 用户访问 HBase 执行操作,提示 admin 用户没有权限操作

hbase(main):001:0> whoami
admin (auth:SIMPLE)
  groups: admin, admin
 
hbase(main):002:0> list
TABLE 
0 row(s) in 0.2000 seconds
 
=> []
hbase(main):003:0> create_namespace 'my_ns_admin'
 
ERROR: org.apache.hadoop.hbase.security.AccessDeniedException: Insufficient permissions for user 'admin' (global, action=ADMIN)
 
Create namespace; pass namespace name,
and optionally a dictionary of namespace configuration.
Examples:
  hbase> create_namespace 'ns1'
  hbase> create_namespace 'ns1', {'PROPERTY_NAME'=>'PROPERTY_VALUE'}

使用 Hbase 超级管理员,为 admin 用户组全局范围授权,授权 admin 用户有创建表的权限。

hbase(main):001:0> whoami
hbase (auth:SIMPLE)
  groups: hbase
 
hbase(main):002:0> grant '@admin', 'CA'
0 row(s) in 0.3170 seconds
 
hbase(main):003:0> user_permission
User Namespace,Table,Family,Qualifier:Permission 
 @admin  hbase,hbase:acl,,: [Permission: actions=CREATE,ADMIN] 
1 row(s) in 0.0610 seconds
 
hbase(main):004:0> user_permission '.*'
User Namespace,Table,Family,Qualifier:Permission 
 @admin  hbase,hbase:acl,,: [Permission: actions=CREATE,ADMIN] 
1 row(s) in 0.8710 seconds

使用 admin 用户访问 Hbase,执行操作,如下,可以看到 admin 用户可以创建 namespace,也可以创建表。但是,没有给 admin 用户赋权其他表的操作权限,它无法查看非 admin 用户创建的表数据。

hbase(main):004:0> create_namespace 'my_ns_admin'
0 row(s) in 0.0460 seconds
 
hbase(main):005:0> create 'my_ns_admin:testtable', 'f1'
0 row(s) in 1.2700 seconds
 
=> Hbase::Table - my_ns_admin:testtable
hbase(main):006:0> put 'my_ns_admin:testtable','0001','f1:name','charels'
0 row(s) in 0.1240 seconds
 
hbase(main):007:0> scan 'my_ns_admin:testtable'
ROW COLUMN+CELL 
 0001  column=f1:name, timestamp=1569227721451, value=charels 
1 row(s) in 0.0430 seconds
 
hbase(main):008:0> scan 'my_ns:test'
ROW COLUMN+CELL 
 
ERROR: org.apache.hadoop.hbase.security.AccessDeniedException: Insufficient permissions for user 'admin' (table=my_ns:test, action=READ)

3.4.2 测试表授权

1. 使用 test 用户访问 HBase,进行操作,未给 test 用户授予任何权限,该用户查看不到任何表,也无法创建表。

hbase(main):001:0> whoami
test (auth:SIMPLE)
  groups: charles
 
hbase(main):002:0> list
TABLE 
0 row(s) in 0.1960 seconds
 
=> []
hbase(main):003:0> create 'test','f1'
 
ERROR: org.apache.hadoop.hbase.security.AccessDeniedException: Insufficient permissions (user=test, scope=default, params=[namespace=default,table=default:test,family=f1],action=CREATE)

2. 使用超级用户 Hbase 为 test 用户授予 my_ns_admin:charles_testtable 表的 RW 权限,拥有 RW 权限的 test 用户则可以看到该表,并可以对该表进行读写操作,但无法进行其他操作。

hbase(main):008:0> whoami
charles (auth:SIMPLE)
  groups: hbase
 
hbase(main):009:0> grant 'test','RW','my_ns_admin:charles_testtable'
0 row(s) in 0.1420 seconds
 
hbase(main):012:0> user_permission '.*'
User Namespace,Table,Family,Qualifier:Permission 
 test  my_ns_admin,my_ns_admin:charles_testtable,,: [Permission: actions=READ,WRITE] 
1 row(s) in 0.0260 seconds

3. 再次使用 test 用户访问 HBase,这时 test 用户拥有查看 my_ns_admin:charles_testtable 表的权限,并且可以向这张表中写入数据。

hbase(main):005:0> whoami
test (auth:SIMPLE)
  groups: charles
 
hbase(main):006:0> list
TABLE 
my_ns_admin:charles_testtable 
1 row(s) in 0.0140 seconds
 
=> ["my_ns_admin:charles_testtable"]

hbase(main):008:0> scan "my_ns_admin:charles_testtable"
ROW COLUMN+CELL 
 0001  column=f1:name, timestamp=1569295080614, value=charles 
 0002  column=f1:name, timestamp=1569308212541, value=charles 
2 row(s) in 0.2050 seconds
 
hbase(main):009:0> put 'my_ns_admin:charles_testtable','0001','f2:age',’24’
0 row(s) in 0.0820 seconds
 
hbase(main):010:0> scan "my_ns_admin:charles_testtable"
ROW COLUMN+CELL 
 0001  column=f1:name, timestamp=1569295080614, value=charles 
 0001  column=f2:age, timestamp=1569313276830, value=24 
 0002  column=f1:name, timestamp=1569308212541, value=charles 
2 row(s) in 0.0150 seconds

3.4.3 测试 namespace 授权

1. 使用用户 charles 登录 HBase,并且创建表,由于 charles 并没有分配权限,因此它无法创建表。

hbase(main):001:0> whoami
charles (auth:SIMPLE)
  groups: charles, sudo, usr01
 
hbase(main):002:0> create 'my_ns_admin:charles_table','f1'
 
ERROR: org.apache.hadoop.hbase.security.AccessDeniedException: Insufficient permissions (user=charles, scope=my_ns_admin, params=[namespace=my_ns_admin,table=my_ns_admin:charles_table,family=f1],action=CREATE)

2. 使用超级用户 Hbase 为用户 charles 授权 my_ns_admin 空间的所有权限

hbase(main):018:0> whoami
hbase (auth:SIMPLE)
  groups: hbase
 
hbase(main):019:0> grant 'charles','RWCXA','@my_ns_admin'
0 row(s) in 0.0500 seconds

3. 授权后,再进行以下操作,可以看到,charles 用户被授权了 my_ns_admin 空间下所有权限(RWCXA),则可以在该空间下创建、删除表、也可以向该空间下所有表 put 数据等操作,对于未授权的其它空间无任何操作权限。

hbase(main):004:0> list
TABLE 
my_ns_admin:testtable 
1 row(s) in 0.0190 seconds
 
=> ["my_ns_admin:testtable"]
 
hbase(main):005:0> create 'my_ns_admin:charles_testtable','f1','f2'
0 row(s) in 1.2390 seconds
 
=> Hbase::Table - my_ns_admin:charles_testtable
hbase(main):006:0> put 'my_ns_admin:charles_testtable','0001','f1:name','charles'
0 row(s) in 0.1450 seconds
 
hbase(main):007:0> scan 'my_ns_admin:charles_testtable'
ROW COLUMN+CELL 
0001  column=f1:name, timestamp=1569295080614, value=charles 
1 row(s) in 0.0570 seconds
 
hbase(main):008:0> scan 'my_ns_admin:testtable'
ROW COLUMN+CELL 
0001  column=f1:name, timestamp=1569227721451, value=charels 
1 row(s) in 0.0240 seconds
 
hbase(main):009:0> put 'my_ns_admin:testtable','0001','f1:age',28
0 row(s) in 0.0080 seconds
 
hbase(main):010:0> scan 'my_ns_admin:testtable'
ROW COLUMN+CELL 
0001  column=f1:age, timestamp=1569295103019, value=28 
0001  column=f1:name, timestamp=1569227721451, value=charels 
1 row(s) in 0.0520 seconds

3.5 HBase 权限总结

  1. HBase 既可以针对用户也可以针对用户组进行授权,如果需要针对用户组授权则需要在用户组前添加 “@”(如:grant ‘@admin’, ‘RWXCA’)。
  2. 在 EMR 中 HBase 支持 Global、NameSpace、Table、ColumnFamily 范围授权。
  3. 拥有 Admin(A) 权限的用户,可以为其它用户进行任何级别授权,在使用 HBase 授权时需要慎用。
  4. 当为用户或用户组拥有 CA 权限时,用户和用户组创建表时会默认的为当前操作用户添加该表的 RWXCA 权限。
  5. 可以下面语法查看当前 HBase 的授权。
hbase> user_permission
hbase> user_permission '@ns1'
hbase> user_permission '@.*'
hbase> user_permission '@^[a-c].*'
hbase> user_permission 'table1'
hbase> user_permission 'namespace1:table1'
hbase> user_permission '.*'
hbase> user_permission '^[A-C].*'

4. 总结

目前随着用户越来越重视数据的安全合规,当基于 Amazon EMR 做为最重要的组件之一来构建数据湖时,如何对 Amazon EMR 的数据访问控制是非常重要的。本博客提供的解决方案提供一个全面的 Amazon EMR 数据访问控制和权限管理框架,帮助有数据细粒度权限管控要求的 Amazon EMR 用户,并且会通过多种连接方式(客户端 CLI,Hue,Beeline 等)访问 Amazon EMR 的场景,实现了基于 Hive MetaStore 的多组件(Hive、Trino、Spark、Yarn 队列、HBase)的身份认证,并且分别通过使用 Hive MetaStore Plugin 、Yarn Plugin、Simple 用户等方式实现细粒度的统一管理 Hive、SparkSQL、Trino、Tez 、Yarn 队列、 HBase 访问 Amazon EMR 中数据的权限控制,满足了 Amazon EMR 的安全管理和控制,确保只有经过授权的用户可以访问和操作数据。

5. 参考资料

https://aws.amazon.com/cn/blogs/china/amazon-emr-authentication-scheme-based-on-openldap-and-kerberos-i-integrating-background-databases/

https://aws.amazon.com/cn/blogs/china/amazon-emr-authentication-scheme-based-on-openldap-and-kerberos-ii-synchronize-ldap-accounts-based-on-sssd/

https://docs.aws.amazon.com/zh_cn/emr/latest/ReleaseGuide/emr-presto-ldap.html

https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-presto-ldap.html

本篇作者

黄霄

亚马逊云科技数据分析解决方案架构师,专注于大数据解决方案架构设计,具有多年大数据领域开发和架构设计经验。

胡正光

AWS 解决方案架构师,15 年 IT 行业经验,目前负责基于 AWS 云计算方案架构的咨询和设计。