Kerberos:Spark UGI 凭据未传递到 Hive
Kerberos: Spark UGI credentials are not getting passed down to Hive
我正在使用 Spark-2.4,我有一个启用了 Kerberos 的集群,我正在尝试通过 spark-sql
shell 运行 查询。
简化的设置基本上是这样的:spark-sql shell 运行ning on a host in a Yarn cluster -> external hive-metastore 运行ning一台主机 -> S3 来存储 table 数据。
当我在启用 DEBUG 日志记录的情况下启动 spark-sql
shell 时,这是我在日志中看到的内容:
> bin/spark-sql --proxy-user proxy_user
...
DEBUG HiveDelegationTokenProvider: Getting Hive delegation token for proxy_user against hive/_HOST@REALM.COM at thrift://hive-metastore:9083
DEBUG UserGroupInformation: PrivilegedAction as:spark/spark_host@REALM.COM (auth:KERBEROS) from:org.apache.spark.deploy.security.HiveDelegationTokenProvider.doAsRealUser(HiveDelegationTokenProvider.scala:130)
这意味着 Spark 进行了调用以从 Hive 元存储中获取委托令牌,然后将其添加到 UGI 的凭据列表中。 This is the piece of code 在 Spark 中执行此操作。我还在 Metastore 日志中验证了正在进行 get_delegation_token()
调用。
现在,当我 运行 一个像 create table test_table (id int) location "s3://some/prefix";
这样的简单查询时,我遇到了 AWS 凭据错误。我修改了 hive metastore 代码并在 Hadoop 中的文件系统初始化之前添加了它 (org/apache/hadoop/hive/metastore/Warehouse.java):
public static FileSystem getFs(Path f, Configuration conf) throws MetaException {
...
try {
// get the current user
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
LOG.info("UGI information: " + ugi);
Collection<Token<? extends TokenIdentifier>> tokens = ugi.getCredentials().getAllTokens();
// print all the tokens it has
for(Token token : tokens) {
LOG.info(token);
}
} catch (IOException e) {
e.printStackTrace();
}
...
}
在 Metastore 日志中,这确实打印了正确的 UGI 信息:
UGI information: proxy_user (auth:PROXY) via hive/hive-metastore@REALM.COM (auth:KERBEROS)
但是 UGI 中没有标记。看起来 Spark code 用别名 hive.server2.delegation.token
添加了它,但我在 UGI 中没有看到它。这让我怀疑 UGI 范围以某种方式被隔离并且没有在 spark-sql 和 hive metastore 之间共享。我该如何解决这个问题?
Spark 不 获取您的 Kerberos 身份 - 它要求每个 FS 发出一些 "delegation token" 让调用者与该服务交互 并且仅此一项服务。这更受限制,因此更安全。
这里的问题是 spark 从可以发布它们的每个文件系统收集委托令牌 - 由于您的 S3 连接器没有发布任何东西,所以没有任何东西下来。
现在,Apache Hadoop 3.3.0 的 S3A 连接器可以设置为在委托令牌内发布您的 AWS 凭证,或者,为了额外的安全性,向 AWS 询问会话凭证并仅发送那些。但是 (a) 您需要一个具有这些依赖项的 spark 构建,并且 (b) Hive 需要使用这些凭据来与 S3 通信。
我正在使用 Spark-2.4,我有一个启用了 Kerberos 的集群,我正在尝试通过 spark-sql
shell 运行 查询。
简化的设置基本上是这样的:spark-sql shell 运行ning on a host in a Yarn cluster -> external hive-metastore 运行ning一台主机 -> S3 来存储 table 数据。
当我在启用 DEBUG 日志记录的情况下启动 spark-sql
shell 时,这是我在日志中看到的内容:
> bin/spark-sql --proxy-user proxy_user
...
DEBUG HiveDelegationTokenProvider: Getting Hive delegation token for proxy_user against hive/_HOST@REALM.COM at thrift://hive-metastore:9083
DEBUG UserGroupInformation: PrivilegedAction as:spark/spark_host@REALM.COM (auth:KERBEROS) from:org.apache.spark.deploy.security.HiveDelegationTokenProvider.doAsRealUser(HiveDelegationTokenProvider.scala:130)
这意味着 Spark 进行了调用以从 Hive 元存储中获取委托令牌,然后将其添加到 UGI 的凭据列表中。 This is the piece of code 在 Spark 中执行此操作。我还在 Metastore 日志中验证了正在进行 get_delegation_token()
调用。
现在,当我 运行 一个像 create table test_table (id int) location "s3://some/prefix";
这样的简单查询时,我遇到了 AWS 凭据错误。我修改了 hive metastore 代码并在 Hadoop 中的文件系统初始化之前添加了它 (org/apache/hadoop/hive/metastore/Warehouse.java):
public static FileSystem getFs(Path f, Configuration conf) throws MetaException {
...
try {
// get the current user
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
LOG.info("UGI information: " + ugi);
Collection<Token<? extends TokenIdentifier>> tokens = ugi.getCredentials().getAllTokens();
// print all the tokens it has
for(Token token : tokens) {
LOG.info(token);
}
} catch (IOException e) {
e.printStackTrace();
}
...
}
在 Metastore 日志中,这确实打印了正确的 UGI 信息:
UGI information: proxy_user (auth:PROXY) via hive/hive-metastore@REALM.COM (auth:KERBEROS)
但是 UGI 中没有标记。看起来 Spark code 用别名 hive.server2.delegation.token
添加了它,但我在 UGI 中没有看到它。这让我怀疑 UGI 范围以某种方式被隔离并且没有在 spark-sql 和 hive metastore 之间共享。我该如何解决这个问题?
Spark 不 获取您的 Kerberos 身份 - 它要求每个 FS 发出一些 "delegation token" 让调用者与该服务交互 并且仅此一项服务。这更受限制,因此更安全。
这里的问题是 spark 从可以发布它们的每个文件系统收集委托令牌 - 由于您的 S3 连接器没有发布任何东西,所以没有任何东西下来。
现在,Apache Hadoop 3.3.0 的 S3A 连接器可以设置为在委托令牌内发布您的 AWS 凭证,或者,为了额外的安全性,向 AWS 询问会话凭证并仅发送那些。但是 (a) 您需要一个具有这些依赖项的 spark 构建,并且 (b) Hive 需要使用这些凭据来与 S3 通信。