我正在尝试在Kubernetes pod中使用client
模式的spark-submit
来提交作业到EMR(由于其他基础设施问题,我们不允许cluster
模式)。默认情况下,spark-submit
使用pod的hostname
作为spark.driver.host
,而该hostname
是pod的主机名,因此spark executor
无法解析它。同时,spark.driver.port
也只能作用于pod(容器)内。
我知道一种方法可以通过传递一些配置给spark-submit
,以便spark executor
可以与driver
通信,这些配置如下:
--conf spark.driver.bindAddress = 0.0.0.0 --conf spark.driver.host = $ HOST_IP_OF_K8S_WORKER --conf spark.driver.port = 32000 --conf spark.driver.blockManager.port = 32001
并在Kubernetes中创建一个服务,以便spark executor
可以与driver
通信:
apiVersion: v1
kind: Service
metadata:
name: spark-block-manager
namespace: my-app
spec:
selector:
app: my-app
type: NodePort
ports:
- name: port-0
nodePort: 32000
port: 32000
protocol: TCP
targetPort: 32000
- name: port-1
nodePort: 32001
port: 32001
protocol: TCP
targetPort: 32001
- name: port-2
nodePort: 32002
port: 32002
protocol: TCP
targetPort: 32002
但问题是一个k8s节点上可能会有多个pod运行,甚至在一个pod中可能会有多个spark-submit作业。因此,在启动pod之前,我们需要动态选择k8s节点上的几个可用端口,并创建一个服务来进行端口映射,然后在启动pod时将这些端口传递到pod中告诉
spark-submit
使用它们。我觉得这有点复杂。使用
hostNetwork: true
可能可以解决这个问题,但它会在我们的基础设施中引入很多其他问题,所以这不是一个选项。如果
spark-submit
能像driver.bindAddress
和driver.host
一样支持bindPort
概念,或者支持proxy
,那么解决问题就更加清晰明了。有人有类似的情况吗?请分享一些见解。
谢谢。
附加背景:
spark版本
:2.4
spark-submit
的 Pod 上。 - Ping.Goblue