如何在 Spark 中使用 Hadoop 凭据提供程序连接到 Oracle 数据库?

Posted

技术标签:

【中文标题】如何在 Spark 中使用 Hadoop 凭据提供程序连接到 Oracle 数据库?【英文标题】:How to use Hadoop Credential provider in Spark to connect to Oracle database? 【发布时间】:2017-12-12 11:15:10 【问题描述】:

我正在尝试在 Spark 和 Oracle 以及 Sqoop 和 Oracle 之间建立安全连接。经过研究,我发现两种不同设置的两种不同选项。

    将 Spark 连接到 Oracle,其中密码使用 spark.jdbc.b64password 进行加密,并已在 spark 代码中解密并在 jdbc url 中使用。 使用 Hadoop 凭据提供程序创建密码文件,并进一步在 Sqoop 中用于连接到 Oracle。

现在将密码保存在两个不同的文件中似乎不是一个好习惯。我的问题是我们可以在 spark 中使用 Hadoop 凭证提供程序来使用为 Sqoop 创建的相同凭证配置文件吗?

如果您有任何其他选择可以使这更好,请提供帮助。

【问题讨论】:

关于选项 2,您可以使用 jceks 密钥库,但您必须从中获取纯字符串形式的密码并将其添加到您的 JDBC URL。此外,它还将在 Spark 计划中可见。 【参考方案1】:

推荐的方法是在 Spark 和 Hadoop 以及 Oracle 中使用 Kerberos 身份验证。 Oracle JDBC 瘦驱动程序支持 Kerberos 身份验证。然后使用单个 Kerberos 主体对从 Spark 或 Hadoop 到 Oracle 数据库的用户进行身份验证。

【讨论】:

感谢您的回答。我是 spark 新手,如果您能提供有关如何实现 kerberos 身份验证的更多详细信息,那就太好了? 您可以先看看这些文档cloudera.com/documentation/enterprise/5-5-x/topics/… 和docs.oracle.com/en/database/oracle/oracle-database/12.2/jjdbc/…。【参考方案2】:

您可以使用 Spark 支持的所有语言从代码中读取 jecks 密码:

Python:

spark1 = SparkSession.builder.appName("xyz").master("yarn").enableHiveSupport().config("hive.exec.dynamic.partition", "true").config("hive.exec.dynamic.partition.mode", "nonstrict").getOrCreate()
x = spark1.sparkContext._jsc.hadoopConfiguration()
x.set("hadoop.security.credential.provider.path", "jceks://file///localpathtopassword")
a = x.getPassword("<password alias>")
passw = ""
for i in range(a.__len__()):
   passw = passw + str(a.__getitem__(i))

在上面的代码中你会得到passw中的密码字符串

斯卡拉:

import org.apache.hadoop.security.alias.CredentialProvider
import org.apache.hadoop.security.alias.CredentialProvider.CredentialEntry
import org.apache.hadoop.security.alias.CredentialProviderFactory
import org.apache.hadoop.conf.Configuration


val conf_H: Configuration = new org.apache.hadoop.conf.Configuration()
val alias = password_alias
val jceksPath = security_credential_provider_path`enter code here`
conf_H.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, jceksPath)
val pass = conf_H.getPassword(alias).mkString
if (pass != null && !pass.isEmpty() && !pass.equalsIgnoreCase("")) 
      jdbcPassword = pass

【讨论】:

【参考方案3】:

你也可以允许 spark 在 hadoop 配置中设置hadoop.security.credential.provider.path

"""
Create java key store with following command:
> keytool -genseckey -alias duke -keypass 123456 -storetype jceks -keystore keystore.jceks
> export HADOOP_CREDSTORE_PASSWORD=123456
"""
jceks = os.path.join(os.path.dirname(__file__), "keystore.jceks")
print(jceks)
assert os.path.isfile(jceks)

spark_session = lambda: (SparkSession
                         .builder
                         .enableHiveSupport()
                         .config('spark.ui.enabled', False)
                         .config("spark.hadoop.hadoop.security.credential.provider.path",
                                 "jceks://file//" + jceks)
                         .getOrCreate())
with spark_session() as spark:
    hc = spark.sparkContext._jsc.hadoopConfiguration()
    jo = hc.getPassword("duke")
        
    expected_password = ''.join(jo)
        
    assert len(retrieved_password) > 0

spark.hadoop.hadoop.security.credential.provider.path 有点奇怪,但 spark 会在加载 hadoop 设置时切断spark.hadoop. 前缀

【讨论】:

以上是关于如何在 Spark 中使用 Hadoop 凭据提供程序连接到 Oracle 数据库?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Apache Spark 访问 s3a:// 文件?

如何在现有的 Hadoop 2.x 中使用 spark

如何在Spark提交中使用s3a和Apache spark 2.2(hadoop 2.8)?

如何在 Spark Submit 中将 s3a 与 Apache spark 2.2(hadoop 2.8) 一起使用?

如何获取hadoop mapreduce job运行信息

如何获取hadoop mapreduce job运行信息