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。 此类应用程序的 shuffle 数据在 External Shuffle Service 重启后将无法恢复。 3.5.0

Kubernetes

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

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

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

属性名默认值含义起始版本
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 的配置系统允许高级用户访问该库的配置。

此协议有两个互不兼容的版本。 版本 1 省略了将密钥派生函数 (KDF) 应用于密钥交换协议的输出,而版本 2 应用 KDF 以确保派生的会话密钥均匀分布。 版本 1 是默认版本,用于向后兼容。 **建议使用版本 2** 以获得更好的安全属性。 可以通过将 spark.network.crypto.authEngineVersion 设置为 1 或 2 分别配置版本。

还支持基于 SASL 的加密,但应将其视为已弃用。 当与 Spark 2.2.0 之前的版本的 shuffle 服务通信时,仍然需要它。

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

属性名默认值含义起始版本
spark.network.crypto.enabled false 启用基于 AES 的 RPC 加密,包括 2.2.0 中添加的新身份验证协议。 2.2.0
spark.network.crypto.cipher AES/CTR/NoPadding 要使用的密码模式。 默认为 "AES/CTR/NoPadding" 以实现向后兼容,该模式未经身份验证。 建议使用 "AES/GCM/NoPadding",这是一种经过身份验证的加密模式。 4.0.0, 3.5.2, 3.4.4
spark.network.crypto.authEngineVersion 1 要使用的基于 AES 的 RPC 加密的版本。 有效版本为 1 或 2。 建议使用版本 2。 3.4.3, 3.5.2
spark.network.crypto.config.* commons-crypto 库的配置值,例如要使用的密码实现。 配置名称应为 commons-crypto 配置的名称,不带 commons.crypto 前缀。 2.2.0
spark.network.crypto.saslFallback true 如果使用 Spark 的内部机制进行身份验证失败,是否回退到 SASL 身份验证。 当应用程序连接到不支持内部 Spark 身份验证协议的旧 shuffle 服务时,这很有用。 在 shuffle 服务端,禁用此功能将阻止旧客户端进行身份验证。 2.2.0
spark.authenticate.enableSaslEncryption false 启用基于 SASL 的加密通信。 2.2.0
spark.network.sasl.serverAlwaysEncrypt false 禁用使用 SASL 身份验证的端口的未加密连接。 这将拒绝来自启用身份验证但不请求基于 SASL 的加密的客户端的连接。 1.4.0

本地存储加密

Spark 支持加密写入本地磁盘的临时数据。 这包括 shuffle 文件、shuffle 溢出和存储在磁盘上的数据块(用于缓存和广播变量)。 它不包括使用诸如 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 Cryptography Architecture Standard Algorithm Name Documentation 的 KeyGenerator 部分中进行了描述。 2.1.0
spark.io.encryption.commons.config.* commons-crypto 库的配置值,例如要使用的密码实现。 配置名称应为 commons-crypto 配置的名称,不带 commons.crypto 前缀。 2.1.0

Web UI

身份验证和授权

Web UI 的身份验证通过使用 javax servlet filters 来实现。 您需要一个实现您要部署的身份验证方法的过滤器。 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 Standalone Master / Worker Web UI
spark.ssl.historyServer History Server Web UI

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

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

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

hadoop credential create spark.ssl.keyPassword -value password \
    -provider jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks

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

  <property>
    <name>hadoop.security.credential.provider.path</name>
    <value>jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks</value>
  </property>

或者通过 SparkConf “spark.hadoop.hadoop.security.credential.provider.path=jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks”。

准备密钥库

密钥库可以由 keytool 程序生成。 Java 8 的此工具的参考文档位于 这里。 配置 Spark Standalone 部署模式的密钥库和信任存储的最基本步骤如下

YARN 模式

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

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

Standalone 模式

用户需要为 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 用于其通信的主要端口,以及如何配置这些端口。

仅限 Standalone 模式

默认端口目的配置设置注意
浏览器 Standalone Master 8080 Web UI spark.master.ui.port /
SPARK_MASTER_WEBUI_PORT
基于 Jetty。仅限 Standalone 模式。
浏览器 Standalone Worker 8081 Web UI spark.worker.ui.port /
SPARK_WORKER_WEBUI_PORT
基于 Jetty。仅限 Standalone 模式。
Driver /
Standalone Worker
Standalone Master 7077 将作业提交到集群 /
加入集群
SPARK_MASTER_PORT 设置为 "0" 可随机选择端口。仅限 Standalone 模式。
外部服务 Standalone Master 6066 通过 REST API 将作业提交到集群 spark.master.rest.port 使用 spark.master.rest.enabled 启用/禁用此服务。仅限 Standalone 模式。
Standalone Master Standalone Worker (随机) 调度 executors SPARK_WORKER_PORT 设置为 "0" 可随机选择端口。仅限 Standalone 模式。

所有集群管理器

默认端口目的配置设置注意
浏览器 应用程序 4040 Web UI spark.ui.port 基于 Jetty
浏览器 History Server 18080 Web UI spark.history.ui.port 基于 Jetty
Executor /
Standalone Master
Driver (随机) 连接到应用程序 /
通知 executor 状态更改
spark.driver.port 设置为 "0" 可随机选择端口。
Executor / Driver Executor / Driver (随机) Block Manager 端口 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 在类路径中,并且配置包含远程 Metastore 服务的 URI(hive.metastore.uris 不为空),则将获得 Hive 令牌。

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

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

目前仅在 YARN、Kubernetes 和 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 提供主体和密钥表(例如,使用带有 --principal--keytab 参数的 spark-submit),应用程序将维护有效的 Kerberos 登录名,该登录名可以无限期地用于检索委托令牌。

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

使用票据缓存

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

由用户来维护 Spark 可以使用的更新的票证缓存。

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

与 Kubernetes 的安全交互

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

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

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

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

  1. 使用 $kinit 提交,该 $kinit 将 TGT 存储在本地票证缓存中
    /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. 使用本地密钥表和 Principal 提交
    /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. 使用预填充的 Secrets 提交,其中包含已存在于命名空间内的委托令牌
    /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 History Server 的超级用户。

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

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

如果您的应用程序通过启用 spark.driver.log.persistToDfs.enabled 在客户端模式下持久化 Driver 日志,则应手动创建 Driver 日志所在的目录(spark.driver.log.dfsDir),并具有正确的权限。为了保护日志文件,目录权限应设置为 drwxrwxrwxt。目录的所有者和组应对应于运行 Spark History Server 的超级用户。

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