在企業級巨量資料平台中,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配置錯誤。 | 確保 |