Spark可以运行在由Kubernetes管理的集群上。此功能使用已添加到Spark的本地Kubernetes调度程序。
Kubernetes调度器目前是实验性的。在未来的版本中,可能会出现配置,容器图像和入口点的行为变化。
· Spark 2.3或更高版本的可运行分发。
· 正在运行的Kubernetes集群版本> = 1.6,并使用kubectl为其配置了访问权限 。如果您还没有可用的Kubernetes群集,则可以使用minikube在本地计算机上设置测试群集 。
o 我们建议在启用DNS插件的情况下使用最新版本的minikube。
o 请注意,默认的minikube配置不足以运行Spark应用程序。我们推荐3个CPU和4g内存,以便能够使用一个执行程序启动一个简单的Spark应用程序。
· 您必须具有适当的权限才能在群集中列出,创建,编辑和删除 窗格。您可以验证您是否可以通过运行列出这些资源kubectl auth can-i pods
。
o 必须允许驱动程序窗格使用的服务帐户凭据创建窗格,服务和配置图。
· 您必须在群集中配置Kubernetes DNS。
spark-submit可以直接用于将Spark应用程序提交给Kubernetes集群。提交机制的工作原理如下:
· Spark在Kubernetes窗格中创建一个Spark驱动程序。
· 该驱动程序创建也在Kubernetes窗格中运行并连接到它们的执行程序,并执行应用程序代码。
· 当应用程序完成时,执行程序窗格会终止并被清理,但驱动程序窗格会保留日志并在Kubernetes API中保持“已完成”状态,直到最终收集垃圾或手动清理垃圾。
请注意,在完成状态,驾驶员舱并没有使用任何的计算或存储资源。
驱动程序和执行程序pod调度由Kubernetes处理。可以通过 使用其配置属性的节点选择器将驱动程序和执行程序窗格安排在可用节点的子集上。在将来的版本中,可以使用更高级的调度提示,如
node/pod affinities。
Kubernetes要求用户提供可以部署到容器内容器中的图像。这些图像被构建为在Kubernetes支持的容器运行时环境中运行。Docker是一个容器运行时环境,经常与Kubernetes一起使用。Spark(从版本2.3开始)附带一个可用于此目的的Dockerfile,或自定义以匹配单个应用程序的需求。它可以在kubernetes/dockerfiles/ 目录中找到。
Spark还附带了一个bin/docker-image-tool.sh脚本,可用于构建和发布Docker映像以与Kubernetes后端一起使用。
用法示例是:
$ ./bin/docker-image-tool.sh -r
$ ./bin/docker-image-tool.sh -r
要以群集模式启动Spark Pi,
$ bin/spark-submit \
--master k8s://https://
--deploy-mode cluster \
--name spark-pi \
--class org.apache.spark.examples.SparkPi \
--conf spark.executor.instances=5 \
--conf spark.kubernetes.container.image=
local:///path/to/examples.jar
通过将--master命令行参数传递给应用程序配置spark-submit或通过spark.master在应用程序的配置中进行设置 来指定的Spark主机必须是具有该格式的URL k8s://
在Kubernetes模式,由指定的星火应用程序名称spark.app.name或--name以参数 spark-submit使用默认命名像司机和执行人创建Kubernetes资源。因此,应用程序名称必须由小写字母数字字符组成-,and . 和必须以字母数字字符开头和结尾。
如果您有Kubernetes群集设置,则通过执行一种发现apiserver URL的方法kubectl cluster-info。
$ kubectl cluster-info
Kubernetes master is running at http://127.0.0.1:6443
在上面的例子中,spark-submit通过指定 --master k8s://http://127.0.0.1:6443spark-submit的参数,可以使用特定的Kubernetes集群。此外,还可以使用身份验证代理kubectl proxy与Kubernetes API进行通信。
本地代理可以通过以下方式启动:
$ kubectl proxy
如果本地代理正在localhost:8001上运行,--master k8s://http://127.0.0.1:8001则可以用作spark-submit的参数。最后,请注意,在上面的示例中,我们使用特定的URI指定了一个具有特定URI的jar local://。这个URI是已经在Docker镜像中的示例jar的位置。
如果您的应用程序的依赖项全部托管在远程位置(如HDFS或HTTP服务器)中,则它们可能会被其适当的远程URI引用。此外,应用程序依赖关系可以预先安装到定制的Docker镜像中。这些依赖关系可以通过在local://URI中引用它们和/或SPARK_EXTRA_CLASSPATH在Dockerfiles中设置 环境变量来添加到类路径中。local://在引用自定义Docker镜像中的依赖关系时,该方案也是必需的spark-submit。请注意,使用提交客户端的本地文件系统中的应用程序依赖关系目前尚不支持。
当在HDFS或HTTP服务器等远程位置托管应用程序依赖项时,驱动程序和执行程序窗格需要一个Kubernetes init- 容器来下载依赖项,以便驱动程序和执行程序容器可以在本地使用它们。
init-container处理在spark.jars(或--jars选项spark-submit)和 spark.files(或--files选项spark-submit)中指定的远程依赖关系。它还处理远程托管的主应用程序资源,例如主应用程序jar。以下显示了对spark-submit命令使用远程依赖关系的示例:
$ bin/spark-submit \
--master k8s://https://
--deploy-mode cluster \
--name spark-pi \
--class org.apache.spark.examples.SparkPi \
--jars https://path/to/dependency1.jar,https://path/to/dependency2.jar
--files hdfs://host:port/path/to/file1,hdfs://host:port/path/to/file2
--conf spark.executor.instances=5 \
--conf spark.kubernetes.container.image=
https://path/to/examples.jar
Kubernetes Secrets可用于为Spark应用程序提供访问安全服务的凭据。要将用户指定的密码安装到驱动程序容器中,用户可以使用表单的配置属性spark.kubernetes.driver.secrets.[SecretName]=
--conf spark.kubernetes.driver.secrets.spark-secret=/etc/secrets
--conf spark.kubernetes.executor.secrets.spark-secret=/etc/secrets
请注意,如果使用init-container,则安装到驱动程序容器中的任何密码也将被装入驱动程序的init容器中。同样,挂载到执行程序容器中的任何秘密也将被挂载到执行程序的init容器中。
这些是您可以调查运行/完成的Spark应用程序,监视进度并采取行动的不同方式。
可以使用Kubernetes API和kubectlCLI 访问日志。当Spark应用程序正在运行时,可以使用以下方式从应用程序流式传输日志:
$ kubectl -n=
如果安装在群集上,则也可以通过Kubernetes仪表板访问相同的日志 。
与任何应用程序关联的用户界面可以在本地使用 kubectl port-forward。
$ kubectl port-forward
然后,可以访问Spark驱动程序UI http://localhost:4040。
可能有几种故障。如果Kubernetes API服务器拒绝来自spark-submit的请求,或者由于其他原因拒绝连接,则提交逻辑应指示遇到的错误。但是,如果在应用程序运行期间出现错误,通常最好的调查方式可能是通过Kubernetes CLI。
要获得有关围绕驱动程序窗格做出的调度决策的一些基本信息,您可以运行:
$ kubectl describe pod
如果该容器遇到运行时错误,则可以使用以下方法进一步探测状态:
$ kubectl logs
失败的执行程序窗格的状态和日志可以用类似的方法检查。最后,删除驱动程序窗口将清理整个spark应用程序,包括所有执行程序,相关服务等。驱动程序窗格可以被认为是Spark应用程序的Kubernetes表示形式。
Kubernetes具有名称空间的概念。命名空间是在多个用户之间划分群集资源的方式(通过资源配额)。Kubernetes上的Spark可以使用命名空间来启动Spark应用程序。这可以通过spark.kubernetes.namespace配置使用。
Kubernetes允许使用ResourceQuota对单个名称空间上的资源,对象数量等设置限制。名称空间和ResourceQuota可以由管理员组合使用,以控制运行Spark应用程序的Kubernetes群集中的共享和资源分配。
在启用了RBAC的 Kubernetes集群中,用户可以配置各种Kubernetes上的Spark使用的Kubernetes RBAC角色和服务帐户,以访问Kubernetes API服务器。
Spark驱动程序窗格使用Kubernetes服务帐户访问Kubernetes API服务器以创建和监视执行程序窗格。驱动程序窗口使用的服务帐户必须具有适当的权限才能使驱动程序能够完成其工作。具体而言,服务帐户至少必须被授予 Role或ClusterRole允许驱动程序窗格创建窗格和服务。默认情况下,如果在创建pod时没有default指定服务帐户,则驱动程序窗格会自动在由其指定的命名空间中分配服务帐户spark.kubernetes.namespace。
根据部署的Kubernetes的版本和设置,此default服务帐户可能具有或不具有允许驱动程序窗格在默认Kubernetes RBAC策略下创建窗格和服务的 角色。有时用户可能需要指定一个具有授予的正确角色的自定义服务帐户。Kubernetes上的Spark支持通过配置属性指定由驱动程序窗口使用的自定义服务帐户 spark.kubernetes.authenticate.driver.serviceAccountName=
--conf spark.kubernetes.authenticate.driver.serviceAccountName=spark
要创建自定义服务帐户,用户可以使用该kubectl create serviceaccount命令。例如,以下命令创建一个名为的服务帐户spark:
$ kubectl create serviceaccount spark
授予服务帐户a Role或ClusterRole,RoleBinding或ClusterRoleBinding需要。要创建一个RoleBindingor ClusterRoleBinding,用户可以使用kubectl create rolebinding(或clusterrolebinding for ClusterRoleBinding)命令。例如,以下命令edit ClusterRole在default 名称空间中创建一个并将其授予spark上面创建的服务帐户:
$ kubectl create clusterrolebinding spark-role --clusterrole=edit --serviceaccount=default:spark --namespace=default
请注意,Role只能用于授予对单个名称空间内资源(如pod)的访问权限,而a ClusterRole可用于授予跨所有名称空间的对集群范围资源(如节点)以及名称空间资源(如pod)的访问权限。对于Kubernetes上的Spark,由于驱动程序始终在相同的名称空间中创建执行程序窗格,所以a Role就足够了,尽管用户可能会使用它ClusterRole。有关RBAC授权以及如何为pod配置Kubernetes服务帐户的更多信息,请参阅使用RBAC授权和 配置 Pod的服务帐户。
客户端模式目前不受支持。
有Kubernetes上的几个Spark功能目前正在使用fork - apache-spark-on-k8s / spark进行孵化,预计最终将成为未来版本的spark-kubernetes集成。
其中一些包括:
· PySpark
· [R
· 动态执行器缩放
· 本地文件依赖管理
· Spark应用程序管理
· 作业队列和资源管理
如果您想尝试这些功能并向开发团队提供反馈,可以参考文档。
有关Spark配置的信息,请参阅配置页面。以下配置特定于Kubernetes上的Spark。
Spark属性
后续继续完善............