火花安全
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 secrets 挂载身份验证秘密,这些秘密用户挂载到他们的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支持基于AES的加密用于RPC连接。要启用加密,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支持对写入本地磁盘的临时数据进行加密。这包括洗牌文件、洗牌溢出和存储在磁盘上的数据块(用于缓存和广播变量)。它不包括通过API生成的输出数据的加密,例如
saveAsHadoopFile
或
saveAsTable
。它也可能不包括用户显式创建的临时文件。
以下设置涵盖了启用写入磁盘的数据加密:
| 属性名称 | 默认 | 含义 | 自版本起 |
|---|---|---|---|
spark.io.encryption.enabled
|
false | 启用本地磁盘输入/输出加密。目前支持所有模式,除了Mesos。当使用此功能时,强烈建议启用RPC加密。 | 2.1.0 |
spark.io.encryption.keySizeBits
|
128 | 输入/输出加密的密钥大小(以位为单位)。支持的值为128、192和256。 | 2.1.0 |
spark.io.encryption.keygen.algorithm
|
HmacSHA1 | 生成输入/输出加密密钥时使用的算法。支持的算法在Java加密体系结构标准算法名称文档的KeyGenerator部分中进行了描述。 | 2.1.0 |
spark.io.encryption.commons.config.*
|
无 |
commons-crypto库的配置值,例如用于哪些密码实现。配置名称应为commons-crypto配置的名称,不带
commons.crypto
前缀。
|
2.1.0 |
网页用户界面
身份验证和授权
启用 Web 界面的身份验证使用 javax servlet filters 完成。您需要一个实现您想要部署的身份验证方法的过滤器。Spark 不提供任何内置的身份验证过滤器。
Spark 还支持在存在身份验证过滤器时对用户界面的访问控制。每个应用程序可以配置其自己的单独访问控制列表 (ACLs)。Spark 区分“查看”权限(谁被允许查看应用程序的用户界面)和“修改”权限(谁可以执行诸如终止正在运行的应用程序的作业等操作)。
可以为用户或组配置ACL。配置条目接受以逗号分隔的列表作为输入,这意味着可以为多个用户或组赋予所需的权限。如果您在共享集群上运行,并且有一组管理员或开发人员需要监控他们可能没有自己启动的应用程序,则可以使用此功能。添加到特定ACL的通配符(
*
)意味着所有用户将拥有相应的权限。默认情况下,只有提交应用程序的用户会被添加到ACL中。
组成员资格是通过使用可配置的组映射提供程序建立的。映射器使用下面表格中描述的
spark.user.groups.mapping
配置选项进行配置。
以下选项控制Web用户界面的身份验证:
| 属性名称 | 默认 | 含义 | 自版本 |
|---|---|---|---|
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历史服务器ACLs
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所提供的所有用户界面,单独的应用程序配置将被忽略。
SSL配置
SSL的配置是按照层次结构组织的。用户可以配置默认的SSL设置,这些设置将用于所有支持的通信协议,除非它们被协议特定的设置覆盖。通过这种方式,用户可以轻松地为所有协议提供通用设置,而无需禁用单独配置每个协议的能力。下表描述了SSL配置命名空间:
| 配置命名空间 | 组件 |
|---|---|
spark.ssl
|
默认的 SSL 配置。这些值将适用于所有以下命名空间,除非在命名空间级别显式覆盖。 |
spark.ssl.ui
|
Spark 应用程序 Web UI |
spark.ssl.standalone
|
独立主节点 / 工作节点 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://hdfs@nn1.example.com:9001/user/backup/ssl.jceks
要配置凭证提供程序的位置,请在Spark使用的Hadoop配置中设置
hadoop.security.credential.provider.path
配置选项,例如:
hadoop.security.credential.provider.path
jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks
或者通过 SparkConf “spark.hadoop.hadoop.security.credential.provider.path=jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks”。
准备密钥存储
密钥库可以通过
keytool
程序生成。此工具的参考文档(针对Java 8)在
这里
。配置Spark独立部署模式的密钥库和信任库的基本步骤如下:
- 为每个节点生成一对密钥
- 将密钥对的公钥导出到每个节点的文件中
- 将所有导出的公钥导入到一个单一的信任库中
- 将信任库分发到集群节点
YARN模式
要为在集群模式下运行的驱动程序提供本地信任存储或密钥存储文件,可以通过使用
--files
命令行参数(或相应的
spark.files
配置)将其与应用程序一起分发。这些文件将放置在驱动程序的工作目录中,因此 TLS 配置只需引用文件名,而不需要绝对路径。
以这种方式分发本地密钥存储可能需要将文件暂存于 HDFS(或集群使用的其他类似分布式文件系统)中,因此建议在配置基础文件系统时考虑安全性(例如,通过启用身份验证和网络加密)。
独立模式
用户需要为主节点和工作节点提供密钥存储和配置选项。它们必须通过在
SPARK_MASTER_OPTS
和
SPARK_WORKER_OPTS
环境变量中附加适当的 Java 系统属性来设置,或者仅在
SPARK_DAEMON_JAVA_OPTS
中设置。
用户可以允许执行者使用从工作进程继承的 SSL 设置。可以通过将
spark.ssl.useNodeLocalConf
设置为
true
来实现。在这种情况下,客户端提供的用户设置将不被使用。
Mesos模式
Mesos 1.3.0 及更新版本支持
Secrets
原语,既可以作为基于文件的秘密,也可以作为基于环境的秘密。Spark 允许通过
spark.mesos.driver.secret.filenames
和
spark.mesos.driver.secret.envkeys
分别指定基于文件和基于环境变量的秘密。
根据秘密存储后端,机密可以通过引用或值传递,使用
spark.mesos.driver.secret.names
和
spark.mesos.driver.secret.values
配置属性,分别。
引用类型的秘密由秘密存储提供,并通过名称引用,例如
/mysecret
。值类型的秘密通过命令行传递,并转换为其
相应的文件或环境变量。
HTTP 安全头
Apache Spark 可以被配置以包含 HTTP 头,以帮助防止跨站脚本攻击 (XSS)、跨框架脚本攻击 (XFS)、MIME 嗅探,并且还可以强制执行 HTTP 严格传输 安全性。
| 属性名称 | 默认值 | 含义 | 自版本起 |
|---|---|---|---|
spark.ui.xXssProtection
|
1; mode=block
|
HTTP X-XSS-Protection 响应头的值。您可以从以下选项中选择适当的值:
|
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 时使用。
|
2.3.0 |
网络安全端口配置
一般来说,Spark集群及其服务不会部署在公共互联网中。它们通常是私有服务,应该仅在部署Spark的组织的网络内可访问。访问Spark服务使用的主机和端口应限制为需要访问这些服务的源主机。
以下是Spark用于其通信的主要端口以及如何配置这些端口。
仅限独立模式
| 来源 | 目标 | 默认端口 | 目的 | 配置设置 | 备注 |
|---|---|---|---|---|---|
| 浏览器 | 独立主节点 | 8080 | Web UI |
spark.master.ui.port /
|
基于Jetty。仅独立模式。 |
| 浏览器 | 独立工作节点 | 8081 | Web UI |
spark.worker.ui.port /
|
基于Jetty。仅独立模式。 |
|
驱动程序 /
独立工作节点 |
独立主节点 | 7077 |
提交作业到集群 /
加入集群 |
SPARK_MASTER_PORT
|
设置为 "0" 可以随机选择一个端口。仅独立模式。 |
| 外部服务 | 独立主节点 | 6066 | 通过 REST API 提交作业到集群 |
spark.master.rest.port
|
使用
spark.master.rest.enabled
来启用/禁用此服务。仅独立模式。
|
| 独立主节点 | 独立工作节点 | (随机) | 调度执行器 |
SPARK_WORKER_PORT
|
设置为 "0" 可以随机选择一个端口。仅独立模式。 |
所有集群管理器
| 来源 | 目标 | 默认端口 | 目的 | 配置设置 | 备注 |
|---|---|---|---|---|---|
| 浏览器 | 应用程序 | 4040 | Web 界面 |
spark.ui.port
|
基于 Jetty |
| 浏览器 | 历史服务器 | 18080 | Web 界面 |
spark.history.ui.port
|
基于 Jetty |
|
执行器 /
独立主控 |
驱动程序 | (随机) |
连接到应用程序 /
通知执行器状态更改 |
spark.driver.port
|
设置为 "0" 以随机选择端口。 |
| 执行器 / 驱动程序 | 执行器 / 驱动程序 | (随机) | 块管理器端口 |
spark.blockManager.port
|
通过 ServerSocketChannel 的原始套接字 |
凯尔伯罗斯
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 上受支持。该配置涵盖在 运行 Spark 在 YARN 上 页面。
长时间运行的应用程序
长期运行的应用程序如果其运行时间超过了需要访问的服务中配置的最大委托令牌生命周期,可能会遇到问题。
此功能并非在所有地方均可用。特别是,它仅在 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的安全交互
在与基于Hadoop的Kerberos后端服务交谈时,注意到Spark需要获取委托令牌,以便非本地进程可以进行身份验证。这些委托令牌在Kubernetes中存储在由Driver和其Executors共享的Secrets中。因此,提交Kerberos作业的方式有三种:
在所有情况下,您必须定义环境变量:
HADOOP_CONF_DIR
或
spark.kubernetes.hadoop.configMapName.
还需要注意的是,KDC需要从容器内部可见。
如果用户希望使用一个包含Hadoop配置文件的远程 HADOOP_CONF 目录,可以通过将
spark.kubernetes.hadoop.configMapName
设置为一个预先存在的 ConfigMap 来实现。
-
使用存储在本地票据缓存中的 TGT 提交 $kinit:
/usr/bin/kinit -kt/ /opt/spark/bin/spark-submit \ --deploy-mode cluster \ --class org.apache.spark.examples.HdfsTest \ --master k8s:// \ --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_ .jar \ -
使用本地 Keytab 和 Principal 提交
/opt/spark/bin/spark-submit \ --deploy-mode cluster \ --class org.apache.spark.examples.HdfsTest \ --master k8s://\ --conf spark.executor.instances=1 \ --conf spark.app.name=spark-hdfs \ --conf spark.kubernetes.container.image=spark:latest \ --conf spark.kerberos.keytab= \ --conf spark.kerberos.principal= \ --conf spark.kubernetes.kerberos.krb5.path=/etc/krb5.conf \ local:///opt/spark/examples/jars/spark-examples_ .jar \ -
使用预填充的秘密提交,这些秘密包含已经存在于命名空间内的委托令牌
/opt/spark/bin/spark-submit \ --deploy-mode cluster \ --class org.apache.spark.examples.HdfsTest \ --master k8s://\ --conf spark.executor.instances=1 \ --conf spark.app.name=spark-hdfs \ --conf spark.kubernetes.container.image=spark:latest \ --conf spark.kubernetes.kerberos.tokenSecret.name= \ --conf spark.kubernetes.kerberos.tokenSecret.itemKey= \ --conf spark.kubernetes.kerberos.krb5.path=/etc/krb5.conf \ local:///opt/spark/examples/jars/spark-examples_ .jar \
3b. 像(3)中那样提交,但是指定一个预创建的 krb5 ConfigMap 和预创建的
HADOOP_CONF_DIR
ConfigMap
/opt/spark/bin/spark-submit \
--deploy-mode 集群 \
--class org.apache.spark.examples.HdfsTest \
--master k8s:// \
--conf spark.executor.instances=1 \
--conf spark.app.name=spark-hdfs \
--conf spark.kubernetes.container.image=spark:latest \
--conf spark.kubernetes.kerberos.tokenSecret.name= \
--conf spark.kubernetes.kerberos.tokenSecret.itemKey= \
--conf spark.kubernetes.hadoop.configMapName= \
--conf spark.kubernetes.kerberos.krb5.configMapName= \
local:///opt/spark/examples/jars/spark-examples_.jar \
事件日志记录
如果您的应用程序使用事件日志,则事件日志存放的目录(
spark.eventLog.dir
)应手动创建并设置正确的权限。为了保护日志文件,目录权限应设置为
drwxrwxrwxt
。目录的所有者和组应与运行 Spark 历史服务器的超级用户相对应。
这将允许所有用户对目录进行写入,但将阻止无权限用户读取、删除或重命名文件,除非他们是文件的拥有者。事件日志文件将由 Spark 创建,其权限设置为只有用户和组具有读取和写入访问权限。
在客户端模式中持久化驱动程序日志
如果您的应用程序通过启用
spark.driver.log.persistToDfs.enabled
在客户端模式下持久化驱动程序日志,那么驱动程序日志存放的目录 (
spark.driver.log.dfsDir
) 应该手动创建,并设置适当的权限。为了保护日志文件,目录的权限应该设置为
drwxrwxrwxt
。该目录的所有者和组应该对应于运行 Spark 历史服务器的超级用户。
这将允许所有用户写入该目录,但将阻止无权限用户读取、删除或重命名文件,除非他们是文件的拥有者。驱动程序日志文件将由Spark创建,权限设置为只有用户和组具有读写访问权限。