Spark RDD.pipe 运行 bash 脚本作为特定用户

Spark RDD.pipe run bash script as a specific user

我注意到 RDD.pipe(Seq("/tmp/test.sh")) 使用用户 yarn 运行 shell 脚本。这是有问题的,因为它允许 spark 用户访问只能由 yarn 用户访问的文件。

解决这个问题的最佳方法是什么?
调用 sudo -u sparkuser 不是一个干净的解决方案。我什至不愿意考虑那个。

我不确定这是否是 Spark 以不同方式对待 Pipe() 的错误,但我在 JIRA 上打开了一个类似的问题:https://issues.apache.org/jira/projects/SPARK/issues/SPARK-26101

现在进入正题。显然,在 YARN 集群中,Spark Pipe() 需要一个容器,您的 Hadoop 是不安全的还是受 Kerberos 保护的,区别在于容器是由用户 yarn/nobody 运行还是由启动容器的用户 your actual user 运行。

要么使用 Kerberos 来保护你的 Hadoop,要么如果你不想通过保护你的 Hadoop,你可以在使用 Linux users/groups 启动容器的 YARN 中设置两个配置. 注意,您必须在集群中的所有节点上共享相同的users/groups。否则,这是行不通的。 (也许使用 LDAP/AD 同步您的 users/groups)

设置这些:

yarn.nodemanager.linux-container-executor.nonsecure-mode.limit-users = false

yarn.nodemanager.container-executor.class = org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor

来源:https://hadoop.apache.org/docs/r2.7.4/hadoop-yarn/hadoop-yarn-site/NodeManagerCgroups.html (即使在 Hadoop 3.0 中也是如此)

此修复适用于 Cloudera 最新的 CDH 5.15.1 (yarn-site.xml): http://community.cloudera.com/t5/Batch-Processing-and-Workflow/YARN-force-nobody-user-on-all-jobs-and-so-they-fail/m-p/82572/highlight/true#M3882

示例:

val test = sc.parallelize(Seq("test user")).repartition(1)

val piped = test.pipe(Seq("whoami"))

val c = piped.collect()

est: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[4] at repartition at <console>:25
piped: org.apache.spark.rdd.RDD[String] = PipedRDD[5] at pipe at <console>:25
c: Array[String] = Array(maziyar)

这将 return 在 yarn-site.xml 中设置这些配置后启动 Spark 会话的 username 并在所有节点之间同步所有 users/groups。