سؤال

Hi I am trying to write a java client for secure hbase. I want to do kinit also from code itself for that i`m using the usergroup information class. Can anyone point out where am I going wrong here?

this is the main method that Im trying to connect o hbase from.

I have to add the configuration in the CONfiguration object rather than using the xml, because the client can be located anywhere.

Please see the code below:

    public static void main(String [] args) {
    try {
        System.setProperty(CommonConstants.KRB_REALM, ConfigUtil.getProperty(CommonConstants.HADOOP_CONF, "krb.realm"));
        System.setProperty(CommonConstants.KRB_KDC, ConfigUtil.getProperty(CommonConstants.HADOOP_CONF,"krb.kdc"));
        System.setProperty(CommonConstants.KRB_DEBUG, "true");

        final Configuration config = HBaseConfiguration.create();

        config.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, AUTH_KRB);
        config.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHORIZATION, AUTHORIZATION);
        config.set(CommonConfigurationKeysPublic.FS_AUTOMATIC_CLOSE_KEY, AUTO_CLOSE);
        config.set(CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY, defaultFS);
        config.set("hbase.zookeeper.quorum", ConfigUtil.getProperty(CommonConstants.HBASE_CONF, "hbase.host"));
        config.set("hbase.zookeeper.property.clientPort", ConfigUtil.getProperty(CommonConstants.HBASE_CONF, "hbase.port"));
        config.set("hbase.client.retries.number", Integer.toString(0));
        config.set("zookeeper.session.timeout", Integer.toString(6000));
        config.set("zookeeper.recovery.retry", Integer.toString(0));
        config.set("hbase.master", "gauravt-namenode.pbi.global.pvt:60000");
        config.set("zookeeper.znode.parent", "/hbase-secure");
        config.set("hbase.rpc.engine", "org.apache.hadoop.hbase.ipc.SecureRpcEngine");
        config.set("hbase.security.authentication", AUTH_KRB);
        config.set("hbase.security.authorization", AUTHORIZATION);
        config.set("hbase.master.kerberos.principal", "hbase/gauravt-namenode.pbi.global.pvt@pbi.global.pvt");
        config.set("hbase.master.keytab.file", "D:/var/lib/bda/secure/keytabs/hbase.service.keytab");
        config.set("hbase.regionserver.kerberos.principal", "hbase/gauravt-datanode2.pbi.global.pvt@pbi.global.pvt");
        config.set("hbase.regionserver.keytab.file", "D:/var/lib/bda/secure/keytabs/hbase.service.keytab");

        UserGroupInformation.setConfiguration(config);
        UserGroupInformation userGroupInformation = UserGroupInformation.loginUserFromKeytabAndReturnUGI("hbase/gauravt-datanode2.pbi.global.pvt@pbi.global.pvt", "D:/var/lib/bda/secure/keytabs/hbase.service.keytab");
        UserGroupInformation.setLoginUser(userGroupInformation);

        User user = User.create(userGroupInformation);

        user.runAs(new PrivilegedExceptionAction<Object>() {

            @Override
            public Object run() throws Exception {
                HBaseAdmin admins = new HBaseAdmin(config);

                if(admins.isTableAvailable("ambarismoketest")) {
                    System.out.println("Table is available");
                };

                HConnection connection = HConnectionManager.createConnection(config);

                HTableInterface table = connection.getTable("ambarismoketest");



                admins.close();
                System.out.println(table.get(new Get(null)));
                return table.get(new Get(null));
            }
        });
        System.out.println(UserGroupInformation.getLoginUser().getUserName());


    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

I`m getting the following exception:

    Caused by: org.apache.hadoop.ipc.RemoteException(javax.security.sasl.SaslException): GSS initiate failed
at org.apache.hadoop.hbase.security.HBaseSaslRpcClient.readStatus(HBaseSaslRpcClient.java:110)
at org.apache.hadoop.hbase.security.HBaseSaslRpcClient.saslConnect(HBaseSaslRpcClient.java:146)
at org.apache.hadoop.hbase.ipc.RpcClient$Connection.setupSaslConnection(RpcClient.java:762)
at org.apache.hadoop.hbase.ipc.RpcClient$Connection.access$600(RpcClient.java:354)
at org.apache.hadoop.hbase.ipc.RpcClient$Connection$2.run(RpcClient.java:883)
at org.apache.hadoop.hbase.ipc.RpcClient$Connection$2.run(RpcClient.java:880)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:396)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)
at org.apache.hadoop.hbase.ipc.RpcClient$Connection.setupIOstreams(RpcClient.java:880)
... 33 more

Any pointers would be helpful.

هل كانت مفيدة؟

المحلول

The above works nicely, but I've seen a lot of folks struggle with setting all of the right properties in the Configuration object. There's no de-facto list that I've found of exactly what you need and don't need and it is painfully dependent on your cluster configuration.

The surefire way is to have a copy of your HBase configurations in your classpath, since your client can be anywhere as you mentioned. Then you can add the resources to your object without having to specify all properties.

Configuration conf = HBaseConfiguration.create();
conf.addResource("core-site.xml");
conf.addResource("hbase-site.xml");
conf.addResource("hdfs-site.xml");

Here were some sources to back this approach: IBM, Scalding (Scala)

Also note that this approach doesn't limit you to actually use the internal Zookeeper principal and keytab, i.e. you can create keytabs for applications or Active Directory users and leave the internally generated keytabs for the daemons to authenticate amongst themselves.

نصائح أخرى

Not sure if you still need help. I think setting the "hadoop.security.authentication" property is missing from your snippet.

I am using following code snippet to connect to secure HBase (on CDH5). You can give a try.

config.set("hbase.zookeeper.quorum", zookeeperHosts);
config.set("hbase.zookeeper.property.clientPort", zookeeperPort);
config.set("hadoop.security.authentication", "kerberos");
config.set("hbase.security.authentication", "kerberos");
config.set("hbase.master.kerberos.principal", HBASE_MASTER_PRINCIPAL);
config.set("hbase.regionserver.kerberos.principal", HBASE_RS_PRINCIPAL);

UserGroupInformation.setConfiguration(config);
UserGroupInformation.loginUserFromKeytab(ZOOKEEPER_PRINCIPAL,ZOOKEEPER_KEYTAB);

HBaseAdmin admins = new HBaseAdmin(config);
TableName[] tables  = admins.listTableNames();

for(TableName table: tables){
    System.out.println(table.toString());
}
in Jdk 1.8, you need set 
"System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");"

config.set("hbase.zookeeper.quorum", zookeeperHosts);
config.set("hbase.zookeeper.property.clientPort", zookeeperPort);
config.set("hadoop.security.authentication", "kerberos");
config.set("hbase.security.authentication", "kerberos");
config.set("hbase.master.kerberos.principal", HBASE_MASTER_PRINCIPAL);
config.set("hbase.regionserver.kerberos.principal", HBASE_RS_PRINCIPAL);
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
UserGroupInformation.setConfiguration(config);
UserGroupInformation.loginUserFromKeytab(ZOOKEEPER_PRINCIPAL,ZOOKEEPER_KEYTAB);

HBaseAdmin admins = new HBaseAdmin(config);
TableName[] tables  = admins.listTableNames();

for(TableName table: tables){
    System.out.println(table.toString());
}

quote:
http://hbase.apache.org/book.html#trouble.client 
question: 142.9 

I think the best is https://scalding.io/2015/02/making-your-hbase-client-work-in-a-kerberized-environment/

To make the code work you don’t have to change any line from the one written in the top of this post, you just have to make your client able to access the full HBase configuration. This just implies to change your running classpath to:

/opt/cloudera/parcels/CDH-5.3.0-1.cdh5.3.0.p0.30/lib/hbase/conf:target/scala-2.11/hbase-assembly-1.0.jar This will make everything run smoothly. It is specific for CDH 5.3 but you can adapt it for your cluster configuration.

PS No need in this:

conf.addResource("core-site.xml");
conf.addResource("hbase-site.xml");
conf.addResource("hdfs-site.xml");

Because HBaseConfiguration has

  public static Configuration addHbaseResources(Configuration conf) {
conf.addResource("hbase-default.xml");
conf.addResource("hbase-site.xml");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top