1、KDC创建principal
1.1、创建认证用户
登陆到kdc服务器,使用root或者可以使用root权限的普通用户操作:
# kadmin.local -q “addprinc -randkey hbase/yjt”
# kadmin.local -q “addprinc -randkey zookeeper/yjt”
# kadmin.local -q “addprinc -randkey zkcli/yjt”
其中hbase集群有几台,上面的第一台命令就需要执行几次,每次执行的时候请把yjt修改成你机器对应的主机名
同理,zookeeper也是一样
1.2、生成密钥文件
生成hbase密钥文件
# kadmin.local -q “xst -norankey -k /etc/hbase.keytab hbase/yjt”
生成zookeeper密钥文件
# kadmin.local -q “xst -norankey -k /etc/zk.keytab zookeeper/yjt zkcli/yjt”
拷贝hbase.keytab到所有的hbase集群节点的conf目录下
拷贝zk.keytab到所有zookeeper集群节点的conf目录下
2、zookeeper操作
2.1、创建jaas.conf文件
在zookeeper的conf目录下创建或者修改jaas.conf,没有就创建,配置信息如下:
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/data1/hadoop/zookeeper/conf/zk.keytab"
storeKey=true
useTicketCache=false
principal="zookeeper/yjt@HADOOP.COM"; #这里注意,如果是多个zookeeper,那么这个principal里面的域名改成对应的主机名,同时在这个server里面,principal必须以zookeeper开头,也就是principal='zookeeper/hostname@xxx.COM',否则会报服务不能找到错误。
};
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/data1/hadoop/zookeeper/conf/zk.keytab"
storeKey=true
useTicketCache=false
principal="zkcli/yjt@HADOOP.COM";
};
2.2、创建java.env文件
在zookeeper的conf目录下创建或者修改java.env文件,配置信息如下:
export JVMFLAGS="-Djava.security.auth.login.config=/data1/hadoop/zookeeper/conf/jaas.conf"
2.3、修改zoo.cfg文件
添加如下属性:
kerberos.removeHostFromPrincipal=true kerberos.removeRealmFromPrincipal=true authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider jaasLoginRenew=3600000
2.4、测试zookeeper kerberos
首先启动zookeeper集群,然后使用zkcli -server IP:端口(注意,一定要以这种方式)测试
如下:zkCli.sh -server yjt:2181
在输出的信息中,最下面如果能找到类似下面这样的信息,就代表配置成功:
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
WATCHER::
WatchedEvent state:SaslAuthenticated type:None path:null
在使用zkCli.sh连接zookeeper的时候,这里贴一下错误信息:
WatchedEvent state:SyncConnected type:None path:null 2019-11-20 12:49:55,971 [myid:] - ERROR [main-SendThread(rslog084:2181):ZooKeeperSaslClient@308] - An error: (java.security.PrivilegedActionException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7) - LOOKING_UP_SERVER)]) occurred when evaluating Zookeeper Quorum Member's received SASL token. Zookeeper Client will go to AUTH_FAILED state. 2019-11-20 12:49:55,971 [myid:] - ERROR [main-SendThread(rslog084:2181):ClientCnxn$SendThread@1076] - SASL authentication with Zookeeper Quorum member failed: javax.security.sasl.SaslException: An error: (java.security.PrivilegedActionException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7) - LOOKING_UP_SERVER)]) occurred when evaluating Zookeeper Quorum Member's received SASL token. Zookeeper Client will go to AUTH_FAILED state.
造成上述原因是由于服务端principal主体错误,可能错误的原因如下:
1、在jaas.conf文件中,principal主体错误,正确的主体名称格式: zookeeper/<hostname>@<realm>
2、当采用zkCli.sh 的方式请求中,默认的host应该是localhost,因此在kdc中才会发现客户端的请求和 zookeeper/localhost@NETEASE.COM 这个principal进行认证,但是在kerberos的database中却没有这个principal。
解决方法: 使用zkCli.sh -server host:port 访问。 同时zookeeper配置文件中sever部分的principal必须为zookeeper/<hostname>@<your realm>
3、hbase配置
3.1、配置hbase-site.xml
添加如下配置:
<property>
<name>hbase.security.authorization</name>
<value>true</value>
</property>
<property>
<name>hbase.security.authentication</name>
<value>kerberos</value>
</property>
<property>
<name>hbase.rpc.engine</name>
<value>org.apache.hadoop.hbase.ipc.SecureRpcEngine</value>
</property>
<property>
<name>hbase.regionserver.kerberos.principal</name>
<value>hbase/_HOST@HADOOP.COM</value>
</property>
<property>
<name>hbase.regionserver.keytab.file</name>
<value>/data1/hadoop/hbase/conf/hbase.keytab</value>
</property>
<property>
<name>hbase.master.kerberos.principal</name>
<value>hbase/_HOST@HADOOP.COM</value>
</property>
<property>
<name>hbase.master.keytab.file</name>
<value>/data1/hadoop/hbase/conf/hbase.keytab</value>
</property>
3.2、启动hbase
# start-hbase.sh
进去到hbase的客户端
# hbase shell
查看当前存在的表
hbase(main):001:0> list
TABLE
0 row(s) in 0.3550 seconds
=> []
如果上述的输出没有报错,说明配置成功
注:hadoop版本在2.6以上数据传输才能使用sasl方式,而hbase又得版本集成Hadoop的版本低于2.6,会导致hbase失败,我在使用hadoop2.9.2,hbase1.3.1测试的时候,就报如下错误:
2019-10-24 15:04:12,325 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Failed to read expected SASL data transfer protection handshake from client at /192.168.0.230:48326. Perhaps the client is running an older version of Hadoop which does not support SASL data transfer protection
2019-10-24 15:05:02,352 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Failed to read expected SASL data transfer protection handshake from client at /192.168.0.230:48346. Perhaps the client is running an older version of Hadoop which does not support SASL data transfer protection
2019-10-24 15:05:12,418 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Failed to read expected SASL data transfer protection handshake from client at /192.168.0.230:48352. Perhaps the client is running an older version of Hadoop which does not support SASL data transfer protection
2019-10-24 15:05:22,461 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Failed to read expected SASL data transfer protection handshake from client at /192.168.0.230:48356. Perhaps the client is running an older version of Hadoop which does not support SASL data t
解决办法:
(1) 、使用高版本的hbase
(2) 、把高版本的hbase下面的lib库里面的文件拷贝到低版本的hbase lib库里面,当然,先要删除低版本hbase lib库里面的关于hadoop相关的软件报。
3.2、测试
(1)、在集群内部进入到shell,输入命令为 hbase shell
创建表:
# create ‘test’, ‘c1’
如果能成功创建说明没问题
(2)、咋集群内部使用phoenix连接测试
在使用Kerberos以后,phoenix连接hbase的方式有两种:
第一种:查看当前是否存在票据
出现上面的信息,说明是存在票据的,所以,这个时候可以使用:
jdbc:phoenix:<quorom>:<port> 方式连接
如下:
# ./sqlline.py yjt:2181 其实就跟原先的连接方法一样。
第二种:不存在票据
jdbc:phoenix:<quorom>:<port>:[zk_rootNode]:<principal>:<keytab>
# ./sqlline.py yjt:2181:hbase/yjt:/data1/hadoop/hbase/conf/hbase.keytab
如果出现上述,说明成功。
在测试的时候,由于配置不当,导致在集群内部测试时失败,错误日志如下:
解决办法:这是由于配置完hbase Kerberos以后,没有把hbase-iste.xml拷贝到phoenix的bin目录下覆盖原来的配置文件,导致失败。
(3) 、hbase客户端测试
- 从集群拷贝hbase的目录到客户端,注意:hbase的根目录最好一致,这样就不用修改hbase-site.xml文件里面的密钥路径了。如下:
Hbase集群(随便选一台)上面操作,操作用户为hduser,下面的192.168.0.9为集群的客户端:
# scp -r /data1/hadoop/hbase 192.168.0.9:/data1/hadoop
- 拷贝zookeeper密钥
Hbase依赖与zookeeper连接,所以,需要把zookeeper的密钥文件从zookeeper集群拷贝到客户端(当然,可以拷贝整个目录到客户端,这样还可以测试zookeeper的客户端是否可以正常使用,当hbase错问题的时候,可以排查是否是zookeeper导致的),zookeeper的密钥存放与客户端的/data1/hadoop/zookeeper/conf下(这个目录随意,只需要这个目录与hbase/conf下面的zk-jaas.conf文件里面的密钥存放路径统一就行),如下:
# scp /data1/hadoop/zookeeper/conf/zk.keytab 192.168.0.9:/data1/hadoop/zookeeper/conf
- 拷贝hadoop到客户端
同理,hbase依赖与Hadoop存储数据,所以需要与Hadoop进行交互,这里拷贝Hadoop的配置到客户端,如下:
# scp -r /data1/hadoop/hadoop 192.168.0.9:/data1/hadoop
同时,还需要拷贝jdk(如果客户端存在,也可以不用拷贝,但是,jdk的目录不一样的话,需要修改hbase,hadoop环境变量内部的java属性)
# scp -r /data1/hadoop/jdk 192.168.0.9:/data1/jdk
- 配置hbase、zookeeper、Hadoop的环境变量
修改当前用户的.bashrc文件,我当前的用户是hduser
# vim /home/hduser/.bashrc 修改如下:
export HBASE_HOME=/data1/hadoop/hbase
export PATH=${HBASE_HOME}/bin:${PATH}
export ZOOK_HOME=/data1/hadoop/zookeeper
export PATH=${ZOOK_HOME}/bin:$PATH
export HADOOP_HOME=/data1/hadoop/hadoop
export PATH=${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin:$PATH
注意:这里一定要设置Hadoop的环境变量,如果Hadoop环境变量设置错误,或者没有设置,将会报如下的错误:
Caused by: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
FATAL [main] ipc.RpcClientImpl: SASL authentication failed. The most likely cause is missing or invalid credentials. Consider 'kinit'.
javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
出现上述错误的原因有如下几点:
第一点:没有使用kinit获取tgt;
第二点:没有正确配置kerberos配置文件;
第三点:客户端与集群时间不一致(时间相差超过5分钟);
第四点:客户端使用的jar包与集群不一致;
第五点:Hadoop环境变量未正确设置。
如果在集群内部可以正常的使用hbase shell,但是在客户端不行,可以在客户端打开调试模式,如下:
在测试之前,先获取票据:
# kinit /data1/hadoop/hbase/conf/hbase.keytab hbase/yjt
# klist (查看票据)
# exprot HBASE_ROOT_LOGGER=DEBUG,console
# hbase shell
使用list列出当前存在的表,如果正常列出,说明客户端配置成功。当然也可以使用创建表的方式测试,如下:
hbase(main):002:0> create 'ns1:t2', 'f2'
注:ns1是表空间,如果不存在,可以使用create_namespace 'ns1' 创建
(4) 、客户端使用phoenix连接测试
- 客户端Phoenix配置(不多说),可以从集群内部拷贝。
- 测试phoenix,使用 ./sqlline.py yjt:2181 连接到集群。
注:上述用户都是使用hduser用户测试的,这个用户同时也是启动集群的用户,接下来创建不同的用户测试。
3.3、客户端使用不同用户测试
测试hbase shell
(1)、创建普通用户yujt
(2)、echo ‘123456’ |passwd --stdin ‘yujt’
(3)、su - yujt
(4)、配置hadoop、jdk环境变量
(5)、hbase shell 测试
测试phoenix
Ok