一.安装Ambari2.5.0与HDP2.6.0集群
二.HDP与Kerberos集成
环境:
三台Ali云服务器 hdp-1,hdp-2,hdp-3
centos7
HDP2.6.0
kerberos 1.15.1-8
Hadoop与kerberos集成的一般步骤(此处只列出主要步骤,安装细节及完整步骤后期整理,需要设计):
1. 选择一个节点作为KDC,安装并修改配置
yum install krb5-server krb5-libs krb5-workstation
修改三个配置文件
- vi /etc/krb5.conf
修改[realms]里的kdc和admin_server所在主机
[libdefaults]
renew_lifetime = 7d
forwardable = true
default_realm = HADOOP.COM
ticket_lifetime = 24h
dns_lookup_realm = false
dns_lookup_kdc = false
default_ccache_name = /tmp/krb5cc_%{uid}
#default_tgs_enctypes = aes des3-cbc-sha1 rc4 des-cbc-md5
#default_tkt_enctypes = aes des3-cbc-sha1 rc4 des-cbc-md5
[logging]
default = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
kdc = FILE:/var/log/krb5kdc.log
[realms]
HADOOP.COM = {
admin_server = hdp-3.wanwan.com
kdc = hdp-3.wanwan.com
}
- vi /var/kerberos/krb5kdc/kdc.conf
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
[realms]
HADOOP.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 camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal
}
- vi /var/kerberos/krb5kdc/kadm5.acl
*/admin@HADOOP.COM *
复制 krb5.conf 到每个节点,如果是ambari,则只拷给ambari server所在机器就可以,其它节点后面会自动分发
2. 创建principal数据库
/usr/sbin/kdb5_util create -s -r DEWAVE
出现 Loading random data 的时候另开个终端执行点消耗CPU的命令如 cat /dev/sda > /dev/urandom 可以加快随机数采集。
3. Start the KDC server and the KDC admin server并设置开机启动
service krb5kdc start
service kadmin start
chkconfig krb5kdc on
chkconfig kadmin on
4.创建kerberos管理员
kadmin.local
addprinc admin/admin@HADOOP.COM
关于 kerberos 的管理,可以使用 kadmin.local 或 kadmin,至于使用哪个,取决于 账户和访问权限:
- 如果有访问 kdc 服务器的 root 权限,但是没有 kerberos admin 账户,使 用 kadmin.local
- 如果没有访问 kdc 服务器的 root 权限,但是有 kerberos admin 账户,使 用 kadmin
按照提示输入密码
listprincs <!--查看创建的principle-->
5.重启kadmin
service kadmin restart
6.下载JCE
For Oracle JDK 1.8:
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
For Oracle JDK 1.7:
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
下载JCE
补充1:
JCE(Java Cryptography Extension)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。
它提供对对称、不对称、块和流密码的加密支持,它还支持安全流和密封的对象。它不对外出口,用它开发完成封装后将无法调用。
补充2:
If you are using Oracle JDK, you must distribute and install the JCE on all hosts in the cluster, including the Ambari Server.
Be sure to restart Ambari Server after installng the JCE. If you are using OpenJDK, some distributions of the OpenJDK
come with unlimited strength JCE automatically and therefore, installation of JCE is not required.
将下载的JCE解压并覆盖$JAVA_HOME/jre/lib/security/目录下的文件(所有节点)
[root@hdp-3 security]# ll
总用量 188
-rw-r--r-- 1 root root 4054 4月 24 14:44 blacklist
-rw-r--r-- 1 root root 1273 4月 24 14:44 blacklisted.certs
-rw-r--r-- 1 root root 114757 4月 24 14:44 cacerts
-rw-r--r-- 1 root root 2466 4月 24 14:44 java.policy
-rw-r--r-- 1 root root 41530 4月 24 14:44 java.security
-rw-r--r-- 1 root root 98 4月 24 14:44 javaws.policy
-rw-r--r-- 1 root root 3035 4月 24 22:17 local_policy.jar
drwxr-xr-x 4 root root 4096 4月 24 14:44 policy
-rw-r--r-- 1 root root 0 4月 24 14:44 trusted.libraries
-rw-r--r-- 1 root root 3023 4月 24 22:17 US_export_policy.jar
在hdp中,安装时只需要安装进行到此即可,其余工作:创建client,principle,keytab由ambari来完成
7. 安装客户端
在其余节点以root用户安装
yum install krb5-devel krb5-workstation -y
使用 yum 安装可能会报错,提示无法安装。这是由于生产中的集群有可能没有配
置可以访问外网。这时候可以通过 rpm 包的方式离线安装,或者重新配置 yum 源在线安装。
8.创建principal和keytab
举例:为用户user1创建pricipal
kadmin.local -q 'addprinc -pw user1 user1@HADOOP.COM'
举例:为用户user1创建keytab
kadmin.local -q "xst -k /etc/securitykeytabs/user1.keytab user1@HADOOP.COM"
需要注意的点
- 安装 hadoop 集群的用户要具有 root 权限或者 sudo 权限。
- Hadoop 集群要配置和运行在非安全模式。
- 对本地目录和 hadoop系统目录设置合适的文件权限。
- Kerberos 是时间敏感的,所以需要所有机器进行时间同步,最多允许 5 分钟的 延迟。有的服务器延迟超过 5 分钟,它将无法通过认证。
- 集群中所有机器支持 DNS 解析和主机映射。Kerberos 不支持 IP 地址。所有节点需要 支持反向 DNS 解析,返回正确的主机名。
- Kerberos 需要开通端口 88 设置 KDC,开通端口 749 启动管理服务。因为所有的节点 都需要连接 KDC 进行认证,因此所有运行 hadoop 守护进程的节点都需要开通 88 端 口。
- Kerberos 的领域名称将用于认证 hadoop 集群。
- 一定要确保集群中关闭了 selinex
kerberos的认证过程:
1、当用户在一个kerberos-aware网络中登录到他的workstation之后,authentication server将向KDC发送一个TGT请求(a request for a ticket-granting ticket),而他的principal将作为其中的组成部分。该请求可以由登录程序来负责发送(这样该过程对用户透明),也可以在用户登录后通过执行kinit来发送。
2、KDC在其数据库中检查该pricipal。
3、如果找到了该principal,则KDC将创建一个TGT,并用user key进行加密,然后将加密后的TGT发送给该用户。这里,user key并不是用户的密码,而是由用户密码计算而来(例如hash)。
4、用户所在主机的Kerberos client的登录程序或者kinit程序在收到加密的TGT后,用该用户的user key进行解密。user key只会在client主机上被使用,绝不会在网络上传输。KDC发送的ticket将被保存在一个本地文件中(credentials cache),它可以被kerberized services查验。
5、用户的身份验证完成后,servers(运行着kerberized applciations & services)可以查验被识别的principals及其keys(这将被保存在keytab中),而不必用kinit来查验。
一些常用命令:
kadmin.local:
<!--添加principle-->
addprinc
<!--列出principle-->
listprincs
<!--删除principle-->
delprinc
<!--退出kadmin.local-->
exit/quit
---
<!--列出ticket-->
klist
<!--销毁ticket-->
kdestroy
<!--查看keytab-->
klist -ket *.keytab
<!--获取ticket-->
kinit -kt {*.keytab} {对应的principle}
一.hdfs认证
vi core-site.xml
<property>
<name>hadoop.security.authentication</name>
<value>kerberos</value>
</property>
<property>
<name>hadoop.security.authorization</name>
<value>true</value>
</property>
vi hdfs-site.xml
<property>
<name>dfs.block.access.token.enable</name>
<value>true</value>
</property>
<property>
<name>dfs.https.enable</name>
<value>true</value>
</property>
<property>
<name>dfs.https.policy</name>
<value>HTTPS_ONLY</value>
</property>
<property>
<name>dfs.namenode.https-address.pin-cluster1.testnn1</name>
<value>hdp-1:50470</value>
</property>
<property>
<name>dfs.namenode.https-address.pin-cluster1.testnn2</name>
<value>hdp-2:50470</value>
</property>
<property>
<name>dfs.https.port</name>
<value>50470</value>
</property>
<property>
<name>dfs.namenode.keytab.file</name>
<value>/usr/local/hadoop/etc/hadoop/hdfs.keytab</value>
</property>
<property>
<name>dfs.namenode.kerberos.principal</name>
<value>hadoop/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.namenode.kerberos.internal.spnego.principal</name>
<value>HTTP/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.datanode.data.dir.perm</name>
<value>700</value>
</property>
<property>
<name>dfs.datanode.address</name>
<value>0.0.0.0:1004</value>
</property>
<property>
<name>dfs.datanode.http.address</name>
<value>0.0.0.0:1006</value>
</property>
<property>
<name>dfs.datanode.keytab.file</name>
<value>/usr/local/hadoop/etc/hadoop/hdfs.keytab</value>
</property>
<property>
<name>dfs.datanode.kerberos.principal</name>
<value>hadoop/_HOST@HADOOP.COM</value>
</property>
<property>
<property>
<name>dfs.journalnode.keytab.file</name>
<value>/usr/local/hadoop/etc/hadoop/hdfs.keytab</value>
</property>
<property>
<name>dfs.journalnode.kerberos.principal</name>
<value>hadoop/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.journalnode.kerberos.internal.spnego.principal</name>
<value>HTTP/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.web.authentication.kerberos.principal</name>
<value>HTTP/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.web.authentication.kerberos.keytab</name>
<value>/usr/local/hadoop/etc/hadoop/hdfs.keytab</value>
</property>
需要注意的点:
- dfs.datanode.address表示 data transceiver RPC server 所绑定的 hostname 或 IP 地址,如果开启 security,端口号必须小于 1024(privil eged port),否则的话启动 datanode 时候会报 Cannot start secure cluster without privileged resources 错误
- principal 中的 instance 部分可以使用 _HOST 标记,系统会自动替换它为全称域名
- 如果开启了 security, hadoop 会对 hdfs block data(由 dfs.data.dir 指定)做 permission check,方式用户的代码不是调用hdfs api而是直 接本地读block data,这样就绕过了kerberos和文件权限验证,管理员可以通过设置 dfs.datanode.data.dir.perm 来修改 datanode 文件权 限,这里我们设置为700
- datanode启动要用root用户启动,且需要安装jsvcdfs.datanode.address
vi yarn-site.xml
<property>
<name>yarn.resourcemanager.keytab</name>
<value>/usr/local/hadoop/etc/hadoop/hdfs.keytab</value>
</property>
<property>
<name>yarn.resourcemanager.principal</name>
<value>hadoop/_HOST@HADOOP.COM</value>
</property>
<property>
<name>yarn.nodemanager.keytab</name>
<value>/usr/local/hadoop/etc/hadoop/hdfs.keytab</value>
</property>
<property>
<name>yarn.nodemanager.principal</name>
<value>hadoop/_HOST@HADOOP.COM</value>
</property>
<property>
<name>yarn.nodemanager.container-executor.class</name>
<value>org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor</value>
</property>
<property>
<name>yarn.nodemanager.linux-container-executor.group</name>
<value>hadoop</value>
</property>
<property>
<name>yarn.https.policy</name>
<value>HTTPS_ONLY</value>
</property>
vi mapred-site.xml
<property>
<name>mapreduce.jobhistory.keytab</name>
<value>/usr/local/hadoop/etc/hadoop/hdfs.keytab</value>
</property>
<property>
<name>mapreduce.jobhistory.principal</name>
<value>hadoop/_HOST@HADOOP.COM</value>
</property>
<property>
<name>mapreduce.jobhistory.http.policy</name>
<value>HTTPS_ONLY</value>
</property>
在 kerberos环境下,使用Java API操作hdfs时,要确保两个条件,1.确保票据缓存在有效期内,2.登录时有有效的princple和keytab,以下为关键代码
public class UserLogginUtil {
private static final int MAX_RETRY_NUMS =3;
/**
* 以指定的"keytab"和"principal" 登录
* @param principal principal
* @param keytab keytab
* @return Conifiguration
*/
public static Configuration init(String principal, String keytab) {
Preconditions.checkState(StringUtils.isNotBlank(principal),"must specify the principal");
Preconditions.checkState(StringUtils.isNotBlank(keytab),"must specify the keytab");
Configuration conf = new org.apache.hadoop.conf.Configuration();
conf.set("hadoop.security.authentication", "Kerberos");
UserGroupInformation.setConfiguration(conf);
int retryNums = 0;
do{
try {
UserGroupInformation.loginUserFromKeytab(principal,keytab);
break;
} catch (IOException e) {
++retryNums;
if(retryNums >= MAX_RETRY_NUMS){
throw new RuntimeException(String.format("failed to loggin in the given principal-%s," +
"keytab-%s, has retried 3 times,caused by %s",
principal,keytab,ExceptionUtils.getStackTrace(e)));
}else{
try{
if (UserGroupInformation.isLoginKeytabBased()) {
UserGroupInformation.getLoginUser().reloginFromKeytab();
} else {
UserGroupInformation.getLoginUser().reloginFromTicketCache();
}
}catch (Exception ex){
// 重试过程中,不再捕获异常
}
}
}
}while (true);
return conf;
}
}
提示:在集群执行文件操作命令,如:hadoop fs -ls / 报以下错误时:
18/05/03 09:51:05 WARN ipc.Client: Exception encountered while connecting to the server : javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
ls: Failed on local exception: java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]; Host Details : local host is: "hdp-1.wanwan.com/172.26.84.70"; destination host is: "hdp-3.wanwan.com":8020;
一般为ticket失效,重新获取一下即可。
二. spark集成
针对spark-submit的任务,有两种办法通过kerberos认证:
1.先kinit -k -t /etc/security/xx.keytab user/host@REALM.COM,然后spark-submit提交即可
2.作为参数提供给spark-submit:--keytab /etc/security/spark.headless.keytab --principal /spark-hdp_wanwan@HADOOP.COM
,注意紧跟着命令spark-submit,不要放到最后(会被当做spark JOB的参数)
即启动之前需要设置kinit或者指定keytab由spark-submit自己loginfromkeytab。
三.HIVE认证
vi hive-site.xml
<property>
<name>hive.server2.enable.doAs</name>
<value>false</value>
</property>
<property>
<name>hive.server2.authentication</name>
<value>KERBEROS</value>
</property>
<property>
<name>hive.server2.authentication.kerberos.principal</name>
<value>dtdream/_HOST@HADOOP.COM</value>
</property>
<property>
<name>hive.server2.authentication.kerberos.keytab</name>
<value>/etc/security/hive.service.keytab</value>
</property>
认证方式:
1.beeline
举例
beeline -u "jdbc:hive2://47.92.156.1:10000/default;principal=hive/hdp-2.wanwan.com@HADOOP.COM" -e "select * from wanwan_test.student_info where age =22 LIMIT 10" --hiveconf mapreduce.job.queuename=default --hiveconf hadoop.security.authentication=kerberos --hiveconf hive.server2.authentication.kerberos.principal=hive/hdp-2.wanwan.com@HADOOP.COM --hiveconf hive.server2.authentication.kerberos.keytab=/etc/security/keytabs/hive.llap.zk.sm.keytab
jdbc连接
此处的principal为安装metastore的节点上的pricipal
jdbc:hive2://hdp-2.wanwan.com:10000/default;principal=hive/hdp-2.wanwan.com@HADOOP.COM
后序:kerberos原理很复杂,笔者到现在也只是略知皮毛一二,还有很多疑问没有解决。上述文档并非完整,还待后续更新。