如何将 spark worker 连接到 kubernetes 中的 spark driver(独立集群)
how to connect spark workers to spark driver in kubernetes (standalone cluster)
我创建了一个 Dockerfile
,仅包含从主网站下载的 debian
和 apache spark
。然后我创建了一个 kubernetes 部署以拥有 1 个 pod 运行 spark driver
和另一个 spark worker
NAME READY STATUS RESTARTS AGE
spark-driver-54446998ff-2rz5h 1/1 Running 0 45m
spark-worker-5d55b54d8d-9vfs7 1/1 Running 2 (69m ago) 16h
经测试有效
我可以使用位于 /spark-dir/sbin/
的 ./start-master.sh
启动 spark 驱动程序。这是从 start-master.sh
文件
生成的日志
22/04/28 04:34:25 INFO Utils: Successfully started service 'sparkMaster' on port 7077.
22/04/28 04:34:25 INFO Master: Starting Spark master at spark://10.244.1.148:7077
22/04/28 04:34:25 INFO Master: Running Spark version 3.2.1
22/04/28 04:34:26 INFO Utils: Successfully started service 'MasterUI' on port 8080.
22/04/28 04:34:27 INFO MasterWebUI: Bound MasterWebUI to 0.0.0.0, and started at http://spark-driver-54446998ff-2rz5h:8080
22/04/28 04:34:28 INFO Master: I have been elected leader! New state: ALIVE
什么 spark-driver
/etc/hosts 产生:
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.244.1.148 spark-driver-54446998ff-2rz5h
现在我可以将我的工作人员连接到同一命名空间中的另一个 pod 上:./start-worker.sh spark://10.244.1.148:7077
这显示成功,因为在 spark-driver
日志文件中,它显示:
22/04/28 04:34:52 INFO Master: Registering worker 10.244.2.134:44413 with 4 cores, 1024.0 MiB RAM
我的问题是: 为了让我动态地执行此操作,我需要 worker pod 能够为它提取 spark-driver
的 ip 地址连接。我读到一个潜在的方法是利用 dns
服务来实现这一点,但到目前为止我一直没有成功。
这是我的 deployment.yaml
文件,其中也包含 service
。但我无法理解它是如何协同工作的。
apiVersion: v1
kind: Service
metadata:
name: spark-driver
spec:
type: ClusterIP
# type: NodePort
selector:
app.kubernetes.io/name: spark-3.2.1
app.kubernetes.io/instance: spark-driver
ports:
- name: service
protocol: TCP
port: 80
targetPort: service-port
- name: spark-master
protocol: TCP
port: 8080
targetPort: spark-ui-port
- name: spark-worker
protocol: TCP
port: 7077
targetPort: spark-wkr-port
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spark-driver
labels:
app.kubernetes.io/name: spark-3.2.1
app.kubernetes.io/instance: spark-driver
app.kubernetes.io/version: 0.0.4
app.kubernetes.io/managed-by: kubernetes-standalone-cluster
spec:
replicas: 1
selector:
matchLabels:
app: spark-3.2.1-driver
template:
metadata:
labels:
app: spark-3.2.1-driver
spec:
containers:
- name: spark-driver
image: zzzzzzzzzzz
ports:
- containerPort: 80
name: service-port
- containerPort: 8080
name: spark-ui-port
- containerPort: 7077
name: spark-wkr-port
resources:
requests:
cpu: "2"
memory: "2Gi"
limits:
cpu: "4"
memory: "3Gi"
env:
- name: SPARK_MASTER_HOST
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SPARK_MASTER_PORT
value: "7077"
- name: SPARK_MODE
value: driver
- name: TERM
value: xterm
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spark-worker
labels:
app.kubernetes.io/name: spark-3.2.1-worker
app.kubernetes.io/instance: spark-worker
app.kubernetes.io/version: 0.0.4
app.kubernetes.io/managed-by: kubernetes-standalone-cluster
spec:
replicas: 1
selector:
matchLabels:
app: spark-3.2.1-worker
template:
metadata:
labels:
app: spark-3.2.1-worker
spec:
containers:
- name: spark-worker
image: zzzzzzzzzzz
resources:
requests:
cpu: "2"
memory: "1Gi"
limits:
cpu: "4"
memory: "2Gi"
env:
- name: SPARK_MODE
value: worker
- name: TERM
value: xterm
---
我应该如何配置服务或 spark env,以便 spark worker 可以使用 dns
连接到 spark 驱动程序?
我也想和你一样,目前还没有成功。但是,这可能对您有用:
您可以像这样将驱动程序 pod 的主机 IP 公开为环境变量:
-env:
- name: "SPARK_DRIVER_HOST_IP"
valueFrom:
fieldRef:
apiVersion: "v1"
fieldPath: "status.hostIP"
这对我有用,因为我继续将 spark.host.driver 属性 设置为 SPARK_DRVIER_HOST_IP。实际上,我是在我的容器内执行此操作的,该容器应该在我的 SparkConf 设置中 运行 spark 应用程序。
但是我的问题是执行程序在尝试连接到 [driverHostIP]:[PORT] 时遇到连接被拒绝的情况。我怀疑这可能是因为我需要一个服务来公开这个 IP,就像你在你的 yaml 中那样?但我不确定。
我希望我们都拥有此解决方案的两个部分,并且希望使用公开的驱动程序 IP 地址和 spark 驱动程序服务能够正常工作。让我知道是否有方便的驱动程序 IP 是否有帮助。
我创建了一个 Dockerfile
,仅包含从主网站下载的 debian
和 apache spark
。然后我创建了一个 kubernetes 部署以拥有 1 个 pod 运行 spark driver
和另一个 spark worker
NAME READY STATUS RESTARTS AGE
spark-driver-54446998ff-2rz5h 1/1 Running 0 45m
spark-worker-5d55b54d8d-9vfs7 1/1 Running 2 (69m ago) 16h
经测试有效
我可以使用位于 /spark-dir/sbin/
的 ./start-master.sh
启动 spark 驱动程序。这是从 start-master.sh
文件
22/04/28 04:34:25 INFO Utils: Successfully started service 'sparkMaster' on port 7077.
22/04/28 04:34:25 INFO Master: Starting Spark master at spark://10.244.1.148:7077
22/04/28 04:34:25 INFO Master: Running Spark version 3.2.1
22/04/28 04:34:26 INFO Utils: Successfully started service 'MasterUI' on port 8080.
22/04/28 04:34:27 INFO MasterWebUI: Bound MasterWebUI to 0.0.0.0, and started at http://spark-driver-54446998ff-2rz5h:8080
22/04/28 04:34:28 INFO Master: I have been elected leader! New state: ALIVE
什么 spark-driver
/etc/hosts 产生:
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.244.1.148 spark-driver-54446998ff-2rz5h
现在我可以将我的工作人员连接到同一命名空间中的另一个 pod 上:./start-worker.sh spark://10.244.1.148:7077
这显示成功,因为在 spark-driver
日志文件中,它显示:
22/04/28 04:34:52 INFO Master: Registering worker 10.244.2.134:44413 with 4 cores, 1024.0 MiB RAM
我的问题是: 为了让我动态地执行此操作,我需要 worker pod 能够为它提取 spark-driver
的 ip 地址连接。我读到一个潜在的方法是利用 dns
服务来实现这一点,但到目前为止我一直没有成功。
这是我的 deployment.yaml
文件,其中也包含 service
。但我无法理解它是如何协同工作的。
apiVersion: v1
kind: Service
metadata:
name: spark-driver
spec:
type: ClusterIP
# type: NodePort
selector:
app.kubernetes.io/name: spark-3.2.1
app.kubernetes.io/instance: spark-driver
ports:
- name: service
protocol: TCP
port: 80
targetPort: service-port
- name: spark-master
protocol: TCP
port: 8080
targetPort: spark-ui-port
- name: spark-worker
protocol: TCP
port: 7077
targetPort: spark-wkr-port
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spark-driver
labels:
app.kubernetes.io/name: spark-3.2.1
app.kubernetes.io/instance: spark-driver
app.kubernetes.io/version: 0.0.4
app.kubernetes.io/managed-by: kubernetes-standalone-cluster
spec:
replicas: 1
selector:
matchLabels:
app: spark-3.2.1-driver
template:
metadata:
labels:
app: spark-3.2.1-driver
spec:
containers:
- name: spark-driver
image: zzzzzzzzzzz
ports:
- containerPort: 80
name: service-port
- containerPort: 8080
name: spark-ui-port
- containerPort: 7077
name: spark-wkr-port
resources:
requests:
cpu: "2"
memory: "2Gi"
limits:
cpu: "4"
memory: "3Gi"
env:
- name: SPARK_MASTER_HOST
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SPARK_MASTER_PORT
value: "7077"
- name: SPARK_MODE
value: driver
- name: TERM
value: xterm
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spark-worker
labels:
app.kubernetes.io/name: spark-3.2.1-worker
app.kubernetes.io/instance: spark-worker
app.kubernetes.io/version: 0.0.4
app.kubernetes.io/managed-by: kubernetes-standalone-cluster
spec:
replicas: 1
selector:
matchLabels:
app: spark-3.2.1-worker
template:
metadata:
labels:
app: spark-3.2.1-worker
spec:
containers:
- name: spark-worker
image: zzzzzzzzzzz
resources:
requests:
cpu: "2"
memory: "1Gi"
limits:
cpu: "4"
memory: "2Gi"
env:
- name: SPARK_MODE
value: worker
- name: TERM
value: xterm
---
我应该如何配置服务或 spark env,以便 spark worker 可以使用 dns
连接到 spark 驱动程序?
我也想和你一样,目前还没有成功。但是,这可能对您有用:
您可以像这样将驱动程序 pod 的主机 IP 公开为环境变量:
-env:
- name: "SPARK_DRIVER_HOST_IP"
valueFrom:
fieldRef:
apiVersion: "v1"
fieldPath: "status.hostIP"
这对我有用,因为我继续将 spark.host.driver 属性 设置为 SPARK_DRVIER_HOST_IP。实际上,我是在我的容器内执行此操作的,该容器应该在我的 SparkConf 设置中 运行 spark 应用程序。
但是我的问题是执行程序在尝试连接到 [driverHostIP]:[PORT] 时遇到连接被拒绝的情况。我怀疑这可能是因为我需要一个服务来公开这个 IP,就像你在你的 yaml 中那样?但我不确定。
我希望我们都拥有此解决方案的两个部分,并且希望使用公开的驱动程序 IP 地址和 spark 驱动程序服务能够正常工作。让我知道是否有方便的驱动程序 IP 是否有帮助。