使用Java连接开启Kerberos认证的Hive

在企业级大数据平台中,Kerberos认证是保障Hadoop、Hive、HBase等组件安全性的关键机制。当本地Java客户端需要连接到启用了Kerberos认证的EMR集群时,必须正确配置Kerberos,并利用Hive JDBC驱动进行连接。本文将介绍在macOS/Linux环境中,通过Java代码连接到启用了Kerberos认证的EMR Hive服务的方法。

前提条件

已创建集群,且在软件配置页面的高级设置区域中,打开了Kerberos身份认证开关。创建集群详情请参见创建集群

步骤一:获取EMR集群Kerberos配置

  1. 使用SSH方式登录集群Master节点,详情请参见登录集群

  2. 执行以下命令获取Kerberos配置文件krb5.conf。该文件通常位于集群master-1-1节点的/etc/krb5.conf路径下。

    cat /etc/krb5.conf

    根据实际情况获取的配置项default_realm会在后续的Java代码中使用。其中,获取到的配置信息示例如下:

    [logging]
      default = FILE:/mnt/disk1/log/kerberos/krb5libs.log
      kdc = FILE:/mnt/disk1/log/kerberos/krb5kdc.log
      admin_server = FILE:/mnt/disk1/log/kerberos/kadmind.log
    
    [libdefaults]
      default_realm = EMR.C-EXAMPLE.COM
      dns_lookup_realm = false
      dns_lookup_kdc = false
      ticket_lifetime = 24h
      renew_lifetime = 7d
      forwardable = true
      rdns = false
      dns_canonicalize_hostname = true
      pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
      kdc_timeout = 30s
      max_retries = 3
    
    [realms]
      EMR.C-EXAMPLE.COM = {
        kdc = master-1-1.c-ce2fcb9c9c0b****.cn-hangzhou.emr.aliyuncs.com:88
        admin_server = master-1-1.c-ce2fcb9c9c0b****.cn-hangzhou.emr.aliyuncs.com:749
      }

步骤二:复制keytab文件并获取Principal

  1. 复制Hivekeytab文件到本地开发环境。

    scp root@<公网IP>:/etc/taihao-apps/hive-conf/keytab/hive.keytab /tmp/hive.keytab

    其中<公网IP>:Master节点的公网IP,获取方式请参见获取节点公网IP和节点名称

  2. 在本地验证keytab文件的有效性,并获取Principal。

    klist -kt /tmp/hive.keytab

    命令执行成功后的返回示例如下:

    Keytab name: FILE:/tmp/hive.keytab
    KVNO Timestamp           Principal
    ---- ------------------- ------------------------------------------------------
       2 02/25/2025 10:40:41 hive/master-1-1.c-EXAMPLE.cn-hangzhou.emr.aliyuncs.com@EMR.C-EXAMPLE.COM
       2 02/25/2025 10:40:41 hive/master-1-1.c-EXAMPLE.cn-hangzhou.emr.aliyuncs.com@EMR.C-EXAMPLE.COM

    获取的Principal示例格式为:hive/master-1-1.c-EXAMPLE.cn-hangzhou.emr.aliyuncs.com@EMR.C-EXAMPLE.COM,Principal的值后续会在Java代码连接Hive时使用。

步骤三:配置网络访问控制策略

为保证本地开发环境可以访问EMR集群,您需要根据以下步骤配置安全组规则。

  1. 获取本地开发环境的访问IP地址。

    您可以通过访问IP地址,获取当前服务器的访问IP地址。

  2. 进入安全组页面。

    1. 登录E-MapReduce控制台

    2. 在顶部菜单栏处,根据实际情况选择地域和资源组

    3. 集群管理页面,单击目标集群的集群ID。

    4. 基础信息页面,单击集群安全组后面的链接。

  3. 安全组规则页面,单击手动添加,填写安全组策略。

    协议类型选择全部授权对象填写为步骤1获取的访问IP地址,其余参数保持默认。详情请参见添加安全组规则

步骤四:编写Java代码

配置Maven依赖

pom.xml文件中添加以下依赖。

<dependencies>
    <dependency>
        <groupId>org.apache.hive</groupId>
        <artifactId>hive-jdbc</artifactId>
        <version>3.1.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>3.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-auth</artifactId>
        <version>3.2.1</version>
    </dependency>
</dependencies>

Java代码示例

根据步骤一:获取EMR集群Kerberos配置步骤二:复制keytab文件并获取Principal获取的配置信息,修改下面代码示例中的参数值,然后将代码内容填写到Main.java文件中。

package com.aliyun.emr.example;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class Main {
    private static final String DRIVER_CLASS = "org.apache.hive.jdbc.HiveDriver";
    
    public static void main(String[] args) throws Exception {
        // 设置Kerberos认证的Realm信息和KDC地址。
        System.setProperty("java.security.krb5.realm", "EMR.EXAMPLE.COM");
        System.setProperty("java.security.krb5.kdc", "$IPORHOST");
        
        Configuration conf = new Configuration();
        conf.set("hadoop.security.authentication", "kerberos");
        UserGroupInformation.setConfiguration(conf);
        // 使用Keytab文件进行Kerberos登录。
        UserGroupInformation.loginUserFromKeytab(
            "hive/master-1-1.c-EXAMPLE.cn-hangzhou.emr.aliyuncs.com@EMR.C-EXAMPLE.COM",
            "/tmp/hive.keytab"
        );
        
        Class.forName(DRIVER_CLASS);
        
        // 定义Hive的Principal,用于JDBC连接时的身份验证。
        String hivePrincipal = "hive/master-1-1.c-EXAMPLE.cn-hangzhou.emr.aliyuncs.com@EMR.C-EXAMPLE.COM";
        // 构造Hive JDBC URL,包含连接地址和Principal信息。
        String hiveUrl = "jdbc:hive2://$IPORHOST:10000/;principal=" + hivePrincipal;
        Connection connection = DriverManager.getConnection(hiveUrl);
        Statement statement = connection.createStatement();
        
        ResultSet resultSet = statement.executeQuery("SHOW DATABASES");
        while (resultSet.next()) {
            System.out.println(resultSet.getString(1));
        }
        
        resultSet.close();
        statement.close();
        connection.close();
    }
}

要配置的参数信息如下:

参数

参数配置

java.security.krb5.realm

步骤一:获取EMR集群Kerberos配置中获取的krb5.conf配置中的default_realm值。

java.security.krb5.kdc

KDC服务器地址。您可配置为Master节点的地址,如公网IP地址或域名,请确保可访问。

hivePrincipal

步骤二:复制keytab文件并获取Principal中获取的Principal。

UserGroupInformation.loginUserFromKeytab

第一个参数为hivePrincipal的值。

hiveUrl

$IPORHOSTjava.security.krb5.kdc的值。

如果您需要调试,请在main方法开始的地方添加如下代码。

System.setProperty("sun.security.krb5.debug", "true");

常见问题及解决方案

问题

原因

解决方案

Cannot contact any KDC

KDC地址错误或网络问题。

确保krb5.confKDC地址正确,并使用nc -zv测试端口可连通。

keytab contains no suitable keys

keytab文件不匹配。

运行klist -kt /path/to/hive.keytab确保principal正确。

LoginException: Unable to obtain password

keytab无法访问。

运行chmod 400 /path/to/hive.keytab确保权限正确。

GSS initiate failed

Kerberos配置错误。

确保java.security.krb5.conf配置正确。