本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

在 Kubernetes 1.2 上使用 Spark 和 Zeppelin 处理大数据

编者按:这是关于 Kubernetes 1.2 新功能的一系列深度文章中的第五篇。

随着大数据使用量的指数级增长,许多 Kubernetes 客户表示有兴趣在其 Kubernetes 集群上运行 Apache Spark,以利用容器的可移植性和灵活性。幸运的是,借助 Kubernetes 1.2,您现在可以拥有一个同时运行 Spark、Zeppelin 和其他应用程序的平台。

为什么选择 Zeppelin? 

Apache Zeppelin 是一个基于 Web 的笔记本,可实现交互式数据分析。作为其后端之一,Zeppelin 连接到 Spark。Zeppelin 允许用户以简单的方式与 Spark 集群交互,而无需处理命令行解释器或 Scala 编译器。

为什么选择 Kubernetes? 

在 Kubernetes 之外有多种方式运行 Spark

  • 您可以使用专用资源以独立模式运行它 
  • 您可以在 YARN 集群上运行它,与 Hadoop 和 HDFS 共同驻留 
  • 您可以在 Mesos 集群上与其他 Mesos 应用程序一起运行它 

那么为什么要在 Kubernetes 上运行 Spark 呢?

  • 集群的单一统一接口:Kubernetes 可以管理各种工作负载;无需为数据处理处理 YARN/HDFS,也无需为其他应用程序处理单独的容器编排器。 
  • 提高服务器利用率:在 Spark 和云原生应用程序之间共享节点。例如,您可能有一个流式应用程序正在运行,用于向流式 Spark 管道馈送数据,或者一个 Nginx Pod 用于服务 Web 流量——无需静态划分节点。 
  • 工作负载之间的隔离:Kubernetes 的服务质量机制允许您安全地将 Spark 等批处理工作负载与对延迟敏感的服务器调度到相同的节点上。 

启动 Spark 

对于此演示,我们将使用 Google Container Engine (GKE),但这应该适用于您已安装 Kubernetes 集群的任何地方。首先,使用 storage-full 范围创建一个 Container Engine 集群。这些 Google Cloud Platform 范围将允许集群写入私有 Google Cloud Storage Bucket(我们稍后会解释为什么需要它): 

$ gcloud container clusters create spark --scopes storage-full
--machine-type n1-standard-4

注意:我们使用 n1-standard-4(大于默认节点大小)来演示水平 Pod 自动扩缩的一些功能。但是,Spark 在默认节点大小 n1-standard-1 上运行良好。

集群创建后,您就可以使用 Kubernetes GitHub 存储库中的配置文件在 Kubernetes 上启动 Spark

$ git clone https://github.com/kubernetes/kubernetes.git
$ kubectl create -f kubernetes/examples/spark

‘kubernetes/examples/spark’ 是一个目录,因此此命令告诉 kubectl 创建该目录中所有 YAML 文件中定义的所有 Kubernetes 对象。您不必克隆整个存储库,但这会使此演示的步骤稍微容易一些。

Pod(尤其是 Apache Zeppelin)有点大,因此 Docker 可能需要一些时间来拉取镜像。一切运行后,您应该会看到类似以下的内容

$ kubectl get pods
NAME READY STATUS RESTARTS AGE
spark-master-controller-v4v4y 1/1 Running 0 21h
spark-worker-controller-7phix 1/1 Running 0 21h
spark-worker-controller-hq9l9 1/1 Running 0 21h
spark-worker-controller-vwei5 1/1 Running 0 21h
zeppelin-controller-t1njl 1/1 Running 0 21h

您可以看到 Kubernetes 正在运行一个 Zeppelin 实例、一个 Spark 主节点和三个 Spark 工作节点。

设置到 Zeppelin 的安全代理 

接下来,您将设置从本地机器到 Zeppelin 的安全代理,以便您可以从本地机器访问集群中运行的 Zeppelin 实例。(注意:您需要将此命令更改为集群上创建的实际 Zeppelin Pod。)

$ kubectl port-forward zeppelin-controller-t1njl 8080:8080

这建立了到 Kubernetes 集群和 Pod (zeppelin-controller-t1njl) 的安全链接,然后将相关端口 (8080) 转发到本地端口 8080,这将允许您安全地使用 Zeppelin。

现在 Zeppelin 已经启动并运行,我该如何使用它呢? 

在我们的示例中,我们将向您展示如何构建一个简单的电影推荐模型。这基于 Spark 网站上的代码,略作修改以使其对 Kubernetes 更具吸引力。 

现在安全代理已启动,请访问 https://:8080/。您应该会看到一个介绍页面,如下所示

点击“导入笔记”,给它一个任意名称(例如“电影”),然后点击“从 URL 添加”。对于 URL,输入

https://gist.githubusercontent.com/zmerlynn/875fed0f587d12b08ec9/raw/6
eac83e99caf712482a4937800b17bbd2e7b33c4/movies.json

然后点击“导入笔记”。这将为您提供此演示的现成 Zeppelin 笔记。您现在应该有一个“电影”笔记本(或您命名的任何名称)。如果您点击该笔记,您应该会看到一个类似的屏幕

您现在可以点击 PySpark 代码块右上角的“播放”按钮,您将创建一个新的、内存中的电影推荐模型!在 Spark 应用程序模型中,Zeppelin 作为 Spark 驱动程序,与 Spark 集群主节点交互以完成其工作。在这种情况下,在 Zeppelin Pod 中运行的驱动程序会获取数据并将其发送到 Spark 主节点,主节点将其分发给工作节点,工作节点使用驱动程序中的代码计算出电影推荐模型。如果 Google Cloud Storage (GCS) 中有更大的数据集,也可以轻松地从 GCS 拉取数据。在下一节中,我们将讨论如何将数据保存到 GCS。

使用 Google Cloud Storage(可选) 

对于此演示,我们将使用 Google Cloud Storage,它允许我们存储模型数据,使其超越单个 Pod 的生命周期。Kubernetes 版 Spark 内置了 Google Cloud Storage 连接器。只要您可以在运行 Kubernetes 节点的 Google Container Engine 项目中的虚拟机访问数据,您就可以使用 Spark 镜像上的 GCS 连接器访问数据。

如果您愿意,可以更改笔记顶部的变量,以便示例实际上保存并恢复电影推荐引擎的模型——只需将这些变量指向您可以访问的 GCS 存储桶即可。如果您想创建 GCS 存储桶,您可以在命令行上执行类似以下操作

$ gsutil mb gs://my-spark-models

您需要将此 URI 更改为对您来说独一无二的名称。这将创建一个您可以在上述示例中使用的存储桶。

将水平 Pod 自动扩缩与 Spark 结合使用(可选) 

Spark 对工作节点的来去具有一定的弹性,这意味着我们有机会:我们可以使用 Kubernetes 水平 Pod 自动扩缩来自动扩缩 Spark 工作节点池,为工作节点设置目标 CPU 阈值和最小/最大池大小。这消除了手动配置工作节点副本数量的需要。

像这样创建自动扩缩器(注意:如果您没有更改集群的机器类型,您可能希望将 --max 限制为较小的值): 

$ kubectl autoscale --min=1 --cpu-percent=80 --max=10 \
  rc/spark-worker-controller

要查看自动扩缩的完整效果,请等待复制控制器稳定回一个副本。使用 ‘kubectl get rc’ 并等待 spark-worker-controller 上的“replicas”列回落到 1。

我们之前运行的工作负载运行得太快,对 HPA 来说没有太大意义。要更改工作负载使其运行足够长时间以看到自动扩缩激活,请将代码中的“rank = 100”行更改为“rank = 200”。点击播放后,Spark 工作节点池应该会迅速增加到 20 个 Pod。作业完成后,工作节点池需要长达 5 分钟才能回落到一个副本。

结论

在本文中,我们向您展示了如何在 Kubernetes 上运行 Spark 和 Zeppelin,以及如何使用 Google Cloud Storage 存储 Spark 模型,以及如何使用水平 Pod 自动扩缩动态调整 Spark 工作节点池的大小。

这是一系列关于如何在 Kubernetes 上运行大数据框架的文章中的第一篇——敬请关注!

请加入我们的社区,帮助我们构建 Kubernetes 的未来!有很多参与方式。如果您对 Kubernetes 和大数据特别感兴趣,您会对以下内容感兴趣