1.非安全模式
在非安全模式下,访问hdfs文件系统的客户端代码如下:
package ntci.hadoop.hdfs.test;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.security.UserGroupInformation;
import java.io.*;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
/**
* Created by ctt on 2017/4/9.
*/
public class HDFSClient {
public static void main(String[] args) throws IOException {
try {
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://hadoop-m-21:8020");
conf.set("fs.hdfs.impl",org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());//如果在pom.xml中配置了如下依赖,可省
// <groupId>org.apache.hadoop</groupId>
// <artifactId>hadoop-hdfs</artifactId>
// <version>2.6.0</version>
UserGroupInformation.setConfiguration(conf);//初始化用户组信息,并设置用户权限信息。即对UGI设置静态配置,特别是设置安全认证机制和组查找服务。
FileSystem fs = FileSystem.get(conf);
FileStatus[] fsStatus = fs.listStatus(new Path("/"));
for (int i = 0;i < fsStatus.length;i++){
System.out.println(fsStatus[i].getPath().toString());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.安全模式下(非代理)
2.1为集群配置kerberos
使用域名:HADOOP.COM。
2.2创建测试用户test
在root用户下,使用kadmin.local命令,本地操作KDC数据库:kadmin.local -q “addprinc test”,回车,输入两次test用户的密码:test。 这样,获取到test用户的 principal:test@HADOOP.COM,默认的主机名为:ctt-m-48。
2.3获取test用户的Ticket-Granting ticket
(1)输入kinit test回车,输入其密码test,回车,得到test用户的TGT,或者
(2)kinit -k -t test.keytab test@HADOOP.COM(kinit obtains and caches an initial ticket-granting ticket for principal),票据存放在TGT cache:/tmp/krb5cc_*本地缓存中(其中*表示的是用户的ID)。
kinit [-V] [-l lifetime] [-s start_time] [-r renewable_life] [-p | -P] [-f | -F] [-a] [-A] [-C] [-E] [-v] [-R] [-k [-t keytab_file]] [-c cache_name] [-n] [-S service_name] [-I input_ccache] [-T armor_ccache] [-X attribute[=value]] [principal]
可以通过使用命令:klist -e查看test用户的TGT,如下所示,可以看到TGT的创建日期,有效期,属主以及类型等信息。

2.4生成test用户的keytab文件test.keytab
在root用户下使用kadmin.local -q “xst -norandkey -k test.keytab test@HADOOP.COM”命令。同时将生成的test.keytab文件放到/etc/security/keytabs文件夹下。
2.5综合以上过程得到test用户的principal和test.keytab文件,用来做请求认证
(1)Ticket-Granting-Ticket(TGT):这张ticket需要用户手动获取,这张ticket是用户获取Service Ticket的凭证。用户需要提供Kerberos principal和密码或者keytab通过Kerberos认证才能够获取TGT,获取后TGT会缓存在用户的客户端(/tmp/krb5cc_*)。
(2)Service Ticket:访问集群中各个服务的凭证。Kerberos会自动根据客户端缓存的TGT来向用户发放Service Ticket,用户手动获取了TGT后 无需 自己获取Service Ticket。
(3)要通过Kerberos的认证需要提供principal及其对应的密码。密码可以手动输入,也可以存放在一个keytab文件中。“Keytab”是“key table”的简写,它用于存放一个或多个principal的密码。进行Kerberos认证时,一个用户可以提供principal和密码,或者principal和keytab文件。如果使用principal和keytab文件认证,那么Kerberos会去keytab文件中读取principal密码。
2.6代码样例
2.6.1功能介绍
HDFS初始化是指在使用HDFS提供的API之前,需要做的必要工作。过程为:加载HDFS服务配置文件,并进行kerberos安全认证,认证通过后再实例化Filesystem,之后使用HDFS的API。
2.6.2配置文件介绍
文件 | 作用 | Core-site.xml | 配置hdfs详细参数。 | Hdfs-site.xml | 配置hdfs详细参数。 | *.keytab | 对于Kerberos安全认证提供HDFS用户信息。 | krb5.conf | Kerberos server配置信息 |
2.6.3代码样例
public class HDFSClient {
public static void main(String[] args) {
try {
//1. 初始化Configuration对象,并加载配置文件。
Configuration conf = new Configuration();
//conf.set("fs.defaultFS","hdfs://ctt-m-48:8020");
//conf.set("hadoop.security.authentication","kerberos");
conf.addResource(new Path("/usr/hdp/2.5.0.0-1245/hadoop/conf/core-site.xml"));
conf.addResource(new Path("/usr/hdp/2.5.0.0-1245/hadoop/conf/hdfs-site.xml"));
//2. 根据配置文件进行Kerberos安全认证。
UserGroupInformation.setConfiguration(conf);//初始化用户组信息,得到kerberos的realm,以及auth_to_local(即principal到本地用户的映射,例如:RULE:[1:1@0](hdfs-hadoop_ctt@HADOOP.COM)s/.*/hdfs/),同时即对UGI设置静态配置,特别是设置安全认证机制和组查找服务。
UserGroupInformation.loginUserFromKeytab("test@HADOOP.COM","/etc/security/keytabs/test.keytab");//在此,我们使用用户名(principal)和keytab文件登录,如果选择使用用户名和密码登录,则相应的代码可写为:LoginContext lc = kinit();
//UserGroupInformation.loginUserFromSubject(lc.getSubject());
//3. 初始化HDFS Filesystem文件系统操作对象。使用FileSystem对象对HDFS文件系统进行查询,创建、删除目录、文件操作。
FileSystem fs = FileSystem.get(conf);
fs.copyFromLocalFile(new Path(path), new Path("/tmp/test/test1"));
FileStatus[] fsStatus = fs.listStatus(new Path("/"));
for (int i = 0;i < fsStatus.length;i++){
System.out.println(fsStatus[i].getPath().toString());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package etl.dh;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.security.UserGroupInformation;
public class HdfsKerberosTest2 {
/**
*
* @throws IOException
*/
public void list() throws IOException {
Configuration conf = new Configuration();
init(conf);
FileSystem fs = FileSystem.get(conf);
// 查看文件hdfs文件目录
FileStatus[] flist = fs.listStatus(new Path("/"));
for (FileStatus status : flist) {
System.out.println(status.getPath());
System.out.println(status.getPermission());
System.out.println(status.getReplication());// copy how much
}
}
public void init(final Configuration conf) throws IOException {
System.setProperty("java.security.krb5.kdc", "freeipa.com");// kdc的ip
System.setProperty("java.security.krb5.realm", "COM");// realm
System.setProperty("java.security.krb5.conf", "D:\\etl\\krb5.conf");
conf.set("hadoop.security.authentication", "Kerberos");
conf.set("fs.defaultFS", "hdfs://duhai.com:8020");
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab("duhai@COM", "D:\\etl\\duhai.keytab");// 在kdc中增加的认证名称和生成的keytab
}
public static void main(final String[] args) throws IOException {
HdfsKerberosTest2 test = new HdfsKerberosTest2();
test.list();
}
}
|