写点什么

Spark On Kubernetes 的 Web UI 访问实践

  • 2022-10-28
    江苏
  • 本文字数:1919 字

    阅读完需:约 6 分钟

本文作者为中国移动云能力中心软件开发工程师洪冬冬,文章详细介绍了不同场景下使用不同的方式实现对 Spark on K8s 的 Web UI 访问实践,供大家参考。

背景

在将 Spark 从 YARN 集群迁移到 Kubernetes 集群的过程中,遇到一个问题,以 Cluster 模式提交任务后,我们该如何访问 Spark Web UI。 

在 Kubernetes 中提供了名为 Service 的资源,它是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。Service 大致可以分为以下几类:

  • ClusterIP:默认值,通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。

  • NodePort:将 Service 通过指定的 Node 上的端口暴露给外部,通过此方法,就可以在集群外部访问服务。

  • LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。

  • ExternalName:把集群外部的服务引入集群内部,直接使用

在 Kubernetes 中,当 Spark 的 driver pod 启动后,默认会帮我们创建一个 ClusterIP 类型的 service,且当前开源版本中我们无法修改 service 类型。我们可以借助这个 Service,根据使用场景,通过不同的方式来实现对 Web UI 的访问。

实践

1、端口转发

在 Spark 官网示例中(https://spark.apache.org/docs/latest/running-on-kubernetes.html#accessing-driver-ui),使用 Kubernetes 自带的端口转发命令 kubectl port-forward 实现对 Web UI 的访问,具体命令如下:

[root@HOSTNAME spark]# kubectl port-forward 4040:4040 Forwarding from 127.0.0.1:4040 -> 4040 Forwarding from [::1]:4040 -> 4040
复制代码

该命令使用执行命令的宿主机的 4040 端口转发 driver pod 的 4040 端口,我们可以在本地访问宿主机的 4040 端口来实现 Web UI 的访问(需要本地可以连通宿主机)。

2、创建新的 service

由于 Spark 默认创建的是 ClusterIP 类型 service,无法直接在外部访问,我们可以直接为 driver pod 创建一个新的 NodePort/LoadBalancer 类型的 service,以 NodePort 为例,命令如下:

[root@HOSTNAME spark]# kubectl expose pod <driver-pod-name> --type=NodePort --port 4040service/<driver-pod-name> exposed
复制代码

创建完 NodePort 后,可以通过 get service 命令获取对应的端口映射关系。

[root@HOSTNAME spark]# kubectl get service<NodePort-name>         NodePort    <IP>   <none>        4040:31231/TCP   
复制代码

其中 31231 为映射的外部访问地址,可以通过 Kubernetes 集群中任意宿主机 IP:31231 来访问 Web UI。

3、Ingress

Ingress 是 Kubernetes 中对集群中服务的外部访问进行管理的 API 对象,支持和维护 AWS、 GCE 和 Nginx Ingress 控制器。可以看作是 service 上的 service,工作原理如下:



Ingress 是目前在生产中比较推荐的方案,部分集成 Spark 的开源组件也是通过 ingress 来暴露 Web UI。一个简单的 ingress 模版如下:

[root@HOSTNAME spark]#  vi spark-ingress.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:  name: <driver-pod-name>-ingress  annotations:    nginx.ingress.kubernetes.io/rewrite-target: /spec:  kubernetes.io/ingress.class: "nginx"  rules:  - http:      paths:      - path: /        backend:          service:            name: <spark-driver-svc>            port:              number: 4040
复制代码

成功创建 Ingress 后,我们可以通过 IP:Port/的方式来访问 Spark Web UI。

4、Gateway 配合 spark 反向代理

Spark 在 2.1.0 以后引入了反向代理功能,详见(https://issues.apache.org/jira/browse/SPARK-20044),基于反向代理,我们可以实现对 Spark Web UI 的动态代理。其工作原理如下:



需要在 Spark 中开启 reverseProxy,参数如下:

spark.ui.reverseProxy=truespark.ui.reverseProxyUrl=http://<host>:<port>/<path>
复制代码

其中 host:port 为网关服务的入口地址,path 为对应 spark driver 的转发路径,我们可以在应用中对应关系持久化到 mysql/zookeeper 中,便于 gateway 服务动态加载。这种方案依赖外部服务,同时需要对应用改造。通过翻阅文档和源码,spark 支持定义各种资源的前缀字符串,可以设置参数

spark.kubernetes.driver.resourceNamePrefix=prefix-a
复制代码

此时,可以直接推断出 Spark 创建的 ClusterIP 为 prefix-a-driver-svc。通过添加配置,既不会增加外部依赖,也不需要改造应用,可以很方便的实现 gateway 对 spark Web UI 的动态代理。

总结

根据不同的使用场景,我们可以选择不同的方式实现对 Web UI 的访问,在 gateway 配合 Spark 反向代理方案的使用过程中,我们也遇到了性能和转发方面的问题。后续,将进一步探索 Nginx ingress 的方案,实现基于原生组件的动态代理功能。

用户头像

移动云,5G时代你身边的智慧云 2019-02-13 加入

移动云大数据产品团队,在移动云上提供云原生大数据分析LakeHouse,消息队列Kafka/Pulsar,云数据库HBase,弹性MapReduce,数据集成与治理等PaaS服务。 微信公众号:人人都学大数据

评论

发布
暂无评论
Spark On Kubernetes 的 Web UI 访问实践_移动云大数据_InfoQ写作社区