参考上面两篇基本配置,添加了部分配置
本文主要记录 CDH 集群上集成 Kerberos 的过程,包括 Kerberos 的安装和 CDH 相关配置修改说明。
一、安装Kerberos
1. 整体说明
- 软件版本
操作系统:CentOs 6.8
CDH版本:Hadoop 2.6.0-cdh5.9.0
JDK版本:jdk1.7.0_67-cloudera
运行用户:root - 集群主机角色划分
sunmvm20 作为master节点,安装kerberos Server
其他节点作为slave节点,安装kerberos client
2. 配置host
添加主机名到 /etc/hosts 文件中。
$ cat /etc/hosts
127.0.0.1 localhost
192.168.1.20 sunmvm20
192.168.1.26 sunmvm26
192.168.1.27 sunmvm27
192.168.1.28 sunmvm28
注意:hostname 请使用小写,要不然在集成 kerberos 时会出现一些错误。
3. 安装 Kerberos
在 sunmvm20 上安装 krb5、krb5-server 和 krb5-client。
yum install krb5-server -y
# klist等命令找不大时执行下面安装
yum install -y krb5-server krb5-workstation pam_krb5
在其他节点安装 krb5-devel、krb5-workstation
$ ssh sunmvm26 "yum install krb5-devel krb5-workstation -y"
$ ssh sunmvm27 "yum install krb5-devel krb5-workstation -y"
$ ssh sunmvm28 "yum install krb5-devel krb5-workstation -y"
4. 修改配置文件
kdc 服务涉及到三个配置文件:
- /etc/krb5.conf
- /var/kerberos/krb5kdc/kdc.conf
- /var/kerberos/krb5kdc/kadm5.acl
1)编辑配置文件 /etc/krb5.conf。默认安装的文件中包含多个示例项。
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = 0HKJ.COM
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
default_tgs_enctypes = aes256-cts-hmac-sha1-96
default_tkt_enctypes = aes256-cts-hmac-sha1-96
permitted_enctypes = aes256-cts-hmac-sha1-96
clockskew = 120
udp_preference_limit = 1
[realms]
0HKJ.COM = {
kdc = sunmvm20
admin_server = sunmvm20
}
[domain_realm]
.0hkj.com = 0HKJ.COM
ohkj.com = 0HKJ.COM
说明:
- [logging]:表示 server 端的日志的打印位置
- [libdefaults]:每种连接的默认配置,需要注意以下几个关键的小配置
- default_realm = 0HKJ.COM:设置 Kerberos 应用程序的默认领域。如果您有多个领域,只需向 [realms] 节添加其他的语句。
- ticket_lifetime: 表明凭证生效的时限,一般为24小时。
- renew_lifetime: 表明凭证最长可以被延期的时限,一般为一个礼拜。当凭证过期之后,对安全认证的服务的后续访问则会失败。
- clockskew:时钟偏差是不完全符合主机系统时钟的票据时戳的容差,超过此容差将不接受此票据。通常,将时钟扭斜设置为 300 秒(5 分钟)。这意味着从服务器的角度看,票证的时间戳与它的偏差可以是在前后 5 分钟内。
- udp_preference_limit= 1:禁止使用 udp 可以防止一个 Hadoop 中的错误
- [realms]:列举使用的 realm。
- kdc:代表要 kdc 的位置。格式是 机器:端口
- admin_server:代表 admin 的位置。格式是 机器:端口
- default_domain:代表默认的域名
- [appdefaults]:可以设定一些针对特定应用的配置,覆盖默认配置。
2)修改 /var/kerberos/krb5kdc/kdc.conf ,该文件包含 Kerberos 的配置信息。例如,KDC 的位置,Kerbero 的 admin 的realms 等。需要所有使用的 Kerberos 的机器上的配置文件都同步。这里仅列举需要的基本配置。详细介绍参考:krb5conf
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
[realms]
0HKJ.COM = {
#master_key_type = aes256-cts acl_file = /var/kerberos/krb5kdc/kadm5.acl
dict_file = /usr/share/dict/words
max_renewable_life = 7d
max_life = 1d
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
default_principal_flags = +renewable, +forwardable
}
说明:
- 0HKJ.COM: 是设定的 realms。名字随意。Kerberos 可以支持多个 realms,会增加复杂度。大小写敏感,一般为了识别使用全部大写。这个 realms 跟机器的 host 没有大关系。
- master_key_type:和 supported_enctypes 默认使用 aes256-cts。JAVA 使用 aes256-cts 验证方式需要安装 JCE 包,见下面的说明。为了简便,你可以不使用 aes256-cts 算法,这样就不需要安装 JCE 。
- acl_file:标注了 admin 的用户权限,需要用户自己创建。文件格式是:Kerberos_principal permissions [target_principal] [restrictions]
- supported_enctypes:支持的校验方式。
- admin_keytab:KDC 进行校验的 keytab。
关于AES-256加密:
对于使用 centos5. 6 及以上的系统,默认使用 AES-256 来加密的。这就需要集群中的所有节点上安装 JCE,如果你使用的是 JDK1.6 ,则到Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 6 页面下载,如果是 JDK1.7,则到 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 7 下载。下载的文件是一个 zip 包,解开后,将里面的两个文件放到下面的目录中:$JAVA_HOME/jre/lib/security.
上面这一步一定要做,否则会报zk,namenode等不支持默认tkt的加密方式错误。
3)为了能够不直接访问 KDC 控制台而从 Kerberos 数据库添加和删除主体,请对 Kerberos 管理服务器指示允许哪些主体执行哪些操作。通过创建 /var/lib/kerberos/krb5kdc/kadm5.acl 完成此操作。
$ cat /var/kerberos/krb5kdc/kadm5.acl
内容如下:
*/admin@0HKJ.COM *
表示principal的名字的第二部分如果是admin,那么该principal就拥有管理员权限
5. 同步配置文件
将 kdc 中的 /etc/krb5.conf 拷贝到集群中其他服务器即可。
$ scp /etc/krb5.conf sunmvm26:/etc/krb5.conf
$ scp /etc/krb5.conf sunmvm27:/etc/krb5.conf
$ scp /etc/krb5.conf sunmvm28:/etc/krb5.conf
6. 创建数据库
在 sunmvm20 上运行初始化数据库命令。其中 -r 指定对应 realm。
$ kdb5_util create -r 0HKJ.COM -s
出现 Loading random data 的时候另开个终端执行点消耗CPU的命令如 cat /dev/sda > /dev/urandom 可以加快随机数采集。该命令会在 /var/kerberos/krb5kdc/ 目录下创建 principal 数据库。
如果遇到数据库已经存在的提示,可以把 /var/kerberos/krb5kdc/ 目录下的 principal 的相关文件都删除掉。默认的数据库名字都是 principal。可以使用 -d指定数据库名字。
7. 启动Kerberos服务
在 sunmvm20 节点上运行:
$ chkconfig --level 35 krb5kdc on
$ chkconfig --level 35 kadmin on
$ service krb5kdc start
$ service kadmin start
8. 创建 kerberos 管理员
关于 kerberos 的管理,可以使用 kadmin.local 或 kadmin,至于使用哪个,取决于账户和访问权限:
- 如果有访问 kdc 服务器的 root 权限,但是没有 kerberos admin 账户,使用 kadmin.local
- 如果没有访问 kdc 服务器的 root 权限,但是用 kerberos admin 账户,使用 kadmin
在 sunmvm20 上创建远程管理的管理员: - 手动输入两次密码
$ kadmin.local -q "addprinc root/admin"
- 也可以不用手动输入密码
$ echo -e "root\nroot" | kadmin.local -q "addprinc root/admin"
抽取密钥并将其储存在本地 keytab 文件 /etc/krb5.keytab 中。这个文件由超级用户拥有,所以必须是 root 用户才能在 kadmin shell 中执行以下命令:
kadmin.local -q "ktadd kadmin/admin"
# 查看生成的keytab
klist -k /etc/krb5.keytab
9. 测试 kerberos
# 列出Kerberos中的所有认证用户,即principals
kadmin.local -q "list_principals"
# 添加认证用户,需要输入密码
kadmin.local -q "addprinc user1"
# 使用该用户登录,获取身份认证,需要输入密码
kinit user1
# 查看当前用户的认证信息ticket
klist
# 更新ticket
kinit -R
# 销毁当前的ticket
kdestroy
# 删除认证用户
kadmin.local -q "delprinc user1"
二、CDH启用Kerberos
CM中的操作
在CM的界面上点击启用Kerberos,启用的时候需要确认几个事情:
1.KDC已经安装好并且正在运行
2.将KDC配置为允许renewable tickets with non-zerolifetime(在之前修改kdc.conf文件的时候已经添加了kdc_tcp_ports、max_life和max_renewable_life这个三个选项)
3.在Cloudera Manager Server上安装openldap-clients
4.为Cloudera Manager创建一个principal,使其能够有权限在KDC中创建其他的principals,就是上面创建的Kerberos管理员账号
上述确认完了之后点击continue,进入下一页进行配置,要注意的是:这里的『Kerberos Encryption Types』必须跟KDC实际支持的加密类型匹配即 /etc/krb5.conf 中的default_tgs_enctypes、default_tkt_enctypes和permitted_enctypes三个选项的值对应起来,不然会出现集群服务无法认证通过的情况。
填 aes256-cts
点击continue,进入下一页,这一页中可以不勾选『Manage krb5.conf through Cloudera Manager』注意,如果勾选了这个选项就可以通过CM的管理界面来部署krb5.conf,但是实际操作过程中发现有些配置仍然需要手动修改该文件并同步。
点击continue,进入下一页,输入Cloudera Manager Principal的管理员账号和密码,注意输入账号的时候要使用@前要使用全称,root/admin。
点击continue,进入下一页,导入KDC Account Manager Credentials。
点击continue,进入下一页,restart cluster并且enable Kerberos。
之后CM会自动重启集群服务,启动之后会会提示Kerberos已启用。
在CM上启用Kerberos的过程中,CM会自动做以下的事情:
1.集群中有多少个节点,每个账户都会生成对应个数的principal,格式为username/hostname@OHKJ.COM,例如hdfs/hadoop-10-0-8-124@OHKJ.COM。使用如下命令来查看:
kadmin.local -q "list_principals"
2.为每个对应的principal创建keytab
3.部署keytab文件到指定的节点中
keytab是包含principals和加密principal key的文件,keytab文件对于每个host是唯一的,因为key中包含hostname,keytab文件用于不需要人工交互和保存纯文本密码,实现到kerberos上验证一个主机上的principal。启用之后访问集群的所有资源都需要使用相应的账号来访问,否则会无法通过Kerberos的authenticatin
4.在每个服务的配置文件中加入有关Kerberos的配置,其中包括Zookeeper服务所需要的jaas.conf和keytab文件都会自动设定并读取,如果用户仍然手动修改了Zookeeper的服务,要确保这两个文件的路径和内容正确性。
创建HDFS超级用户
此时直接用CM生成的principal访问HDFS会失败,因为那些自动生成的principal的密码是随机的,用户并不知道,而通过命令行的方式访问HDFS需要先使用kinit来登录并获得ticket,所以使用kinit hdfs/hadoop-10-0-8-124@XIAOHEI.INFO需要输入密码的时候无法继续。用户可以通过创建一个hdfs@0HKJ.COM的principal并记住密码从命令行中访问HDFS。登录之后就可以通过认证并访问HDFS,默认hdfs用户是超级用户。
kadmin.local -q "addprinc hdfs"
kinit hdfs@0HKJ.COM
为每个用户创建principal
当集群运行Kerberos后,每一个Hadoop user都必须有一个principal或者keytab来获取Kerberos credentials(即使用密码的方式或者使用keytab验证的方式)这样才能访问集群并使用Hadoop的服务。也就是说,如果Hadoop集群存在一个名为hdfs@0HKJ.COM的principal那么在集群的每一个节点上应该存在一个名为hdfs的Linux用户。同时,在HDFS中的目录/user要存在相应的用户目录(即/user/hdfs),且该目录的owner和group都要是hdfs
一般来说,Hadoop user会对应集群中的每个服务,即一个服务对应一个user。例如impala服务对应用户impala。
至此,集群上的服务都启用了Kerberos的安全认证
三、验证Kerberos在集群上是否正常工作
1.确认HDFS可以正常使用
登录到某一个节点后,切换到hdfs用户,然后用kinit来获取credentials
现在用hadoop hdfs -ls /
应该能正常输出结果
用kdestroy销毁credentials后,再使用hadoop hdfs -ls /
会发现报错
2.确认可以正常提交MapReduce job
获取了hdfs的证书后,提交一个PI程序,如果能正常提交并成功运行,则说明Kerberized Hadoop cluster在正常工作
hadoop jar /opt/cloudera/parcels/CDH-5.9.0-1.cdh5.9.0.p0.23/lib/hadoop-mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.9.0.jar pi 2 2
四、集群集成Kerberos过程中遇到的坑
hdfs用户提交mr作业无法运行
INFO mapreduce.Job: Job job_1442654915965_0002 failed with state FAILED due to: Application application_1442654915965_0002 failed 2 times due to AM Container for appattempt_1442654915965_0002_000002 exited with exitCode: -1000 due to: Application application_1442654915965_0002 initialization failed (exitCode=255) with output: Requested user hdfs is not whitelisted and has id 496,which is below the minimum allowed 1000
原因:
Linux user 的 user id 要大于等于1000,否则会无法提交Job。例如,如果以hdfs(id为490)的身份提交一个job,就会看到以上的错误信息
解决方法:
1.使用命令 usermod -u 修改一个用户的user id
2.修改Clouder关于这个该项的设置,Yarn->配置->min.user.id修改为合适的值,当前为0
提交mr作业时可以运行但是有错误信息
INFO mapreduce.Job: Job job_1442722429197_0001 failed with state FAILED due to: Application application_1442722429197_0001 failed 2 times due to AM Container for appattempt_1442722429197_0001_000002 exited with exitCode: -1000 due to: Application application_1442722429197_0001 initialization failed (exitCode=255) with output: Requested user hdfs is banned
原因:
hdfs用户被禁止运行 YARN container,yarn的设置中将hdfs用户禁用了
解决方法:
修改Clouder关于这个该项的设置,Yarn->配置->banned.users 将hdfs用户移除
YARN job运行时无法创建缓存目录
异常信息:
main : user is hdfs
main : requested yarn user is hdfs
Can’t create directory /data/data/yarn/nm/usercache/hdfs/appcache/application_1442724165689_0005 - Permission denied
原因:
该缓存目录在集群进入Kerberos状态前就已经存在了。例如当我们还没为集群Kerberos支持的时候,就用该用户跑过YARN应用
解决方法:
在每一个NodeManager节点上删除该用户的缓存目录,对于用户hdfs,是/data/data/yarn/nm/usercache/hdfs