本文由作者周梁偉授權網易雲社區發布。
一般我們在使用kbs登陸hadoop服務時都直接在shell中調用kinit命令來獲取憑證,這種方式簡單直接,只要獲取一次憑證之后都可以在該會話過程中重復訪問。但是這種方式一個明顯的問題就是如果在本次shell中會間隔調用不同的java程序,而這些程序需要訪問不同權限的問題,需要在訪問前調用各自的ktab文件獲得授權。這中場景下情況會變得非常復雜,這時如果把kbs認證的過程移到java程序中就會簡單很多,每個java程序中獲取各自的憑證,及時多個進程同時運行也不會產生相互影響。我這里介紹兩種java中獲取kbs憑證的方法,分別使用 org.apache.hadoop.security.SecurityUtil 和 org.apache.hadoop.security.UserGroupInformation 兩個類實現。
一、 使用ktab文件簡單登錄方式
登錄操作函數
/** * 嘗試使用kerberos認證登錄hfs *@params * conf: 配置,其中帶有keytab相關配置屬性 * keytab_KEY: 表示conf中代表keytab文件屬性的鍵值 * principal_KEY: 表示conf中代表principal屬性的鍵值 * @throws IOException */ static void tryKerberosLogin(Configuration conf, String keytab_KEY, String principal_KEY) throws IOException { boolean useSec = true; LOG.info("Hadoop Security enabled: " + useSec); if (!useSec) { return; } try { @SuppressWarnings("rawtypes") Class c = Class.forName("org.apache.hadoop.security.SecurityUtil"); // get method login(Configuration, String, String); @SuppressWarnings("unchecked") Method m = c.getMethod("login", Configuration.class, String.class, String.class); m.invoke(null, conf, keytab_KEY, principal_KEY); LOG.info("successfully authenticated with keytab"); } catch (Exception e) { LOG.error( "Flume failed when attempting to authenticate with keytab " + SimpleConfiguration.get().getKerberosKeytab() + " and principal '" + SimpleConfiguration.get().getKerberosPrincipal() + "'", e); return; } } |
配置
... <property> <name>flume.security.kerberos.principal</name> <description></description> </property> <property> <name>flume.security.kerberos.keytab</name> <value>resources/flume.keytab</value> <description></description> </property> … |
Sample
//調用例子 public FileSystem getFileSystem(Configuration conf) { String KEYFILE_key = "flume.security.kerberos.keytab"; String PRINCIPAL_key = "flume.security.kerberos.principal";
try { // 嘗試用kerberos登錄 tryKerberosLogin(conf, KEYFILE_key, PRINCIPAL_key); // 獲取一個hdfs實例 instance = FileSystem.get( conf); } catch (IOException e) { LOG.error("try getFileSystem fail()", e); } catch (URISyntaxException e) { LOG.error("try getFileSystem fail()", e); } } return instance; } |
二、 通過UserGroupInformation獲取代理用戶方式
package com.netease.backend.bigdata.wa.jobs;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.security.UserGroupInformation; import org.apache.log4j.Logger; import org.hsqldb.lib.StringUtil;
import com.netease.backend.bigdata.wa.core.ConfKeys;
/** * 代理用戶信息認證工具 * * @author zhouliangwei * */ public class ProxyUGI {
private static Logger LOG = Logger.getLogger(ProxyUGI.class);
private static UserGroupInformation instance = null; /** * 從Configuration中獲取代理用戶的相關配置,並獲取UserGroupInformation * @return * @throws IOException */ public synchronized static UserGroupInformation getProxyUGI(Configuration conf) { if (instance != null) return instance; try { String username = conf.get(ConfKeys.MR_USER_NAME, ""); String proxyPrincipal = conf.get(ConfKeys.WDA_PROXY_PRINCIPAL, ""); String proxyKtab = conf.get(ConfKeys.WDA_PROXY_KEYTAB, ""); if (StringUtil.isEmpty(username) || StringUtil.isEmpty(proxyPrincipal) || StringUtil.isEmpty(proxyKtab)) { LOG.warn("config properties: [" + ConfKeys.MR_USER_NAME + ", " + ConfKeys.WDA_PROXY_PRINCIPAL + ", " + ConfKeys.WDA_PROXY_KEYTAB + "] in config file './conf/wda-core.xml' must be set!, quite use proxy mechanism"); return null; } instance = UserGroupInformation.createProxyUser(username, UserGroupInformation.loginUserFromKeytabAndReturnUGI( proxyPrincipal, proxyKtab)); } catch (IOException ex) { //just ignore; } return instance; } } |
調用方式
... public static void main(final String[] args) throws Exception { UserGroupInformation ugi = ProxyUGI.getProxyUGI(); if (ugi != null) { ugi.doAs(new PrivilegedExceptionAction<EventJobClient>() { public EventJobClient run() throws Exception { EventJobClient mr = new EventJobClient(); int code = ToolRunner.run(mr, args); System.exit(code); return mr; } }); System.exit(1); } else { int exitCode = ToolRunner.run(new EventJobClient(), args); System.exit(exitCode); } } …. |
相關文章:
【推薦】 Spring 屬性配置
【推薦】 致傳統企業朋友:不夠痛就別微服務,有坑 (1)
【推薦】 一文帶你了解 Raft 一致性協議的關鍵點
