之前为了练习英语用英文写的这个博客,然后被编辑置为转载了,所以想想还是翻译过来比较好。
原文发表于 https://xianglei.tech 确实是我自己原创的。英文很烂,所以才需要练习。
使用Cloudera Manager启用Kerberos安全增强的Hadoop集群(包括一步步安装和配置kerberos)以及kerberos基本原理
目前我工作于AdMaster,某个全球五百强的大企业是我们的深度客户,我为其提供大数据底层平台的技术支持。他们的要求是使用正版的Cloudera Manager来进行集群的管理和操作,约定版本为5.10,这个后续会成为坑中之一,以后的博客我会讲述这个故事。同时他们要求使用Kerberos来进行安全性管理,说实话,我对Kerberos的集群一点好感也没有,但是花钱的是大爷,我没辙。所以上周我用Cloudera Manager辅助搭建了一个Kerberos的Hadoop集群,然后这个是一篇使用Cloudera Manager来搭建安全增加集群的记录。首先,我们需要一个可以跑的Hadoop集群,而且已经提前装好了Kerberos的KDC和其他clients
1. 安装KDC服务器
只需要在一台服务器上运行下面这句话,KDC只安装于一台独立的服务器上
sudo yum -y install krb5-server krb5-libs krb5-workstation krb5-auth-dialog openldap-clients
这个命令会安装KDC Server和krb5-workstation,这是kerberos的client,里面包含了很多有用的命令
2. 修改 /var/kerberos/krb5kdc/kdc.conf
kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] PG.COM = { #master_key_type = aes256-cts acl_file = /var/kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal max_renewable_life = 7d }
把EXAMPLE.COM修改成PG.COM
增加 add max_renewable_life = 7d 意味着7天,或者更长时间,也可以使用4w表示4周
3. 修改/etc/krb5.conf
libdefaults]default_realm = PG.COM dns_lookup_kdc = false dns_lookup_realm = false ticket_lifetime = 259200 renew_lifetime = 604800 forwardable = true default_tgs_enctypes = rc4-hmac default_tkt_enctypes = rc4-hmac permitted_enctypes = rc4-hmac udp_preference_limit = 1 kdc_timeout = 3000 [realms] PG.COM = { kdc = pg-dmp-master2.hadoop admin_server = pg-dmp-master2.hadoop }
EXAMPLE.COM 徐改成 PG.COM 并且在 [realms] 里面, kdc 指向到安装了KDC的服务器已经安装了kadmin的服务器
4. 创建这个realm
kdb5_util create -s -r PG.COM
这会创建一个叫做PG.COM的工作realm,Kerberos允许同时存在管理多个realm
5. 在KDC服务器上创建管理员用户的pricipal
kadmin.local -q "addprinc root/admin"
我在Linux的root账号下使用 root/admin 作为管理员用户,作为admin用户,你可以使用不同于linux的单独的密码,注意,这和linux的root并不是同一个账号,所以,你不用担心你的linux root用户密码会改变。 root/admin只存在于kerberos的数据库中,它和linux的root是两个分开独立的账号
6. 编辑 /var/kerberos/kadm.acl
*/[email protected]
这个用来定义哪些人是PG.COM这个realm的管理员,这句话意味着,凡是挂着/[email protected]的所有用户都是管理员,只要你添加了这个账号。
7. 检查所有的Kerberos配置文件,确保没有错误
/etc/krb5.conf
/var/kerberos/krb5kdc/krb.conf
/var/kerberos/krb5kdc/kadm.acl
8. 然后启动KDC和Kadmin服务
service krb5kdc start service kadmin start
9. 然后登录到集群的其他节点,运行以下命令
yum install krb5-workstation krb5-libs krb5-auth-dialog openldap-clients cyrus-sasl-plain cyrus-sasl-gssapi
在所有节点上安装kerberos的客户端
然后,回到CLoudera Manager,点击集群,操作,在下拉菜单找到启用kerberos或启用安全。然后所有选项打钩,下一步,下一步,下一步,一直到完事。
所有步骤完成之后,你就可以使用kerberos增强的hadoop集群了
这里有几个在安装安全集群中可能会遇到的问题
我如何添加一个新的用户pricipal?
kadmin.local -q "addprinc [email protected]"
需要注意的是,当你想添加了一个普通用户到集群时,你需要在Kadmin的服务器上运行上面的命令,并且,[email protected]是一个常规用户,如果你想添加一个管理员用户,你需要写成username/[email protected],/admin是你在kadm.acl里面定义的。有时候你需要增加的用户需要包含主机名,那么就写成username/[email protected],FQDN意思是完整的主机名,比如xianglei/[email protected].
我如何管理HDFS或YARN,我的意思是,我如何使用hdfs或者yarn用户来管理集群?
好吧,由于Cloudera Manager会自动创建诸如hdfs,yarn,hbase等用户,并且这些用户都是nologin且没有任何密码的,在kerberos里面也是用-randkey然后xst直接创建keytab的。同时这些用户都是Hadoop的管理用户所以你不能直接用以下命令来向KDC请求授权ticket。正常用户都是用kinit username,并且输入密码来验证授权的,但是hadoop的这些账户不可以。
# kinit hdfs kinit: Client not found in Kerberos database while getting initial credentials # kinit [email protected] kinit: Client not found in Kerberos database while getting initial credentials
但是你可以像这样使用keytab来请求ticket
kinit -kt hdfs.keytab hdfs/[email protected]
current_server是你当前登录的服务器的完整主机名,和你想访问或管理HDFS或YARN的用户名。
我使用计算Pi来进行冒烟测试,但是失败了,我已经在KDC数据库里新加了一个用户了?
17/04/24 11:18:35 INFO mapreduce.Job: Job job_1493003216756_0004 running in uber mode : false 17/04/24 11:18:35 INFO mapreduce.Job: map 0% reduce 0% 17/04/24 11:18:35 INFO mapreduce.Job: Job job_1493003216756_0004 failed with state FAILED due to: Application application_1493003216756_0004 failed 2 times due to AM Container for appattempt_1493003216756_0004_000002 exited with exitCode: -1000 For more detailed output, check application tracking page:http://pg-dmp-master1.hadoop:8088/proxy/application_1493003216756_0004/Then, click on links to logs of each attempt. Diagnostics: Application application_1493003216756_0004 initialization failed (exitCode=255) with output: main : command provided 0 main : run as user is dmp main : requested yarn user is dmp User dmp not found Failing this attempt. Failing the application. 17/04/24 11:18:35 INFO mapreduce.Job: Counters: 0 Job Finished in 1.094 seconds java.io.FileNotFoundException: File does not exist: hdfs://PG-dmp-HA/user/dmp/QuasiMonteCarlo_1493003913376_864529226/out/reduce-out at org.apache.hadoop.hdfs.DistributedFileSystem$20.doCall(DistributedFileSystem.java:1257) at org.apache.hadoop.hdfs.DistributedFileSystem$20.doCall(DistributedFileSystem.java:1249) at org.apache.hadoop.fs.FileSystemLinkResolver.resolve(FileSystemLinkResolver.java:81) at org.apache.hadoop.hdfs.DistributedFileSystem.getFileStatus(DistributedFileSystem.java:1249) at org.apache.hadoop.io.SequenceFile$Reader.(SequenceFile.java:1817) at org.apache.hadoop.io.SequenceFile$Reader. (SequenceFile.java:1841) at org.apache.hadoop.examples.QuasiMonteCarlo.estimatePi(QuasiMonteCarlo.java:314) at org.apache.hadoop.examples.QuasiMonteCarlo.run(QuasiMonteCarlo.java:354) at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70) at org.apache.hadoop.examples.QuasiMonteCarlo.main(QuasiMonteCarlo.java:363) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.hadoop.util.ProgramDriver$ProgramDescription.invoke(ProgramDriver.java:71) at org.apache.hadoop.util.ProgramDriver.run(ProgramDriver.java:144) at org.apache.hadoop.examples.ExampleDriver.main(ExampleDriver.java:74) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.hadoop.util.RunJar.run(RunJar.java:221) at org.apache.hadoop.util.RunJar.main(RunJar.java:136)
在一个非安全的集群里,Hadoop会把计算用的container分发到集群的所有节点上,并且用已经存在的账号或替代账号例如yarn或mapred用户来启动这些container。但是在一个安全集群里,container必须使用你提交的用户名来分发和启动,所以,这个错误是由于你仅仅添加了KDC里面的dmp用户这个pricipal,而没有在所有节点建立dmp账户。所以container的执行器无法启动AM或者Mapper或Reducer。所以很简单,你需要在所有节点运行以下命令。
useradd dmp
在集群的所有节点上增加linux用户账号有另外一个快捷的办法,那就是通过LDAP,这样可以替代大量的手工操作,当然,一些自动化运维工具也可以。
最后,我们来了解以下kerberos的基本理论
对于Kerberos来说,一个客户端要访问一个服务,需要经过以下三个步骤
– 验证
– 授权
– 服务请求
客户端先发送一个票证批准票Ticket-Granting Ticket (TGT)给AS服务,就是以后经常会在报错里看到的tgt
AS检查数据库来验证client
– 验证通常也可以通过LDAP或Actice Directory来做
– 如果合法, AS 会发还一个 Ticket/Granting Ticket (TGT) 给 client
client拿到这个TGT以后,会用这个TGT来向服务请求服务器申请一个服务ticket
– 一个服务ticket是用来验证client可以访问哪些服务的
TGS来验证client是否被允许使用它所请求的服务
– 如果访问被批准,TGS会发还给client一个服务票据
Client会用这些票据来访问需要的服务
– 服务会跟client验证这些服务票据的合法性
所以你知道为何起名叫Kerberos了吧,三首地狱看门狗。三方验证授权,互不干涉,三权分立。
kinit 程序是用来想Kerberos申请ticket的
klist 用来查看当前的用户
kdestroy 用来删除你当前使用的票据
( 图片与说明来源于Cloudera管理员认证培训课程,版权属于Cloudera。)