Spark 安全

Spark 安全:你需要知道的事

默认情况下不会启用身份验证等安全功能。在部署开放给互联网或不受信任网络的集群时,重要的是要保护对集群的访问,以防止未经授权的应用程序在集群上运行。

Spark 支持多种部署类型,每种类型都支持不同级别的安全。并非所有部署类型在所有环境中都是安全的,并且默认情况下都不安全。请务必评估您的环境、Spark 支持的内容,并采取适当的措施来保护您的 Spark 部署。

存在许多不同类型的安全问题。Spark 不一定能防止所有问题。下面列出了一些 Spark 支持的内容。此外,请查看您正在使用的部署类型的部署文档,以了解特定于部署的设置。任何未记录的内容,Spark 都不支持。

Spark RPC(Spark 进程之间的通信协议)

身份验证

Spark 目前支持使用共享密钥对 RPC 通道进行身份验证。可以通过设置 spark.authenticate 配置参数来启用身份验证。

用于生成和分发共享密钥的确切机制是特定于部署的。除非在下面指定,否则必须通过设置 spark.authenticate.secret 配置选项来定义密钥。在这种情况下,所有 Spark 应用程序和守护程序共享相同的密钥,这限制了这些部署的安全性,尤其是在多租户集群上。

REST 提交服务器和 MesosClusterDispatcher 不支持身份验证。您应该确保对 REST API 和 MesosClusterDispatcher(默认情况下分别为端口 6066 和 7077)的所有网络访问都限制在被信任提交作业的主机上。

YARN

对于在 YARN 上运行的 Spark,Spark 将自动处理生成和分发共享密钥。每个应用程序将使用唯一的共享密钥。在 YARN 的情况下,此功能依赖于 YARN RPC 加密,以确保密钥分发的安全性。

属性名称默认值含义自版本
spark.yarn.shuffle.server.recovery.disabled false 对于具有更高安全要求并希望其密钥不保存在数据库中的应用程序,将其设置为 true。此类应用程序的混洗数据在外部混洗服务重新启动后将不会恢复。 3.5.0

Kubernetes

在 Kubernetes 上,Spark 还将自动生成一个对每个应用程序唯一的身份验证密钥。该密钥使用环境变量传播到执行器 Pod。这意味着任何可以列出 Spark 应用程序运行的命名空间中的 Pod 的用户也可以看到其身份验证密钥。Kubernetes 管理员应正确设置访问控制规则,以确保 Spark 身份验证是安全的。

属性名称默认值含义自版本
spark.authenticate false Spark 是否对其内部连接进行身份验证。 1.0.0
spark.authenticate.secret 用于身份验证的密钥。有关何时应设置此配置,请参见上文。 1.0.0

或者,可以使用文件和 Kubernetes 密钥来挂载身份验证密钥,用户将其挂载到其 Pod 中。

属性名称默认值含义自版本
spark.authenticate.secret.file 指向用于保护连接的密钥文件的路径。确保文件的内容已安全生成。此文件在驱动程序和执行器上加载,除非其他设置覆盖此设置(见下文)。 3.0.0
spark.authenticate.secret.driver.file spark.authenticate.secret.file 的值 当指定时,将覆盖 Spark 驱动程序读取以加载密钥的位置。在客户端模式下很有用,此时密钥文件的位置可能在 Pod 与驱动程序运行的节点之间有所不同。当指定此设置时,必须指定 spark.authenticate.secret.executor.file,以便驱动程序和执行器都可以使用文件来加载密钥。确保驱动程序上的文件内容与执行器上的文件内容相同。 3.0.0
spark.authenticate.secret.executor.file spark.authenticate.secret.file 的值 当指定时,将覆盖 Spark 执行器读取以加载密钥的位置。在客户端模式下很有用,此时密钥文件的位置可能在 Pod 与驱动程序运行的节点之间有所不同。当指定此设置时,必须指定 spark.authenticate.secret.driver.file,以便驱动程序和执行器都可以使用文件来加载密钥。确保驱动程序上的文件内容与执行器上的文件内容相同。 3.0.0

请注意,在使用文件时,Spark 不会将这些文件挂载到容器中。您需要确保密钥文件已安全部署到您的容器中,并且驱动程序的密钥文件与执行器的密钥文件一致。

加密

Spark 支持对 RPC 连接进行基于 AES 的加密。要启用加密,还必须启用 RPC 身份验证并正确配置。AES 加密使用 Apache Commons Crypto 库,Spark 的配置系统允许高级用户访问该库的配置。

还支持基于 SASL 的加密,但应将其视为已弃用。在与早于 2.2.0 版本的 Spark 版本的混洗服务通信时,它仍然是必需的。

下表描述了用于配置此功能的不同选项。

属性名称默认值含义自版本
spark.network.crypto.enabled false 启用基于 AES 的 RPC 加密,包括在 2.2.0 中添加的新身份验证协议。 2.2.0
spark.network.crypto.config.* commons-crypto 库的配置值,例如要使用的密码实现。配置名称应为 commons-crypto 配置的名称,不带 commons.crypto 前缀。 2.2.0
spark.network.crypto.saslFallback true 如果使用 Spark 的内部机制进行身份验证失败,是否回退到 SASL 身份验证。这在应用程序连接到不支持内部 Spark 身份验证协议的旧混洗服务时很有用。在混洗服务端,禁用此功能将阻止旧客户端进行身份验证。 2.2.0
spark.authenticate.enableSaslEncryption false 启用基于 SASL 的加密通信。 2.2.0
spark.network.sasl.serverAlwaysEncrypt false 禁用使用 SASL 身份验证的端口的未加密连接。这将拒绝来自启用了身份验证但未请求基于 SASL 的加密的客户端的连接。 1.4.0

本地存储加密

Spark 支持加密写入本地磁盘的临时数据。这包括混洗文件、混洗溢出和存储在磁盘上的数据块(用于缓存和广播变量)。它不包括加密使用 saveAsHadoopFilesaveAsTable 等 API 生成的输出数据。它也可能不包括用户显式创建的临时文件。

以下设置涵盖了启用对写入磁盘的数据进行加密

属性名称默认值含义自版本
spark.io.encryption.enabled false 启用本地磁盘 I/O 加密。目前所有模式都支持,除了 Mesos。强烈建议在使用此功能时启用 RPC 加密。 2.1.0
spark.io.encryption.keySizeBits 128 IO 加密密钥大小(以位为单位)。支持的值为 128、192 和 256。 2.1.0
spark.io.encryption.keygen.algorithm HmacSHA1 生成 IO 加密密钥时要使用的算法。支持的算法在 Java 密码体系结构标准算法名称文档的 KeyGenerator 部分中描述。 2.1.0
spark.io.encryption.commons.config.* commons-crypto 库的配置值,例如要使用的密码实现。配置名称应为 commons-crypto 配置的名称,不带 commons.crypto 前缀。 2.1.0

Web UI

身份验证和授权

对 Web UI 启用身份验证是使用 javax servlet 过滤器 完成的。您将需要一个实现您要部署的身份验证方法的过滤器。Spark 没有提供任何内置的身份验证过滤器。

当存在身份验证过滤器时,Spark 还支持对 UI 的访问控制。每个应用程序都可以配置自己的单独访问控制列表 (ACL)。Spark 区分“查看”权限(谁可以查看应用程序的 UI)和“修改”权限(谁可以执行诸如终止正在运行的应用程序中的作业等操作)。

可以为用户或组配置 ACL。配置条目接受逗号分隔的列表作为输入,这意味着可以为多个用户或组授予所需的权限。如果您在共享集群上运行,并且有一组管理员或开发人员需要监控他们可能没有自己启动的应用程序,则可以使用此功能。添加到特定 ACL 中的通配符 (*) 意味着所有用户都将拥有相应的权限。默认情况下,只有提交应用程序的用户会被添加到 ACL 中。

组成员资格是通过使用可配置的组映射提供程序来建立的。映射器使用 spark.user.groups.mapping 配置选项进行配置,该选项在下面的表格中描述。

以下选项控制 Web UI 的身份验证

属性名称默认值含义自版本
spark.ui.allowFramingFrom SAMEORIGIN 通过 X-Frame-Options 允许对特定命名 URI 进行嵌入。默认情况下,只允许来自同一来源。 1.6.0
spark.ui.filters 有关如何配置过滤器的信息,请参见 Spark UI 配置。 1.0.0
spark.acls.enable false 是否启用 UI ACL。如果启用,则会检查用户是否有权查看或修改应用程序。请注意,这需要用户进行身份验证,因此,如果没有安装身份验证过滤器,此选项将不起作用。 1.1.0
spark.admin.acls 具有查看和修改 Spark 应用程序访问权限的用户列表,以逗号分隔。 1.1.0
spark.admin.acls.groups 具有查看和修改 Spark 应用程序访问权限的组列表,以逗号分隔。 2.0.0
spark.modify.acls 具有修改 Spark 应用程序访问权限的用户列表,以逗号分隔。 1.1.0
spark.modify.acls.groups 具有修改 Spark 应用程序访问权限的组列表,以逗号分隔。 2.0.0
spark.ui.view.acls 具有查看 Spark 应用程序访问权限的用户列表,以逗号分隔。 1.0.0
spark.ui.view.acls.groups 具有查看 Spark 应用程序访问权限的组列表,以逗号分隔。 2.0.0
spark.user.groups.mapping org.apache.spark.security.ShellBasedGroupsMappingProvider 用户的组列表由特征 org.apache.spark.security.GroupMappingServiceProvider 定义的组映射服务确定,该服务可以通过此属性配置。
默认情况下,使用基于 Unix shell 的实现,该实现从主机操作系统收集此信息。
注意:此实现仅支持基于 Unix/Linux 的环境。目前不支持 Windows 环境。但是,可以通过实现上述特征来支持新的平台/协议。
2.0.0

在 YARN 上,查看和修改 ACL 在提交应用程序时提供给 YARN 服务,并通过 YARN 接口控制谁具有相应的权限。

Spark History Server ACL

SHS Web UI 的身份验证与常规应用程序相同,使用 servlet 过滤器启用。

要在 SHS 中启用授权,可以使用一些额外的选项

属性名称默认值含义自版本
spark.history.ui.acls.enable false 指定是否应检查 ACL 以授权用户查看历史服务器中的应用程序。如果启用,则无论各个应用程序为 spark.ui.acls.enable 设置了什么,都会执行访问控制检查。应用程序所有者始终有权查看自己的应用程序,并且在运行应用程序时通过 spark.ui.view.acls 指定的任何用户以及通过 spark.ui.view.acls.groups 指定的组也有权查看该应用程序。如果禁用,则不会对历史服务器提供的任何应用程序 UI 进行访问控制检查。 1.0.1
spark.history.ui.admin.acls 具有查看历史服务器中所有 Spark 应用程序访问权限的用户列表,以逗号分隔。 2.1.1
spark.history.ui.admin.acls.groups 具有查看历史服务器中所有 Spark 应用程序访问权限的组列表,以逗号分隔。 2.1.1

SHS 使用与常规应用程序相同的选项来配置组映射提供程序。在这种情况下,组映射提供程序将应用于 SHS 提供的所有 UI 服务器,并且将忽略各个应用程序配置。

SSL 配置

SSL 的配置按层次结构组织。用户可以配置默认 SSL 设置,这些设置将用于所有支持的通信协议,除非它们被特定于协议的设置覆盖。这样,用户可以轻松地为所有协议提供通用设置,而不会禁用单独配置每个协议的能力。下表描述了 SSL 配置命名空间

配置命名空间 组件
spark.ssl 默认 SSL 配置。这些值将应用于以下所有命名空间,除非在命名空间级别明确覆盖。
spark.ssl.ui Spark 应用程序 Web UI
spark.ssl.standalone 独立 Master/Worker Web UI
spark.ssl.historyServer 历史服务器 Web UI

下面是可用 SSL 选项的完整细分。${ns} 占位符应替换为上述命名空间之一。

属性名称默认值含义
${ns}.enabled false 启用 SSL。启用后,需要 ${ns}.ssl.protocol
${ns}.port SSL 服务将在其中监听的端口。
端口必须在特定命名空间配置中定义。读取此配置时,将忽略默认命名空间。
如果未设置,SSL 端口将从同一服务的非 SSL 端口派生。值为“0”将使服务绑定到一个短暂端口。
${ns}.enabledAlgorithms 以逗号分隔的密码列表。指定的密码必须受 JVM 支持。
可以在 Java 安全指南的“JSSE 密码套件名称”部分找到协议参考列表。Java 8 的列表可以在 页面找到。
注意:如果未设置,将使用 JRE 的默认密码套件。
${ns}.keyPassword 密钥库中私钥的密码。
${ns}.keyStore 密钥库文件的路径。路径可以是绝对路径或相对于进程启动的目录的相对路径。
${ns}.keyStorePassword 密钥库的密码。
${ns}.keyStoreType JKS 密钥库的类型。
${ns}.protocol 要使用的 TLS 协议。协议必须受 JVM 支持。
可以在 Java 安全指南的“其他 JSSE 标准名称”部分找到协议参考列表。对于 Java 8,可以在 页面找到列表。
${ns}.needClientAuth false 是否需要客户端身份验证。
${ns}.trustStore 信任库文件的路径。路径可以是绝对路径或相对于进程启动的目录的相对路径。
${ns}.trustStorePassword 信任库的密码。
${ns}.trustStoreType JKS 信任库的类型。

Spark 还支持从 Hadoop 凭据提供程序 中检索 ${ns}.keyPassword${ns}.keyStorePassword${ns}.trustStorePassword。用户可以将密码存储到凭据文件中,并使其可供不同的组件访问,例如

hadoop credential create spark.ssl.keyPassword -value password \
    -provider jceks://[email protected]:9001/user/backup/ssl.jceks

要配置凭据提供程序的位置,请在 Spark 使用的 Hadoop 配置中设置 hadoop.security.credential.provider.path 配置选项,例如

  <property>
    <name>hadoop.security.credential.provider.path</name>
    <value>jceks://[email protected]:9001/user/backup/ssl.jceks</value>
  </property>

或通过 SparkConf “spark.hadoop.hadoop.security.credential.provider.path=jceks://[email protected]:9001/user/backup/ssl.jceks”。

准备密钥库

密钥库可以通过 keytool 程序生成。Java 8 的此工具的参考文档在 这里。为 Spark 独立部署模式配置密钥库和信任库的最基本步骤如下

YARN 模式

要为在集群模式下运行的驱动程序提供本地信任库或密钥库文件,可以使用 --files 命令行参数(或等效的 spark.files 配置)将它们与应用程序一起分发。这些文件将被放置在驱动程序的工作目录中,因此 TLS 配置应该只引用文件名,没有绝对路径。

以这种方式分发本地密钥库可能需要将文件暂存到 HDFS(或集群使用的其他类似分布式文件系统)中,因此建议将底层文件系统配置为考虑安全性(例如,通过启用身份验证和线缆加密)。

独立模式

用户需要为 master 和 worker 提供密钥库和配置选项。它们必须通过在 SPARK_MASTER_OPTSSPARK_WORKER_OPTS 环境变量中附加适当的 Java 系统属性,或者只在 SPARK_DAEMON_JAVA_OPTS 中设置。

用户可以允许执行器使用从 worker 进程继承的 SSL 设置。这可以通过将 spark.ssl.useNodeLocalConf 设置为 true 来实现。在这种情况下,用户在客户端提供的设置将不会使用。

Mesos 模式

Mesos 1.3.0 及更高版本支持 Secrets 原语作为基于文件和基于环境的秘密。Spark 允许使用 spark.mesos.driver.secret.filenamesspark.mesos.driver.secret.envkeys 分别指定基于文件和基于环境变量的秘密。

根据秘密存储后端,秘密可以通过引用或通过值传递,分别使用 spark.mesos.driver.secret.namesspark.mesos.driver.secret.values 配置属性。

引用类型秘密由秘密存储提供,并通过名称引用,例如 /mysecret。值类型秘密在命令行上传递,并转换为其相应的文件或环境变量。

HTTP 安全头

Apache Spark 可以配置为包含 HTTP 标头以帮助防止跨站点脚本 (XSS)、跨帧脚本 (XFS)、MIME 嗅探,以及强制执行 HTTP 严格传输安全。

属性名称默认值含义自版本
spark.ui.xXssProtection 1; mode=block HTTP X-XSS-Protection 响应标头的值。您可以从以下内容中选择适当的值
  • 0(禁用 XSS 过滤)
  • 1(启用 XSS 过滤。如果检测到跨站点脚本攻击,浏览器将清理页面。)
  • 1; mode=block(启用 XSS 过滤。如果检测到攻击,浏览器将阻止渲染页面。)
2.3.0
spark.ui.xContentTypeOptions.enabled true 启用后,X-Content-Type-Options HTTP 响应标头将设置为“nosniff”。 2.3.0
spark.ui.strictTransportSecurity HTTP 严格传输安全 (HSTS) 响应标头的值。您可以从以下内容中选择适当的值,并相应地设置 expire-time。此选项仅在启用 SSL/TLS 时使用。
  • max-age=<expire-time>
  • max-age=<expire-time>; includeSubDomains
  • max-age=<expire-time>; preload
2.3.0

配置端口以进行网络安全

一般来说,Spark 集群及其服务不会部署在公共互联网上。它们通常是私有服务,并且应该只在部署 Spark 的组织的网络内访问。对 Spark 服务使用的主机和端口的访问应限于需要访问这些服务的源主机。

以下是 Spark 用于其通信的主要端口以及如何配置这些端口。

仅独立模式

默认端口目的配置设置备注
浏览器 独立 Master 8080 Web UI spark.master.ui.port /
SPARK_MASTER_WEBUI_PORT
基于 Jetty。仅限独立模式。
浏览器 独立工作器 8081 Web UI spark.worker.ui.port /
SPARK_WORKER_WEBUI_PORT
基于 Jetty。仅限独立模式。
驱动程序 /
独立工作器
独立 Master 7077 将作业提交到集群 /
加入集群
SPARK_MASTER_PORT 设置为“0”以随机选择端口。仅限独立模式。
外部服务 独立 Master 6066 通过 REST API 将作业提交到集群 spark.master.rest.port 使用 spark.master.rest.enabled 来启用/禁用此服务。仅限独立模式。
独立 Master 独立工作器 (随机) 调度执行器 SPARK_WORKER_PORT 设置为“0”以随机选择端口。仅限独立模式。

所有集群管理器

默认端口目的配置设置备注
浏览器 应用程序 4040 Web UI spark.ui.port 基于 Jetty
浏览器 历史服务器 18080 Web UI spark.history.ui.port 基于 Jetty
执行器 /
独立 Master
驱动程序 (随机) 连接到应用程序 /
通知执行器状态更改
spark.driver.port 设置为“0”以随机选择端口。
执行器 / 驱动程序 执行器 / 驱动程序 (随机) 块管理器端口 spark.blockManager.port 通过 ServerSocketChannel 的原始套接字

Kerberos

Spark 支持在使用 Kerberos 进行身份验证的环境中提交应用程序。在大多数情况下,Spark 在对 Kerberos 感知服务进行身份验证时依赖当前登录用户的凭据。可以通过使用诸如 kinit 之类的工具登录到配置的 KDC 来获取此类凭据。

在与基于 Hadoop 的服务通信时,Spark 需要获取委托令牌,以便非本地进程可以进行身份验证。Spark 附带对 HDFS 和其他 Hadoop 文件系统、Hive 和 HBase 的支持。

使用 Hadoop 文件系统(如 HDFS 或 WebHDFS)时,Spark 将获取托管用户主目录的服务的相关令牌。

如果 HBase 位于应用程序的类路径中,并且 HBase 配置已启用 Kerberos 身份验证(hbase.security.authentication=kerberos),则将获取 HBase 令牌。

类似地,如果 Hive 位于类路径中,并且配置包含远程元存储服务的 URI(hive.metastore.uris 不为空),则将获取 Hive 令牌。

如果应用程序需要与其他安全的 Hadoop 文件系统交互,则需要在启动时显式地将它们的 URI 提供给 Spark。这可以通过在 spark.kerberos.access.hadoopFileSystems 属性中列出它们来完成,该属性在下面的配置部分中描述。

Spark 还支持使用 Java 服务机制(参见 java.util.ServiceLoader)的自定义委托令牌提供程序。可以通过在 jar 的 META-INF/services 目录中相应的文件中列出它们的名字,使 org.apache.spark.security.HadoopDelegationTokenProvider 的实现可供 Spark 使用。

委托令牌支持目前仅在 YARN 和 Mesos 模式下受支持。有关更多信息,请参阅特定于部署的页面。

以下选项提供对此功能的更细粒度的控制

属性名称默认值含义自版本
spark.security.credentials.${service}.enabled true 控制在启用安全时是否为服务获取凭据。默认情况下,在配置这些服务时,将检索所有受支持服务的凭据,但如果它与正在运行的应用程序发生冲突,则可以禁用该行为。 2.3.0
spark.kerberos.access.hadoopFileSystems (无) Spark 应用程序将访问的安全的 Hadoop 文件系统的逗号分隔列表。例如,spark.kerberos.access.hadoopFileSystems=hdfs://nn1.com:8032,hdfs://nn2.com:8032, webhdfs://nn3.com:50070。Spark 应用程序必须能够访问列出的文件系统,并且 Kerberos 必须正确配置才能访问它们(在同一个域或受信任的域中)。Spark 为每个文件系统获取安全令牌,以便 Spark 应用程序可以访问这些远程 Hadoop 文件系统。 3.0.0

用户可以在资源调度程序中排除 Kerberos 委托令牌续订。目前仅在 YARN 上支持。配置在 在 YARN 上运行 Spark 页面中介绍。

长时间运行的应用程序

如果长时间运行的应用程序的运行时间超过了它需要访问的服务中配置的委托令牌最大生命周期,则可能会遇到问题。

此功能并非在所有地方都可用。特别是,它仅在 YARN 和 Kubernetes(客户端和集群模式)上实现,以及在使用客户端模式时在 Mesos 上实现。

Spark 支持为这些应用程序自动创建新令牌。有两种方法可以启用此功能。

使用 Keytab

通过向 Spark 提供主体和密钥表(例如,使用 spark-submit 以及 --principal--keytab 参数),应用程序将维护一个有效的 Kerberos 登录,该登录可以无限期地用于检索委托令牌。

请注意,在集群模式下使用密钥表时,它将被复制到运行 Spark 驱动程序的机器上。对于 YARN,这意味着使用 HDFS 作为密钥表的暂存区,因此强烈建议至少 YARN 和 HDFS 都使用加密进行保护。

使用票证缓存

通过将 Spark 配置中的 spark.kerberos.renewal.credentials 设置为 ccache,本地 Kerberos 票证缓存将用于身份验证。Spark 将在可续订的生命周期内保持票证续订,但过期后需要获取新票证(例如,通过运行 kinit)。

用户需要维护一个更新的票证缓存,以便 Spark 可以使用。

可以通过设置 KRB5CCNAME 环境变量来自定义票证缓存的位置。

与 Kubernetes 的安全交互

在与 Kerberos 后面的基于 Hadoop 的服务通信时,需要注意的是,Spark 需要获取委托令牌,以便非本地进程可以进行身份验证。这些委托令牌在 Kubernetes 中存储在驱动程序及其执行器共享的秘密中。因此,有三种方法可以提交 Kerberos 作业

在所有情况下,您都必须定义环境变量:HADOOP_CONF_DIRspark.kubernetes.hadoop.configMapName.

还需要注意的是,KDC 需要从容器内部可见。

如果用户希望使用包含 Hadoop 配置文件的远程 HADOOP_CONF 目录,可以通过将 spark.kubernetes.hadoop.configMapName 设置为预先存在的 ConfigMap 来实现。

  1. 使用将 TGT 存储在本地票证缓存中的 $kinit 提交
    /usr/bin/kinit -kt <keytab_file> <username>/<krb5 realm>
    /opt/spark/bin/spark-submit \
     --deploy-mode cluster \
     --class org.apache.spark.examples.HdfsTest \
     --master k8s://<KUBERNETES_MASTER_ENDPOINT> \
     --conf spark.executor.instances=1 \
     --conf spark.app.name=spark-hdfs \
     --conf spark.kubernetes.container.image=spark:latest \
     --conf spark.kubernetes.kerberos.krb5.path=/etc/krb5.conf \
     local:///opt/spark/examples/jars/spark-examples_<VERSION>.jar \
     <HDFS_FILE_LOCATION>
    
  2. 使用本地密钥表和主体提交
    /opt/spark/bin/spark-submit \
     --deploy-mode cluster \
     --class org.apache.spark.examples.HdfsTest \
     --master k8s://<KUBERNETES_MASTER_ENDPOINT> \
     --conf spark.executor.instances=1 \
     --conf spark.app.name=spark-hdfs \
     --conf spark.kubernetes.container.image=spark:latest \
     --conf spark.kerberos.keytab=<KEYTAB_FILE> \
     --conf spark.kerberos.principal=<PRINCIPAL> \
     --conf spark.kubernetes.kerberos.krb5.path=/etc/krb5.conf \
     local:///opt/spark/examples/jars/spark-examples_<VERSION>.jar \
     <HDFS_FILE_LOCATION>
    
  3. 使用预先填充的秘密提交,这些秘密包含委托令牌,并且已经存在于命名空间中
    /opt/spark/bin/spark-submit \
     --deploy-mode cluster \
     --class org.apache.spark.examples.HdfsTest \
     --master k8s://<KUBERNETES_MASTER_ENDPOINT> \
     --conf spark.executor.instances=1 \
     --conf spark.app.name=spark-hdfs \
     --conf spark.kubernetes.container.image=spark:latest \
     --conf spark.kubernetes.kerberos.tokenSecret.name=<SECRET_TOKEN_NAME> \
     --conf spark.kubernetes.kerberos.tokenSecret.itemKey=<SECRET_ITEM_KEY> \
     --conf spark.kubernetes.kerberos.krb5.path=/etc/krb5.conf \
     local:///opt/spark/examples/jars/spark-examples_<VERSION>.jar \
     <HDFS_FILE_LOCATION>
    

3b. 像在 (3) 中一样提交,但是指定预先创建的 krb5 ConfigMap 和预先创建的 HADOOP_CONF_DIR ConfigMap

/opt/spark/bin/spark-submit \
    --deploy-mode cluster \
    --class org.apache.spark.examples.HdfsTest \
    --master k8s://<KUBERNETES_MASTER_ENDPOINT> \
    --conf spark.executor.instances=1 \
    --conf spark.app.name=spark-hdfs \
    --conf spark.kubernetes.container.image=spark:latest \
    --conf spark.kubernetes.kerberos.tokenSecret.name=<SECRET_TOKEN_NAME> \
    --conf spark.kubernetes.kerberos.tokenSecret.itemKey=<SECRET_ITEM_KEY> \
    --conf spark.kubernetes.hadoop.configMapName=<HCONF_CONFIG_MAP_NAME> \
    --conf spark.kubernetes.kerberos.krb5.configMapName=<KRB_CONFIG_MAP_NAME> \
    local:///opt/spark/examples/jars/spark-examples_<VERSION>.jar \
    <HDFS_FILE_LOCATION>

事件日志记录

如果您的应用程序使用事件日志记录,则应使用适当的权限手动创建事件日志所在的目录(spark.eventLog.dir)。要保护日志文件,目录权限应设置为 drwxrwxrwxt。目录的所有者和组应与运行 Spark 历史服务器的超级用户相对应。

这将允许所有用户写入目录,但将阻止非特权用户读取、删除或重命名文件,除非他们拥有该文件。事件日志文件将由 Spark 创建,其权限使得只有用户和组具有读写权限。

在客户端模式下持久化驱动程序日志

如果您的应用程序通过启用 spark.driver.log.persistToDfs.enabled 在客户端模式下持久化驱动程序日志,则应使用适当的权限手动创建驱动程序日志所在的目录(spark.driver.log.dfsDir)。要保护日志文件,目录权限应设置为 drwxrwxrwxt。目录的所有者和组应与运行 Spark 历史服务器的超级用户相对应。

这将允许所有用户写入目录,但将阻止非特权用户读取、删除或重命名文件,除非他们拥有该文件。驱动程序日志文件将由 Spark 创建,其权限使得只有用户和组具有读写权限。