https://www.psvmc.cn/article/2022-11-08-bigdata-kerberos-centos.html
flink on yarn
flink run \
-yD security.kerberos.login.keytab=/root/psvmc.keytab \
-yD security.kerberos.login.principal=psvmc/hadoop@HADOOP.COM \
yxzt-data-tcs-1.0-SNAPSHOT-jar-with-dependencies.jar -job /root/zjhome/test.json
Принцип сертификации
Требуется два файла
krb5.conf
krb5.keytab
,Обычно получается после генерации сервером.вставитьresources
в каталоге
Укажите файл конфигурации krb5: krb5.conf, замените в соответствии с реальной ситуацией.
Файл аутентификации: krb5.keytab, замените в соответствии с реальной ситуацией.
Аутентификация пользователя: куст, измените в соответствии с реальной ситуацией.
Здесь файл конфигурации и файл аутентификации копируются во временный каталог для аутентификации. При необходимости вы можете указать фиксированный каталог для аутентификации.
Метод аутентификацииKerberosAuth.java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
public class KerberosAuth {
private static final Logger log = LoggerFactory.getLogger(KerberosAuth.class);
// Файл конфигурации Kerberos, полученный из сервиса
private static final String krbConfig = "krb5.conf";
// kerberosСертификациядокумент private static final String krbKeytab = "psvmc.keytab";
// kerberosСертификацияпользователь private static final String principal = "psvmc/hadoop@HADOOP.COM";
public static void init() {
initkerberos();
}
public static void initkerberos() {
log.info("Kerberos Проверка входа");
try {
// Временный каталог Java, окно — C:\Users\login user\AppData\Local\Temp\, Linux — /tmp, вам нужно добавить косую черту в зависимости от ситуации.
String javaTempDir = System.getProperty("java.io.tmpdir");
String tempDir = Paths.get(javaTempDir, "krb_" + System.currentTimeMillis()).toString();
String configPath = getTempPath(tempDir, krbConfig);
String keytabPath = getTempPath(tempDir, krbKeytab);
log.error(configPath);
log.error(keytabPath);
System.setProperty("java.security.krb5.conf", configPath); //Установите путь к файлу krbConfiguration. Обратите внимание, что он должен быть указан перед Configuration, иначе он не вступит в силу.
Configuration conf = new Configuration();
conf.set("hadoop.security.authentication","Kerberos");//настраивать СертификациямодельKerberos UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(основной, keytabPath);//Установить путь к пользователю Сертификации и пути к файлу Сертификации krb
log.error("Kerberos Проверка прошла успешно");
} catch (Exception e) {
log.error("Kerberos Проверка не удалась", e);
}
}
/**
* скопировать файл и получить путь к файлу на основе имени файла (решить проблему, связанную с тем, что пакет jar не поддерживает получение файлов из ресурса)
*
* @param tempPath временный каталог
* @param fileName Имя файла
* @return Временный путь к файлу
*/
@SuppressWarnings("ResultOfMethodCallIgnored")
public static String getTempPath(String tempPath, String fileName) {
InputStream in = KerberosAuth.class.getResourceAsStream("/" + fileName);
String pathAll = tempPath + File.separator + fileName;
File file = new File(pathAll);
File tempPathFile = new File(tempPath);
if (!tempPathFile.exists()) {
tempPathFile.mkdirs();
}
try {
copyInputStreamToFile(in, pathAll);
} catch (Exception e) {
log.error("getTempPath", e);
}
return file.getPath();
}
private static void copyInputStreamToFile(InputStream is, String strFileFullPath) throws IOException {
long size = 0;
BufferedInputStream in = new BufferedInputStream(is);
BufferedOutputStream out = new BufferedOutputStream(Files.newOutputStream(Paths.get(strFileFullPath)));
int len = -1;
byte[] b = new byte[1024];
while ((len = in.read(b)) != -1) {
out.write(b, 0, len);
size += len;
}
in.close();
out.close();
//Изменяем права доступа к файлу
changeFolderPermission(strFileFullPath);
}
private static void changeFolderPermission(String dirPath) {
File dirFile = new File(dirPath);
dirFile.setReadable(true, false);
dirFile.setExecutable(true, false);
dirFile.setWritable(true, false);
}
public static void main(String[] args) {
KerberosAuth.init();
}
}
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.*;
public class KerberosAuthServer {
private static final Logger log = LoggerFactory.getLogger(KerberosAuthServer.class);
public static boolean initkerberos(String principal, String keytabPath) {
log.info("Kerberos Проверка входа");
try {
log.error(principal);
log.error(keytabPath);
Configuration conf = new Configuration();
conf.set("hadoop.security.authentication","Kerberos");//настраивать СертификациямодельKerberos UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(основной, keytabPath);//Установить путь к пользователю Сертификации и пути к файлу Сертификации krb
log.error("Kerberos Проверка прошла успешно");
return true;
} catch (Exception e) {
log.error("Kerberos Проверка не удалась", e);
return false;
}
}
private static void connectHive() throws SQLException, ClassNotFoundException {
Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection connection = DriverManager
.getConnection("jdbc:hive2://hadoop01:10000/zdb;principal=hdfs/hadoop01@HADOOP.COM");
PreparedStatement ps = connection.prepareStatement("show databases");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getString(1));
}
rs.close();
ps.close();
connection.close();
}
public static void main(String[] args) throws SQLException, ClassNotFoundException {
boolean isAuth = KerberosAuthServer.initkerberos("hdfs/hadoop01@HADOOP.COM", "/data/tools/bigdata/kerberos/hdfs.keytab");
if (isAuth) {
connectHive();
}
}
}
Hiveсередина Конфигурация Проверка подлинности После Кербероса,JDBC-соединениепродолжитьkerberosСертификация。
После аутентификации в URL-адрес JDBC также необходимо добавить конфигурации, связанные с аутентификацией.
следующее
jdbc:hive2://192.168.7.101:10000/zdb;principal=psvmc/hadoop@HADOOP.COM
в
principal:
Инструменты
import com.gientech.schedule.config.KerberosConnect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.*;
import java.util.*;
public class HiveUtils {
private static Logger logger = LoggerFactory.getLogger(HiveUtils.class.getName());
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
private static String url = "jdbc:hive2://192.168.7.101:10000/zdb;principal=psvmc/hadoop@HADOOP.COM";//Порт по умолчанию — 10000
/**
* GetConnection
* @return conn
* @throws SQLException
* @throws ClassNotFoundException
*/
public static Connection getConnection() throws SQLException {
Connection conn = null;
try {
KerberosAuth.init();
conn = DriverManager.getConnection(url);
} catch (SQLException e) {
logger.info("Не удалось подключиться к базе данных!");
throw e;
}
return conn;
}
// Создать базу данных
public static void createDatabase(String databaseName) throws Exception {
String sql = "create database "+databaseName;
logger.info("Running: " + sql);
Connection conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(sql);
closeConnection(conn);
closeStatement(stmt);
}
// Все базы данных Запрос
public static void showDatabases() throws Exception {
String sql = "show databases";
logger.info("Running: " + sql);
Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
logger.info(rs.getString(1));
}
closeConnection(rs,stmt,conn);
}
/**
* Создать таблицу (разделитель «,»)
* Такие как создать table tableName(name string,sex string) row format delimited fields terminated by ','
* @param sql
* @throws Exception
*/
public static void createTable(String sql) throws Exception {
logger.info("Running: " + sql);
Connection conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(sql);
closeConnection(conn);
closeStatement(stmt);
}
// Запрос Все таблицы
public static void showTables() throws Exception {
String sql = "show tables";
logger.info("Running: " + sql);
getConnection();
Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
logger.info(rs.getString(1));
}
closeConnection(rs,stmt,conn);
}
// Посмотреть структуру таблицы
public static void descTable(String tableName) throws Exception {
String sql = "desc formatted "+tableName;
logger.info("Running: " + sql);
Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
logger.info(rs.getString(1) + "\t" + rs.getString(2));
}
closeConnection(rs,stmt,conn);
}
// Загрузить данные (убедитесь, что у вас есть права доступа к файлу)
public static void loadData(String filePath,String tableName) throws Exception {
String sql = "load data inpath '" + filePath + "' into table tableName";
logger.info("Running: " + sql);
Connection conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(sql);
closeConnection(conn);
closeStatement(stmt);
}
// Данные запроса
public static void selectData(String sql) throws Exception {
logger.info("Running: " + sql);
Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
rs = stmt.executeQuery(sql);
while (rs.next()) {
logger.info(rs.getString(1));
}
closeConnection(rs,stmt,conn);
}
// Удалить базу данных
public static void dropDatabase(String databaseName) throws Exception {
String sql = "drop database if exists "+databaseName;
logger.info("Running: " + sql);
Connection conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(sql);
closeConnection(conn);
closeStatement(stmt);
}
// Удалить базу данныхповерхность
public static void deopTable(String tableName) throws Exception {
String sql = "drop table if exists "+tableName;
logger.info("Running: " + sql);
Connection conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(sql);
closeConnection(conn);
closeStatement(stmt);
}
public static Map<String,Object> queryMapBySql(String sql){
//Определяем соединение базы данных
Connection conn = null;
//Определяем объект ReadedStatement
PreparedStatement ps = null;
//Определяем набор результатов Запроса
ResultSet rs = null;
try {
conn = getConnection();
//Определяем оператор sql, который будет выполнен
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
return getMapFromResultSet(rs);
} catch (Exception e) {
logger.info("queryDataListBySql"+e.getMessage());
}finally {
closeConnection(rs,ps,conn);
}
return Collections.emptyMap();
}
/**
* Закрыть набор результатов, оператор, соединение
*
* @param rs
* @param stmt
* @param con
*/
public static void closeConnection(ResultSet rs, Statement stmt, Connection con) {
closeResultSet(rs);
closeStatement(stmt);
closeConnection(con);
}
/**
* Закрыть набор результатов
*
* @param rs
*/
public static void closeResultSet(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
logger.info(e.getMessage());
}
}
}
/**
* CloseStatement
*
* @param stmt
*/
public static void closeStatement(Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (Exception e) {
logger.info(e.getMessage());
}
}
}
/**
* Закрыть соединение
*
* @param con
*/
public static void closeConnection(Connection con) {
if (con != null) {
try {
con.close();
} catch (Exception e) {
logger.info(e.getMessage());
}
}
}
/**
* Преобразование результата набора результатов в sonObject
* @param rs ResultSet
* @return List
* @throws SQLException аномальный
*/
public static Map<String,Object> getMapFromResultSet(ResultSet rs)
throws SQLException {
Map<String,Object> hm = new HashMap();
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();// Получить количество столбцов
while(rs.next()) {
for (int i = 1; i <= count; i++) {
String key = rsmd.getColumnLabel(i);
Object value = rs.getObject(i);
hm.put(key, value);
}
}
return hm;
}
public static List<Map<String,Object>> queryListBySql(String sql){
//Определяем соединение базы данных
Connection conn = null;
//Определяем объект ReadedStatement
PreparedStatement ps = null;
//Определяем набор результатов Запроса
ResultSet rs = null;
try {
conn = getConnection();
//Определяем оператор sql, который будет выполнен
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
return getListFromResultSet(rs);
} catch (Exception e) {
logger.info("queryDataListBySql"+e.getMessage());
}finally {
closeConnection(rs,ps,conn);
}
return Collections.emptyList();
}
/**
* Преобразование результатов набора результатов в список
* @param rs ResultSet
* @return List
* @throws SQLException аномальный
*/
private static List<Map<String,Object>> getListFromResultSet(ResultSet rs)
throws SQLException {
List<Map<String,Object>> results= new ArrayList<>();//Данные результата
ResultSetMetaData metaData = rs.getMetaData(); // Получить результаты столбца
List<String> colNameList= new ArrayList<>();
int cols_len = metaData.getColumnCount(); // Получить общее количество столбцов
for (int i = 0; i < cols_len; i++) {
colNameList.add(metaData.getColumnName(i+1));
}
while (rs.next()) {
Map<String, Object> map= new HashMap<>();
for(int i=0;i<cols_len;i++){
String key=colNameList.get(i);
Object value=rs.getString(colNameList.get(i));
map.put(key, value);
}
results.add(map);
}
return results;
}
public static void main(String[] args) throws Exception {
String sql = "SELECT * FROM `t1` LIMIT 1";
List<Map<String, Object>> maps = queryListBySql(sql);
logger.info(maps.toString());
}
}
Сертификация
kinit -kt /data/tools/bigdata/kerberos/hdfs.keytab hdfs/hadoop01@HADOOP.COM
Посмотреть статус сертификации
klist
существовать Тест на сервере
hive
Использование JDBC
До
beeline -n hive -u jdbc:hive2://hadoop01:10000/default
УведомлениеОбязательно добавьте двойные кавычки, иначе оно будет недействительным.
установить в конфигурации
beeline -n hive -u "jdbc:hive2://hadoop01:10000/zdb;principal=hdfs/hadoop01@HADOOP.COM"
В настоящее время подключаться могут только пользователи, указанные в файле конфигурации.
Запрос
show databases;
public class ZRuntimeException extends RuntimeException {
public ZRuntimeException(String format, Object... objs) {
super(String.format(format, objs));
}
}
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
public class ZLoadConfig {
public static String getHadoopConfigRootPath() {
String conf = System.getenv("HADOOP_CONF_DIR");
if (conf == null) {
String hh = System.getenv("HADOOP_HOME");
if (hh == null) {
throw new ZRuntimeException("Файл конфигурации не найден");
}
conf = hh + "/etc/hadoop";
}
return conf;
}
public static String getZKConfigRootPath() {
String conf = System.getenv("ZK_HOME");
if (conf != null) {
conf += "/conf";
}
return conf;
}
public static String getHbaseConfigRootPath() {
String conf = System.getenv("HBASE_HOME");
if (conf != null) {
conf += "/conf";
}
return conf;
}
public static Configuration loadHDFS() throws ZRuntimeException {
String conf = getHadoopConfigRootPath();
Configuration config = new Configuration();
config.addResource(new Path(conf + "/core-site.xml"));
config.addResource(new Path(conf + "/hdfs-site.xml"));
return config;
}
public static YarnConfiguration loadYarn() throws ZRuntimeException {
String conf = getHadoopConfigRootPath();
YarnConfiguration config = new YarnConfiguration();
config.addResource(new Path(conf + "/core-site.xml"));
config.addResource(new Path(conf + "/hdfs-site.xml"));
config.addResource(new Path(conf + "/yarn-site.xml"));
return config;
}
public static Configuration loadHbase() {
String hadoopConfPath = getHadoopConfigRootPath();
String hbaseConfPath = getHbaseConfigRootPath();
Configuration config = HBaseConfiguration.create();
config.addResource(new Path(hadoopConfPath + "/core-site.xml"));
config.addResource(new Path(hadoopConfPath + "/hdfs-site.xml"));
config.addResource(new Path(hadoopConfPath + "/yarn-site.xml"));
config.addResource(new Path(hbaseConfPath += "/hbase-site.xml"));
return config;
}
}
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Properties;
import javax.security.auth.login.LoginContext;
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.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.yarn.api.records.ApplicationReport;
import org.apache.hadoop.yarn.client.api.YarnClient;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
public class ZKerberosUtil {
public static void loginZK() {
try {
// Настройка службы сертификации удостоверений Конфигурация
System.setProperty("java.security.auth.login.config", ZLoadConfig.getZKConfigRootPath() + "/jaas.conf");
// Авторизуйтесь с помощью модуля в сервисе Сертификация удостоверений Конфигурация
LoginContext context = new LoginContext("Client");
context.login();
// Создайте клиент zk и создайте наблюдателя.
ZooKeeper zk = new ZooKeeper("hadoop01:2181", 5000, new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println(event.getPath() + " : " + event.getState().toString());
}
});
while (zk.getState() != ZooKeeper.States.CONNECTED) {
Thread.sleep(500);
}
System.out.println("соединятьприезжатьzk"); List<String> ss = zk.getChildren("/", true);
ss.forEach((s) -> {
System.out.println(s);
});
zk.close();
context.logout();
} catch (Exception e) {
// иметь дело саномальный
e.printStackTrace();
}
}
public static boolean initkerberos(String principal, String keytabPath) {
try {
Configuration conf = new Configuration();
conf.set("hadoop.security.authentication","Kerberos");//настраивать СертификациямодельKerberos UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(основной, keytabPath);//Установить путь к пользователю Сертификации и пути к файлу Сертификации krb
System.out.println("Kerberos Проверка прошла успешно");
return true;
} catch (Exception e) {
System.out.println("Kerberos Проверка не удалась" + e.getMessage());
return false;
}
}
public static void loginHdfs(String principal, String keytabPath) throws IOException {
Configuration conf = ZLoadConfig.loadHDFS();
System.out.println(conf.get("fs.defaultFS"));
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(principal, keytabPath);
FileSystem fs = FileSystem.get(conf);
FileStatus[] fsStatus = fs.listStatus(new Path("/"));
for (FileStatus st : fsStatus) {
System.out.println(st.getPath());
}
}
public static void loginYarn(String principal, String keytabPath) throws IOException, YarnException {
YarnConfiguration conf = ZLoadConfig.loadYarn();
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(principal, keytabPath);
YarnClient yc = YarnClient.createYarnClient();
yc.init(conf);
yc.start();
List<ApplicationReport> applications = yc.getApplications();
applications.forEach((a) -> {
System.out.println(a.getApplicationId());
});
yc.close();
}
public static void loginHive(String principal, String keytabPath) throws SQLException, IOException, ClassNotFoundException {
Configuration conf = ZLoadConfig.loadHDFS();
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(
principal,
keytabPath
);
Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection connection = DriverManager
.getConnection("jdbc:hive2://hadoop01:10000/yxdp_ys;principal=hdfs/hadoop01@HADOOP.COM");
PreparedStatement ps = connection.prepareStatement("show databases");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getString(1));
}
rs.close();
ps.close();
connection.close();
}
public static void loginHbase(String principal, String keytabPath) throws IOException, SQLException {
Configuration conf = ZLoadConfig.loadHbase();
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(
principal,
keytabPath
);
org.apache.hadoop.hbase.client.Connection con = ConnectionFactory.createConnection(conf);
NamespaceDescriptor[] nds = con.getAdmin().listNamespaceDescriptors();
for (NamespaceDescriptor nd : nds) {
System.out.println(nd.getName());
}
}
public static void loginPhoenix(String principal, String keytabPath) throws IOException, ClassNotFoundException, SQLException {
Configuration conf = ZLoadConfig.loadHbase();
Properties prop = new Properties();
conf.getValByRegex(".*?").forEach(prop::setProperty);
Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
// Строка jdbc Phoenix в среде Kerberos: jdbc:phoenix:zk:2181:/znode:principal:keytab
String url = "jdbc:phoenix:hadoop01,hadoop02,hadoop03:/hbase:" + principal + ":" + keytabPath;
PhoenixConnection con = DriverManager.getConnection(url, prop).unwrap(PhoenixConnection.class);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM SYSTEM.CATALOG");
int n = rs.getMetaData().getColumnCount();
for (int i = 0; i < n; i++) {
String cn = rs.getMetaData().getColumnName(n);
System.out.println(cn);
}
rs.close();
stmt.close();
con.close();
}
}
Во-первых, обратите внимание на настройки нескольких переменных среды при настройке.
Файл конфигурации Сертификация, используемая непосредственно ZK.
jaas.conf
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/data/tools/bigdata/kerberos/hdfs.keytab"
storeKey=true
useTicketCache=false
principal="zookeeper/hadoop01@HADOOP.COM";
};
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/data/tools/bigdata/kerberos/hdfs.keytab"
storeKey=true
useTicketCache=false
principal="cli@HADOOP.COM";
};
HDFS, YARN, Hive и Hbase используют сертификацию Hadoop.
Phoenix использует форму толстого клиента — Сертификат.