HBase + Kerberos 配置示例(二)

接上篇《HBase + Kerberos配置示例(一)》,咱們繼續剩下的配置工做。html

環境準備

  • 安裝hadoop/zookeeper/hbase

我在kbhbase1這個機器上已經安裝好了hadoop,zookeeper,hbase,爲了簡單起見全部在東西都跑在這臺機器上。同時檢查了在沒在啓用kerberos的狀況下,hbase工做正常。java

  • 禁用selinux

#vim /etc/sysconfig/selinux 設置SELINUX=disabled,並重啓node

  • 安裝JCE

從Oracle網站下載JCE(Java Cryptography Extension)補丁,此補丁與AES-256加密有關。下載解壓以後,把獲得的兩個jar文件local_policy.jar,US_export_policy.jar拷貝到$JAVA_HOME/ jre/lib/security下進行覆蓋。linux

Hadoop配置

建立keytab程序員

  • kadmin: addprinc -randkey root/kbhbase1.mh.com@MH.COM
  • kadmin: xst -k root.keytab root/kbhbase1.mh.com

這樣就會在kerberos服務器上建立一個用戶root/kbhbase1.mh.com@MH.COM,其中名字中/以後的部分應該是固定寫法,即主機名+kerberos realm,紅色部分則能夠隨意。xst命令會在當前目錄下生成這個root.keytab文件。拷貝root.keytab文件到hadoop的配置目錄,在個人機器上是:/usr/local/hadoop-2.6.0/etc/hadoopweb

修改core-site.xmlshell

<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://kbhbase1.mh.com:9000</value>
</property>

<property>
<name>hadoop.security.authentication</name>
<value>kerberos</value>
<!-- Giving value as "simple" disables security.-->
</property>
<property>
<name>hadoop.security.authorization</name>
<value>true</value>
</property>
</configuration>
View Code

修改hadoop-env.shapache

  • export HADOOP_SECURE_DN_USER=root
  • export JSVC_HOME=/usr/local/hadoop-2.6.0/libexec/

關於JSVC,默認指向hadoop安裝目錄的libexec下,但個人libexec下並無jsvc文件(個人hadoop是直接下載的tar.gz包,不是rpm安裝),google搜索jsvc,而後在apache網站下載源代碼包以及bin包,我下的是commons-daemon-1.0.15-src.tar.gz及commons-daemon-1.0.15-bin.tar.gz,先解壓src包後進入src/native/unix目錄依次執行 ./configure命令, make命令,這樣會在當前目錄下生成一個叫jsvc的文件,把它拷貝到hadoop目錄下的libexec下。 再解壓bin包,而後把獲得的commons-daemon-1.0.15.jar 文件拷貝到hadoop安裝目錄下share/hadoop/hdfs/lib下,同時刪除自帶版本的commons-daemon-xxx.jar包。vim

修改hdfs-site.xml服務器

<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/root/hadoopdata/namenode</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/root/hadoopdata/datanode</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>kbhbase1.mh.com:9001</value>
</property>
<property>
<name>dfs.block.access.token.enable</name>
<value>true</value>
</property>
<!-- NameNode security config -->
<property>
<name>dfs.https.address</name>
<value>kbhbase1.mh.com:50470</value>
</property>
<property>
<name>dfs.https.port</name>
<value>50470</value>
</property>
<property>
<name>dfs.namenode.keytab.file</name>
<value>/usr/local/hadoop-2.6.0/etc/hadoop/root.keytab</value> <!-- path to the HDFS keytab -->
</property>
<property>
<name>dfs.namenode.kerberos.principal</name>
<value>root/_HOST@MH.COM</value>
</property>
<property>
<name>dfs.namenode.kerberos.https.principal</name>
<value>root/_HOST@MH.COM</value>
</property>
<!-- Secondary NameNode security config -->
<property>
<name>dfs.secondary.https.address</name>
<value>kbhbase1.mh.com:50495</value>
</property>
<property>
<name>dfs.secondary.https.port</name>
<value>50495</value>
</property>
<property>
<name>dfs.secondary.namenode.keytab.file</name>
<value>/usr/local/hadoop-2.6.0/etc/hadoop/root.keytab</value> <!-- path to the HDFS keytab -->
</property>
<property>
<name>dfs.secondary.namenode.kerberos.principal</name>
<value>root/_HOST@MH.COM</value>
</property>
<property>
<name>dfs.secondary.namenode.kerberos.https.principal</name>
<value>root/_HOST@MH.COM</value>
</property>
<!-- DataNode security config -->
<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-2.6.0/etc/hadoop/root.keytab</value> <!-- path to the HDFS keytab -->
</property>
<property>
<name>dfs.datanode.kerberos.principal</name>
<value>root/_HOST@MH.COM</value>
</property>
<property>
<name>dfs.datanode.kerberos.https.principal</name>
<value>root/_HOST@MH.COM</value>
</property>
<property>
<name>dfs.web.authentication.kerberos.principal</name>
<value>root/_HOST@MH.COM</value>
</property>
<property>
<name>dfs.datanode.require.secure.ports</name>
<value>false</value>
</property>
</configuration>
View Code

因爲暫時不須要mapreduce,因此相關的設置我就沒配。

啓動hadoop hdfs

  • # start-dfs.sh

namenode,secondarynamenode能夠起來,不過datanode沒起來,仔細看start-dfs.sh的輸出:

Attempting to start secure cluster, skipping datanodes. Run start-secure-dns.sh as root to complete startup.

因此須要執行start-secure-dns.sh(或者使用hadoop datanode命令啓動),在個人機器上,起來以後,使用jps查看,datanode進程有進程號,但沒有名字。

如遇到:

WARN security.UserGroupInformation: Exception encountered while running the renewal command. Aborting renew thread. ExitCodeException exitCode=1: kinit: Ticket expired while renewing credentials

具體看hadoop日誌,會有若干個CheckSum錯誤,則須要在kdc上:

  • kadmin.local: modprinc -maxrenewlife 1week root/kbhbase1.mh.com@MH.COM

關於kerberos ticket的一些解釋

一個ticket有lifetime,若是須要更長的時間,那麼就須要重複地去renew它,每renew一次,就延長一個lifetime。renew就是能夠不用輸入密碼就延長一個ticket的使用時間。 不過,renew這個操做自己也有時間限制,這取決於參數renew_lifetime,好比這個參數設置成7d,那麼也就是說從ticket建立那時開始以後的7天內,你均可以作renew操做(每次renew操做需在ticket還沒有過時前作)。

Zookeeper配置

建立keytab

  • kadmin: addprinc -randkey zookeeper/kbhbase1.mh.com@MH.COM
  • kadmin: xst -k zookeeper.keytab zookeeper/kbhbase1.mh.com

把生成的zookeeper.keytab 放到/usr/local/zookeeper-3.4.6/conf下

修改jaas.conf

Server {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/usr/local/zookeeper-3.4.6/conf/zookeeper.keytab"
  storeKey=true
  useTicketCache=false
  principal="zookeeper/kbhbase1.mh.com@MH.COM";
};
View Code

修改java.env

  • export JVMFLAGS="-Djava.security.auth.login.config=/usr/local/zookeeper-3.4.6/conf/jaas.conf"
  • export JAVA_HOME="/usr/lib/jvm/jdk7"

修改zoo.cfg

tickTime=2000
dataDir=/root/zookeeperdata
clientPort=2181
initLimit=5
syncLimit=2
server.1=kbhbase1.mh.com:2888:3888

kerberos.removeHostFromPrincipal=true
kerberos.removeRealmFromPrincipal=true

authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
jaasLoginRenew=3600000
View Code

HBase配置

建立keytab

  • kadmin: addprinc -randkey hbase/kbhbase1.mh.com@MH.COM
  • kadmin: xst -k hbase.keytab hbase/kbhbase1.mh.com

將生成的文件拷貝到hbase配置目錄/usr/local/hbase-0.98.9-hadoop2/conf

修改hbase-env.sh

  • export JAVA_HOME=/usr/lib/jvm/jdk7/
  • export HBASE_OPTS="-XX:+UseConcMarkSweepGC -Djava.security.auth.login.config=/usr/local/hbase-0.98.9-hadoop2/conf/zk-jaas.conf"
  • export HBASE_MANAGES_ZK=false

修改hbase-site.xml

<configuration>
<property>
 <name>hbase.rootdir</name>
 <value>hdfs://kbhbase1.mh.com:9000/hbase</value>
 <description>The directory shared by region servers.</description>
</property>
<property>
 <name>hbase.zookeeper.property.clientPort</name>
 <value>2181</value>
 <description>Property from ZooKeeper's config zoo.cfg. The port at which the clients will connect.
 </description>
</property>
<property>
 <name>zookeeper.session.timeout</name>
 <value>120000</value>
</property>
<property>
 <name>hbase.zookeeper.quorum</name>
 <value>kbhbase1.mh.com</value>
</property>
<property>
 <name>hbase.tmp.dir</name>
 <value>/root/hbasedata</value>
</property>
<property>
 <name>hbase.cluster.distributed</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@MH.COM</value>
</property>

<property>
<name>hbase.regionserver.keytab.file</name>
<value>/usr/local/hbase-0.98.9-hadoop2/conf/hbase.keytab</value>
</property>

<property>
<name>hbase.master.kerberos.principal</name>
<value>hbase/_HOST@MH.COM</value>
</property>

<property>
<name>hbase.master.keytab.file</name>
<value>/usr/local/hbase-0.98.9-hadoop2/conf/hbase.keytab</value>
</property>
</configuration>
View Code

修改zk-jaas.conf

Client {
      com.sun.security.auth.module.Krb5LoginModule required
      useKeyTab=true
      useTicketCache=false
      keyTab="/usr/local/hbase-0.98.9-hadoop2/conf/hbase.keytab"
      principal="hbase/kbhbase1.mh.com@MH.COM";
   };
View Code

啓動hbase

  • start-hbase.sh

啓動hbase 如遇:

2015-04-11 14:20:58,538 FATAL [master:kbhbase1:60000] master.HMaster: Unhandled exception. Starting shutdown. org.apache.hadoop.security.AccessControlException: Permission denied: user=hbase, access=WRITE, inode="/hbase":root:supergroup:drwxr-xr-x

 個人hbase是直接從tar.gz包解壓安裝的,全部的都有linux的root跑。這個錯誤信息表示在hbase使用的默認用戶「hbase」沒有對hdfs文件系統中的/hbase目錄的訪問權限。 嘗試使用

  • # hadoop fs -chmod -R 777 /hbase

或使用

  • # hadoop fs –rmr /hbase

遇到

rmr: Permission denied: user=admin, access=WRITE, inode="/":root:supergroup:drwxr-xr-x 

這裏的user,應該是我以前kinit的用戶,這個錯誤也就是說,我當前在kbhbase1這臺機器上使用的kerberos身份證是admin/admin,而hdfs的/hbase目錄屬於root用戶,因此沒有權限對它進行更改權限的操做。 因此我添加了一個root/admin

  • kadmin: addprinc root/admin
  • # kinit root/admin
  • # hadoop fs -chmod -R 777 /hbase

這就ok了 啓動成功以後,能夠用hbase shell來試一下,固然,在執行hbase shell前,事先要有kinit一下,你可使用剛纔建的root/admin,或者別的。

Java測試程序

在kbjavatest1安裝kerberos客戶端,從kbhbase1上拷貝hbase-site.xml到本機的某個目錄。鏈接kadmin工具建立用戶javatest,並生成keytab文件:

  • kinit admin/admin
  • kadmin: addprinc -randkey javatest
  • kadmin: xst -k javatest.keytab javatest

建立java project,添加對hbase jar的引用,編寫java代碼,運行時注意把剛纔拷貝來的hbase-site.xml放到運行的classpath中(eclipse能夠經過Run Configurations>>Classpath配置)

public class Test1 {

        public static void main(String[] args) throws IOException {
                // TODO Auto-generated method stub
                Configuration conf = HBaseConfiguration.create();
                conf.set("hadoop.security.authentication", "kerberos");
                UserGroupInformation.setConfiguration(conf);
                UserGroupInformation.loginUserFromKeytab("javatest@MH.COM", "/root/Downloads/javatest.keytab");
                //
                HTable t = new HTable(conf, "test");
                Scan s = new Scan();
                ResultScanner rs = t.getScanner(s);
                try{
                        for(Result r:rs){
                                for(Cell cell:r.rawCells()){
                                        System.out.println("Row: "+new String(CellUtil.cloneRow(cell)));
                                        System.out.println("CF: "+new String(CellUtil.cloneFamily(cell)));
                                        System.out.println("Qualifier: "+new String(CellUtil.cloneQualifier(cell)));
                                        System.out.println("Value: "+new String(CellUtil.cloneValue(cell)));
                                }
                        }
                }finally{
                        t.close();
                }

                System.out.println("Done!");

        }
View Code

 


送書了,送書了,關注公衆號「程序員雜書館」,送出O'Reilly《Spark快速大數據分析》紙質書(亦有一批PDF分享)! —— 2018年12月

相關文章
相關標籤/搜索