更新时间:2024-10-31 GMT+08:00

配置HDFS应用安全认证

场景说明

访问安全集群环境中的服务,需要先通过Kerberos安全认证。所以HDFS应用程序中需要写入安全认证代码,确保HDFS程序能够正常运行。

安全认证有两种方式:

  • 命令行认证:

    提交HDFS应用程序运行前,在HDFS客户端执行如下命令进行认证。

    kinit 组件业务用户

    该方式仅适用于Linux操作系统,且安装了HDFS的客户端。

  • 代码认证:

    通过获取客户端的principal和keytab文件进行认证。

    注意修改代码中的PRINCIPAL_NAME变量为实际使用的值。

    private static final String PRNCIPAL_NAME = "hdfsDeveloper";

安全认证代码

目前样例代码统一调用LoginUtil类进行安全认证。

在HDFS样例工程代码中,不同的样例工程,使用的认证代码不同,包括基本安全认证和带ZooKeeper认证。

  • 基本安全认证:
    com.huawei.bigdata.hdfs.examples包的HdfsExample类样例程序不需要访问HBase或ZooKeeper,所以使用基本的安全认证代码即可。示例代码如下:
    ...
        private static final String PATH_TO_HDFS_SITE_XML = HdfsExample.class.getClassLoader().getResource("hdfs-site.xml").getPath();
        private static final String PATH_TO_CORE_SITE_XML = HdfsExample.class.getClassLoader().getResource("core-site.xml").getPath();
        private static final String PRNCIPAL_NAME = "hdfsDeveloper";
        private static final String PATH_TO_KEYTAB = HdfsExample.class.getClassLoader().getResource("user.keytab").getPath();
        private static final String PATH_TO_KRB5_CONF = HdfsExample.class.getClassLoader().getResource("krb5.conf").getPath();
        private static Configuration conf = null;
        }
    ...
        private static void authentication() throws IOException {
            // security mode
            if ("kerberos".equalsIgnoreCase(conf.get("hadoop.security.authentication"))) {
                System.setProperty("java.security.krb5.conf", PATH_TO_KRB5_CONF);
                LoginUtil.login(PRNCIPAL_NAME, PATH_TO_KEYTAB, PATH_TO_KRB5_CONF, conf);
            }
        }
  • 带ZooKeeper认证:

    com.huawei.bigdata.hdfs.examples包的“ColocationExample”类样例程序不仅需要基础安全认证,还需要添加ZooKeeper服务端Principal才能完成安全认证。示例代码如下:

    ...
        private static final String ZOOKEEPER_SERVER_PRINCIPAL_KEY = "zookeeper.server.principal";
        private static final String PRINCIPAL = "username.client.kerberos.principal";
        private static final String KEYTAB = "username.client.keytab.file";
        private static final String PRNCIPAL_NAME = "hdfsDeveloper";
        private static final String LOGIN_CONTEXT_NAME = "Client";
        private static final String PATH_TO_KEYTAB = System.getProperty("user.dir") + File.separator + "conf" + File.separator + "user.keytab";
        private static final String PATH_TO_KRB5_CONF = ColocationExample.class.getClassLoader().getResource("krb5.conf") .getPath();
        private static String zookeeperDefaultServerPrincipal = null;
        private static Configuration conf = new Configuration();
        private static DFSColocationAdmin dfsAdmin;
        private static DFSColocationClient dfs;
        private static void init() throws IOException {
            LoginUtil.login(PRNCIPAL_NAME, PATH_TO_KEYTAB, PATH_TO_KRB5_CONF, conf);
            LoginUtil.setJaasConf(LOGIN_CONTEXT_NAME, PRNCIPAL_NAME, PATH_TO_KEYTAB);
            zookeeperDefaultServerPrincipal = "zookeeper/hadoop." + KerberosUtil.getKrb5DomainRealm().toLowerCase();
            LoginUtil.setZookeeperServerPrincipal(ZOOKEEPER_SERVER_PRINCIPAL_KEY, zookeeperDefaultServerPrincipal);
        }	
    ...
  • 以上安全认证代码中的hdfsDeveloper用户及该用户的user.keytab、krb5.conf为示例,实际操作时请联系管理员获取相应权限的账号以及对应账号的keytab文件和krb5文件。
  • 用户可登录FusionInsight Manager,选择“系统 > 权限 > 域和互信”,查看“本端域”参数,即为当前系统域名。
  • “zookeeper/hadoop.<系统域名>为用户名,用户的用户名所包含的系统域名所有字母为小写。例如“本端域”参数为“9427068F-6EFA-4833-B43E-60CB641E5B6C.COM”,用户名为“zookeeper/hadoop.9427068f-6efa-4833-b43e-60cb641e5b6c.com”。