在企业级大数据平台中,Kerberos认证是保障Hadoop、Hive、HBase等组件安全性的关键机制。当本地Java客户端需要连接到启用了Kerberos认证的EMR集群时,必须正确配置Kerberos,并利用Hive JDBC驱动进行连接。本文将介绍在macOS/Linux环境中,通过Java代码连接到启用了Kerberos认证的EMR Hive服务的方法。
前提条件
已创建集群,且在软件配置页面的高级设置区域中,打开了Kerberos身份认证开关。创建集群详情请参见创建集群。
步骤一:获取EMR集群Kerberos配置
使用SSH方式登录集群Master节点,详情请参见登录集群。
执行以下命令获取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
复制Hive的keytab文件到本地开发环境。
scp root@<公网IP>:/etc/taihao-apps/hive-conf/keytab/hive.keytab /tmp/hive.keytab
其中<公网IP>:Master节点的公网IP,获取方式请参见获取节点公网IP和节点名称。
在本地验证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集群,您需要根据以下步骤配置安全组规则。
步骤四:编写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 | $IPORHOST为java.security.krb5.kdc的值。 |
如果您需要调试,请在main方法开始的地方添加如下代码。
System.setProperty("sun.security.krb5.debug", "true");
常见问题及解决方案
问题 | 原因 | 解决方案 |
Cannot contact any KDC | KDC地址错误或网络问题。 | 确保krb5.conf中KDC地址正确,并使用 |
keytab contains no suitable keys | keytab文件不匹配。 | 运行 |
LoginException: Unable to obtain password | keytab无法访问。 | 运行 |
GSS initiate failed | Kerberos配置错误。 | 确保 |