Kubernetes 上运行 Spark 和 OzoneFS

本页介绍如何通过以下组件在 Spark 中使用 Ozone 对象存储:

  • OzoneFS (兼容 Hadoop 的文件系统)
  • Hadoop 2.7 (包含在 Spark 发行包中)
  • Kubernetes 的 Spark 调度器
  • 本地 Spark 客户端

准备

下载 Spark 和 Ozone 的最新发行包并解压,本方法使用 spark-2.4.6-bin-hadoop2.7 进行了测试。

你还需要准备以下内容:

  • 用来上传下载 spark+ozone 镜像的仓库(本文档中使用 Docker Hub)
  • 自定义镜像的名称,形如 repo/name(本文档中使用 myrepo/ozone-spark
  • 专门的 Kubernetes 命名空间(本文档中使用 yournamespace

为 driver 创建 docker 镜像

创建 Spark driver/executor 基础镜像

首先使用 Spark 的镜像创建工具创建一个镜像。 在 Spark 发行包中运行以下命令:

  1. ./bin/docker-image-tool.sh -r myrepo -t 2.4.6 build

注意: 如果你使用 Minikube,需要加上 -m 参数来使用 Minikube 镜像的 docker 进程。

  1. ./bin/docker-image-tool.sh -m -r myrepo -t 2.4.6 build

./bin/docker-image-tool.sh 是 Spark 用来创建镜像的官方工具,上面的步骤会创建多个名为 myrepo/spark 的 Spark 镜像,其中的第一个镜像用作接下来步骤的基础镜像。

定制镜像

创建一个用于定制镜像的目录。

从集群中拷贝 ozone-site.xml

  1. kubectl cp om-0:/opt/hadoop/etc/hadoop/ozone-site.xml .

从 Ozone 目录中拷贝 ozonefs.jar使用 hadoop2 版本!

  1. <configuration>
  2. <property>
  3. <name>fs.AbstractFileSystem.o3fs.impl</name>
  4. <value>org.apache.hadoop.fs.ozone.OzFs</value>
  5. </property>
  6. </configuration>

kubectl cp om-0:/opt/hadoop/share/ozone/lib/hadoop-ozone-filesystem-hadoop2-VERSION.jar hadoop-ozone-filesystem-hadoop2.jar

  1. 编写新的 Dockerfile 并构建镜像:

FROM myrepo/spark:2.4.6 ADD core-site.xml /opt/hadoop/conf/core-site.xml ADD ozone-site.xml /opt/hadoop/conf/ozone-site.xml ENV HADOOP_CONF_DIR=/opt/hadoop/conf ENV SPARK_EXTRA_CLASSPATH=/opt/hadoop/conf ADD hadoop-ozone-filesystem-hadoop2.jar /opt/hadoop-ozone-filesystem-hadoop2.jar

  1. ```bash
  2. docker build -t myrepo/spark-ozone

对于远程的 Kubernetes 集群,你可能需要推送镜像:

  1. docker push myrepo/spark-ozone

创建桶并获取 OzoneFS 路径

下载任意文本文件并保存为 /tmp/alice.txt

  1. kubectl port-forward s3g-0 9878:9878
  2. aws s3api --endpoint http://localhost:9878 create-bucket --bucket=test
  3. aws s3api --endpoint http://localhost:9878 put-object --bucket test --key alice.txt --body /tmp/alice.txt

记下 Ozone 文件系统的 URI,在接下来的 spark-submit 命令中会用到它。

创建服务账号

  1. kubectl create serviceaccount spark -n yournamespace
  2. kubectl create clusterrolebinding spark-role --clusterrole=edit --serviceaccount=yournamespace:spark --namespace=yournamespace

运行任务

运行如下的 spark-submit 命令,但需要对下列的值进行修改:

  • kubernetes master url(你可以查看 ~/.kube/config 来获取实际值)
  • kubernetes namespace(本例中为 yournamespace
  • serviceAccountName (如果你按照上面的步骤做了,使用 spark 即可)
  • container.image (在本例中该值为 myrepo/spark-ozone,在上一步中这个镜像被推送至镜像仓库)
  • 输入文件的位置(o3fs://…),使用上面 ozone s3 path <桶名> 命令输出中的字符串即可)
  1. bin/spark-submit \
  2. --master k8s://https://kubernetes:6443 \
  3. --deploy-mode cluster \
  4. --name spark-word-count \
  5. --class org.apache.spark.examples.JavaWordCount \
  6. --conf spark.executor.instances=1 \
  7. --conf spark.kubernetes.namespace=yournamespace \
  8. --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \
  9. --conf spark.kubernetes.container.image=myrepo/spark-ozone \
  10. --conf spark.kubernetes.container.image.pullPolicy=Always \
  11. --jars /opt/hadoop-ozone-filesystem-hadoop2.jar \
  12. local:///opt/spark/examples/jars/spark-examples_2.11-2.4.0.jar \
  13. o3fs://test.s3v.ozone-om-0.ozone-om:9862/alice.txt

使用 kubectl get pod 命令查看可用的 spark-word-count-... pod。

使用 kubectl logs spark-word-count-1549973913699-driver 命令查看计算结果。

输出的结果类似如下:

  1. ...
  2. name: 8
  3. William: 3
  4. this,': 1
  5. SOUP!': 1
  6. `Silence: 1
  7. `Mine: 1
  8. ordered.: 1
  9. considering: 3
  10. muttering: 3
  11. candle: 2
  12. ...