1、编写文档的目的

1.1、背景

在实际的生产系统中,往往面临着多租户的问题,多租户技术(多重租赁技术)是一种软件架构技术,它是在探讨与实现如何于多用户的环境下共用相同的系统或程序组件,并且仍可确保各用户间数据和资源的隔离性。

1.2、模拟要求

  1. 有 3 个业务部门分别为 A、B、C,A 业务部门使用集群资源的 40%,B 业务部门使用集群资源的 30%,C 业务部门使用集群资源的 20%,剩下的给到默认的资源池。
  2. 各个业务部门下分别有业务人员:

A 业务部门:auser1、auser2、auser3
B 业务部门:buser1、buser2、buser3
C 业务部门:cuser1、cuser2、cuser3

  1. 根据上述场景需求在 CDH 集群中为各个业务部门分配多租户。

    1.3、要求

  2. 所有用户均在OpenLDAP上进行管理

  3. 集群已启用Kerberos
  4. 各个业务部门的用户作业只能提交到各个业务部门对应的资源池下根据上述要求完成企业多租户配置及资源池划分。

    1.4、测试环境

  5. RedHat7

  6. CM、CDH版本5.16.2
  7. 集群已启用Kerberos

    2、多租户配置

    2.1、用户的创建和添加

  8. 按照要求,规划的用户和用户组信息如下,密码统一为 123456 | UserName | uid | GroupName/gid | | —- | —- | —- | | auser1 | 1008 | groupa/1111 | | auser2 | 1009 | groupa/1111 | | auser3 | 1010 | groupa/1111 | | buser1 | 1011 | groupa/1112 | | buser2 | 1012 | groupa/1112 | | buser3 | 1013 | groupa/1112 | | cuser1 | 1014 | groupa/1113 | | cuser2 | 1015 | groupa/1113 | | cuser3 | 1016 | groupa/1113 |

  9. 编辑users.ldif文件,添加如下内容 ```shell dn: uid=auser1,ou=People,dc=macro,dc=com uid: auser1 cn: auser1 objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: 123456 shadowLastChange: 18009 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1008 gidNumber: 1111 homeDirectory: /home/auser1

dn: uid=auser2,ou=People,dc=macro,dc=com uid: auser2 cn: auser2 objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: 123456 shadowLastChange: 18009 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1009 gidNumber: 1111 homeDirectory: /home/auser2 dn: uid=auser3,ou=People,dc=macro,dc=com

uid: auser3 cn: auser3 objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: 123456 shadowLastChange: 18009 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1010 gidNumber: 1111 homeDirectory: /home/auser3

dn: uid=buser1,ou=People,dc=macro,dc=com uid: buser1 cn: buser1 objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: 123456 shadowLastChange: 18009 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1011 gidNumber: 1112 homeDirectory: /home/buser1

dn: uid=buser2,ou=People,dc=macro,dc=com uid: buser2 cn: buser2 objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: 123456 shadowLastChange: 18009 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1012 gidNumber: 1112 homeDirectory: /home/buser2

dn: uid=buser3,ou=People,dc=macro,dc=com uid: buser3 cn: buser3 objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: 123456 shadowLastChange: 18009 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1013 gidNumber: 1112 homeDirectory: /home/buser3

dn: uid=cuser1,ou=People,dc=macro,dc=com uid: cuser1 cn: cuser1 objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: 123456 shadowLastChange: 18009 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1014 gidNumber: 1113 homeDirectory: /home/cuser1

dn: uid=cuser2,ou=People,dc=macro,dc=com uid: cuser2 cn: cuser2 objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: 123456 shadowLastChange: 18009 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1015 gidNumber: 1113 homeDirectory: /home/cuser2

dn: uid=cuser3,ou=People,dc=macro,dc=com uid: cuser3 cn: cuser3 objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: 123456 shadowLastChange: 18009 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1016 gidNumber: 1113 homeDirectory: /home/cuser3

  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/2680099/1607307807845-c4085001-63e7-4e60-82b0-efb3a48968b2.png#align=left&display=inline&height=698&margin=%5Bobject%20Object%5D&name=image.png&originHeight=896&originWidth=958&size=76078&status=done&style=none&width=746)
  2. 3. 编辑groups.ldif文件,添加如下内容
  3. ```shell
  4. dn: cn=groupa,ou=Group,dc=macro,dc=com
  5. objectClass: posixGroup
  6. objectClass: top
  7. cn: groupa
  8. userPassword: {crypt}x
  9. gidNumber: 1111
  10. dn: cn=groupb,ou=Group,dc=macro,dc=com
  11. objectClass: posixGroup
  12. objectClass: top
  13. cn: groupb
  14. userPassword: {crypt}x
  15. gidNumber: 1112
  16. dn: cn=groupc,ou=Group,dc=macro,dc=com
  17. objectClass: posixGroup
  18. objectClass: top
  19. cn: groupc
  20. userPassword: {crypt}x
  21. gidNumber: 1113

image.png

  1. 添加用户

    1. ldapadd -D "cn=Manager,dc=macro,dc=com" -W -x -f users.ldif
    2. ldapadd -D "cn=Manager,dc=macro,dc=com" -W -x -f groups.ldif

    image.png
    image.png

  2. Kerberos 服务器创建上面用户的 principal在 KDC 节点,命令行进行操作,密码也全部设置成 123456

    1. kadmin.local
    2. addprinc auser1
    3. addprinc auser2
    4. addprinc auser3
    5. addprinc buser1
    6. addprinc buser2
    7. addprinc buser3
    8. addprinc cuser1
    9. addprinc cuser2
    10. addprinc cuser3

    image.png

  3. 查看是否创建成功

    1. listprincs

    image.png2.2、启用 YARN 的 ACL

  4. CM 界面进入 YARN,选择配置,搜索 acl,如图勾选启用

image.png

  1. 由于 YARN 的 8088 界面默认使用的是 dr.who 用户来访问的,如果设置了 YARN 的ACL,想要查看作业的详细日志,需要把 dr.who 用户加入到 yarn.admin.acl 里。

image.png

  1. 在下面管理 ACL 处,配置为 dr.who 注意,如果只填写组的时候,前面必须有一个空格,代表的是用户名为空,不同的组之间用逗号隔开。这里如果什么都不配置(留空),后面资源池的访问管理控制项的配置不会生效。

  2. 配置好后,点击保存更改

image.png

  1. 重启集群服务

image.png
image.png
image.png

2.3、创建队列并进行 ACL 设置

  1. 在这里需要配置 root 队列的 ACL,如果不配置,前面添加的队列提交访问控制权限可能不会生效,因为子队列会继承父队列的权限。配置如下图

image.png

  1. 从 CM 进入动态资源池配置

image.png

  1. 新建队列groupa,如下图:

image.png

  1. 计划策略项选择 DRF

image.png

  1. 提交访问控制在【组】这一行选择填写groupa。

image.png

  1. 配置【管理访问控制】,在组这一行选中groupa

image.png

  1. 配置好之后保存,同样的配置 groupb 和 groupc,然后点击刷新动态资源池

image.png

2.4、配置放置规则

  1. 在动态资源池配置里选择放置规则,把默认的先全部删除掉,再创建放置规则。

image.png

  1. 根据要求,我们要每个业务部门的用户,只能提交到自己部门对应的资源池下。第一个设置为在运行时使用指定的资源池,这是为了后面验证各自的组只能在自己的资源池下运行。如下图

image.png

  1. 第二个就选择使用与该用户的主要组匹配的资源池,并且不勾选下面的‘在池不存在时创建池’, 这个可以在不指定资源池的情况下,让对应的用户运行在对应的资源池下运行。

image.png

  1. 执行的时候根据放置规则的顺序 1、2、3…进行判断,判断到满足条件的放置规则后,后续的规则不再进行匹配。编辑好后,刷新动态资源池。

image.png

3、验证

3.1、使用 auser1 用户往 root.groupa 队列提交作业

  1. 切换auser1用户并查看

    1. kinit auser1

    image.png

  2. 提交作业到 root.groupa

    1. hive -e "set mapreduce.job.queuename=root.groupa;select count(*) testhive;"

    image.png

  3. 从 YARN 的应用程序界面也可以看到下面信息,job ID 为 job_1607310687593_0004 用户是 auser1,使用的资源池队列为 root.groupa 都满足要求。

image.png

  1. 其他用户同理

    3.2、使用 auser1 用户往 root.groupb 队列提交作业

    1. klist
    2. hive -e "set mapreduce.job.queuename=root.groupb;select count(*) testhive;"

    image.png

  2. 我们同样到 YARN 应用程序下面去查看一下结果。可以看到提示错误,任务 ID,用户和资源池都符合刚才提交的,再点击 ID 进去看下具体信息

image.png

  1. 可以看到用户 auser1 不能提交任务到队列 root.groupb,符合我们设计的要求。

image.png

3.3、使用 auser1 用户 kill 掉 auser1 提交的作业

  1. 先在一个节点登录 auser1 的 principal 提交一个作业,提交作业的同时,在另外节点也登录 auser1 的 principal 执行命令来终止作业。

    1. kinit auser1
    2. klist
    3. hive -e "set mapreduce.job.queuename=root.groupa;select count(*) testhive;"

    image.png

  2. 在提交任务的同时,另外一个节点用命令查询提交的任务 ID,然后再执行命令终止任务,如下:

    1. kinit auser1
    2. klist
    3. yarn application -list
    4. yarn application -kill 进程号

    image.png

  3. 在 YARN 的应用程序界面也可以看到任务执行的情况,显示状态是已停止

image.png

  1. 从 ID 点进去可以看到详细信息,Application killed by user

image.png

3.4、使用 auser1 用户 kill 掉 buser2 提交的作业

  1. 节点1登录auser1,提交作业,同时在另一个节点登录buser2执行命令停止作业

    1. kinit auser1
    2. klist
    3. hive -e "set mapreduce.job.queuename=root.groupa;select count(*) testhive;"

    image.png

  2. 在提交任务的同时,另外一个节点用命令查询提交的任务 ID,然后再执行命令终止任务,如下:

    1. kinit buser2
    2. klist
    3. yarn application -list
    4. yarn application -kill 进程号

    image.png

  3. 在 YARN 的应用程序界面也可以看到任务执行成功

image.png

  1. 点击 ID 可以进去看到详情

image.png

3.5、不指定资源池队列,验证放置规则是否生效

  1. 前面的放置规则如下图,第一个是按照指定的资源池来提交,第二个是提交到该用户匹配的主要组的资源池。前面已经测试过指定资源池了,这里不指定资源池,看看放置规则是否生效。
  2. 分别登录auser1,buser1,cuser1

image.png

  1. 使用xmoba多窗口同时执行作业,这里测试三个用户 auser2,buser3,cuser1,看他们分别提交任务到那个资源池中了。

    1. hive -e "select count (*) from testhive"

    image.png

  2. 可以看到 auser2 提交到了 root.groupa 队列,buser3 提交到了 root.groupb 队列,cuser1 提交到了 root.groupc 队列。放置规则生效。

image.png

3.6、验证资源池权重是否生效

  1. 按照要求,当前资源池权重配置如下 default:groupa:groupb:groupc=1:4:3:2 如下图

image.png

  1. 那么,我们同时提交 4 个任务,按照放置规则,默认分别到 4 个资源池队列中,然后来看他们使用资源的比例,是否符合要求。分别切换到用户ldapuser1,auser1,buser1,cuser1,然后分别登陆对应的 principal,再开始提交任务,查看资源分配情况。

image.png

  1. 在 CM 主页进入 YARN,点击资源池,在主页面上可以看到资源池的使用率,里面有每个资源池队列分配的资源。可以看到比例是按照我们设置的权重来分配的。

image.png

  1. 另外,从 YARN 的 ResourceManager Web UI 也可以查看资源分配详情。在 WEB UI 界面,点击左边 Scheduler 可以看到下图的资源分配数据,也是和我们设置符合的。

image.png

  1. 至此,验证成功,资源池权重配置生效。

    4、问题及解决方案

    4.1、MapReduce作业失败

  2. 运行MapReduce报错权限不足问题,截图如下:

image.png
原因:hdfs的/user目录下没有auser1目录。
解决方案:切换hdfs用户创建目录并赋予权限。

  1. kinit hdfs
  2. klist
  3. hdfs dfs -mkdir /user/auser1
  4. hdfs dfs -chown -R auser1:groupa /user/auser1
  5. hdfs dfs -ls /user/

image.png

  1. 改完权限发现hive权限不足,错误截图如下:

image.png
原因:由于已集成sentry,auser1用户无法读取testhive表
解决方法:切换hive用户为auser1赋予读写权限

  1. kinit hive
  2. klist
  3. beeline
  4. !connect jdbc:hive2://cdh1.macro.com:10000
  5. ------------------------------------------
  6. grant role read to group groupa;
  7. grant role write to group groupa;

image.png

  1. 刷新元数据权限生效