運行支持Kubernetes原生調度的Spark程序-Spark on Kubernetes

TL;DR 直接見 jimmysong.io/spark-on-k

Spark 原生就是一個適合在分散式系統中運行的大數據處理軟體,現在已支持Hadoop Yarn、Mesos,kubernetes的支持還在開發中,現在就說的就是這個 spark-on-kubernetes,而將spark運行在kubernetes上,如何還用Yarn或Mesos就多了一層調度,將使資源調度的效率大打折扣,同時也增加了系統的複雜度,將spark直接使用kubernetes原生調度將是最佳方案,可以最大程度上的利用kubernetes集群的資源。

我們之前就在 kubernetes 中運行過 standalone 方式的 spark 集群,見 Spark standalone on kubernetes。

目前運行支持 kubernetes 原生調度的 spark 程序項目由 Google 主導,fork 自 spark 的官方代碼庫,見 github.com/apache-spark ,屬於Big Data SIG。

參與到該項目的公司有:

  • Bloomberg
  • Google
  • Haiwen
  • Hyperpilot
  • Intel
  • Palantir
  • Pepperdata
  • Red Hat

為何使用 Spark on Kuberentes

使用 kubernetes 原生調度的 spark on kubernetes 是對原有的 spark on yarn 革命性的改變,主要表現在以下幾點:

  1. Kubernetes 原生調度:不再需要二層調度,直接使用 kubernetes 的資源調度功能,跟其他應用共用整個 kubernetes 管理的資源池;
  2. 資源隔離,粒度更細:原先 yarn 中的 queue 在 spark on kubernetes 中已不存在,取而代之的是 kubernetes 中原生的 namespace,可以為每個用戶分別指定一個 namespace,限制用戶的資源 quota;
  3. 細粒度的資源分配:可以給每個 spark 任務指定資源限制,實際指定多少資源就使用多少資源,因為沒有了像 yarn 那樣的二層調度(圈地式的),所以可以更高效和細粒度的使用資源;
  4. 監控的變革:因為做到了細粒度的資源分配,所以可以對用戶提交的每一個任務做到資源使用的監控,從而判斷用戶的資源使用情況,所有的 metric 都記錄在資料庫中,甚至可以為每個用戶的每次任務提交計量;
  5. 日誌的變革:用戶不再通過 yarn 的 web 頁面來查看任務狀態,而是通過 pod 的 log 來查看,可將所有的 kuberentes 中的應用的日誌等同看待收集起來,然後可以根據標籤查看對應應用的日誌;

所有這些變革都能幫助我們更高效的獲的、有效的利用資源,提高生產效率。

Spark 概念說明

Apache Spark 是一個圍繞速度、易用性和複雜分析構建的大數據處理框架。最初在2009年由加州大學伯克利分校的AMPLab開發,並於2010年成為Apache的開源項目之一。

在 Spark 中包括如下組件或概念:

  • Application:Spark Application 的概念和 Hadoop 中的 MapReduce 類似,指的是用戶編寫的 Spark 應用程序,包含了一個 Driver 功能的代碼和分布在集群中多個節點上運行的 Executor 代碼;
  • Driver:Spark 中的 Driver 即運行上述 Application 的 main() 函數並且創建 SparkContext,其中創建 SparkContext 的目的是為了準備Spark應用程序的運行環境。在 Spark 中由 SparkContext 負責和 ClusterManager 通信,進行資源的申請、任務的分配和監控等;當 Executor 部分運行完畢後,Driver負責將SparkContext 關閉。通常用 SparkContext 代表 Driver;
  • Executor:Application運行在Worker 節點上的一個進程,該進程負責運行Task,並且負責將數據存在內存或者磁碟上,每個Application都有各自獨立的一批Executor。在Spark on Yarn模式下,其進程名稱為CoarseGrainedExecutorBackend,類似於 Hadoop MapReduce 中的 YarnChild。一個 CoarseGrainedExecutorBackend進程有且僅有一個 executor 對象,它負責將 Task 包裝成 taskRunner,並從線程池中抽取出一個空閑線程運行 Task。每個 CoarseGrainedExecutorBackend 能並行運行 Task 的數量就取決於分配給它的 CPU 的個數了;
  • Cluster Manager:指的是在集群上獲取資源的外部服務,目前有:
    • Standalone:Spark原生的資源管理,由Master負責資源的分配;
    • Hadoop Yarn:由YARN中的ResourceManager負責資源的分配;
  • Worker:集群中任何可以運行Application代碼的節點,類似於YARN中的NodeManager節點。在Standalone模式中指的就是通過Slave文件配置的Worker節點,在Spark on Yarn模式中指的就是NodeManager節點;
  • 作業(Job):包含多個Task組成的並行計算,往往由Spark Action催生,一個JOB包含多個RDD及作用於相應RDD上的各種Operation;
  • 階段(Stage):每個Job會被拆分很多組 Task,每組任務被稱為Stage,也可稱TaskSet,一個作業分為多個階段,每一個stage的分割點是action。比如一個job是:(transformation1 -> transformation1 -> action1 -> transformation3 -> action2),這個job就會被分為兩個stage,分割點是action1和action2。
  • 任務(Task): 被送到某個Executor上的工作任務;
  • Context:啟動spark application的時候創建,作為Spark 運行時環境。
  • Dynamic Allocation(動態資源分配):一個配置選項,可以將其打開。從Spark1.2之後,對於On Yarn模式,已經支持動態資源分配(Dynamic Resource Allocation),這樣,就可以根據Application的負載(Task情況),動態的增加和減少executors,這種策略非常適合在YARN上使用spark-sql做數據開發和分析,以及將spark-sql作為長服務來使用的場景。Executor 的動態分配需要在 cluster mode 下啟用 「external shuffle service」。
  • 動態資源分配策略:開啟動態分配策略後,application會在task因沒有足夠資源被掛起的時候去動態申請資源,這意味著該application現有的executor無法滿足所有task並行運行。spark一輪一輪的申請資源,當有task掛起或等待 spark.dynamicAllocation.schedulerBacklogTimeout (默認1s)時間的時候,會開始動態資源分配;之後會每隔 spark.dynamicAllocation.sustainedSchedulerBacklogTimeout (默認1s)時間申請一次,直到申請到足夠的資源。每次申請的資源量是指數增長的,即1,2,4,8等。之所以採用指數增長,出於兩方面考慮:其一,開始申請的少是考慮到可能application會馬上得到滿足;其次要成倍增加,是為了防止application需要很多資源,而該方式可以在很少次數的申請之後得到滿足。

架構設計

關於 spark standalone 的局限性與 kubernetes native spark 架構之間的區別請參考 Anirudh Ramanathan 在 2016年10月8日提交的 issue Support Spark natively in Kubernetes #34377。

簡而言之,spark standalone on kubernetes 有如下幾個缺點:

  • 無法對於多租戶做隔離,每個用戶都想給 pod 申請 node 節點可用的最大的資源。
  • Spark 的 master/worker 本來不是設計成使用 kubernetes 的資源調度,這樣會存在兩層的資源調度問題,不利於與 kuberentes 集成。

而 kubernetes native spark 集群中,spark 可以調用 kubernetes API 獲取集群資源和調度。要實現 kubernetes native spark 需要為 spark 提供一個集群外部的 manager 可以用來跟 kubernetes API 交互。

調度器後台

使用 kubernetes 原生調度的 spark 的基本設計思路是將 spark 的 driver 和 executor 都放在 kubernetes 的 pod 中運行,另外還有兩個附加的組件:ResourceStagingServer 和 KubernetesExternalShuffleService。

Spark driver 其實可以運行在 kubernetes 集群內部(cluster mode)可以運行在外部(client mode),executor 只能運行在集群內部,當有 spark 作業提交到 kubernetes 集群上時,調度器後台將會為 executor pod 設置如下屬性:

  • 使用我們預先編譯好的包含 kubernetes 支持的 spark 鏡像,然後調用 CoarseGrainedExecutorBackend main class 啟動 JVM。
  • 調度器後台為 executor pod 的運行時注入環境變數,例如各種 JVM 參數,包括用戶在 spark-submit 時指定的那些參數。
  • Executor 的 CPU、內存限制根據這些注入的環境變數保存到應用程序的 SparkConf 中。
  • 可以在配置中指定 spark 運行在指定的 namespace 中。

參考:Scheduler backend 文檔

安裝指南

我們可以直接使用官方已編譯好的 docker 鏡像來部署,下面是官方發布的鏡像:

組件 -> 鏡像

Spark Driver Image -> kubespark/spark-driver:v2.1.0-kubernetes-0.3.1

Spark Executor Image -> kubespark/spark-executor:v2.1.0-kubernetes-0.3.1

Spark Initialization Image -> kubespark/spark-init:v2.1.0-kubernetes-0.3.1

Spark Staging Server Image -> kubespark/spark-resource-staging-server:v2.1.0-kubernetes-0.3.1

PySpark Driver Image -> kubespark/driver-py:v2.1.0-kubernetes-0.3.1

PySpark Executor Image -> kubespark/executor-py:v2.1.0-kubernetes-0.3.1

我將這些鏡像放到了我的私有鏡像倉庫中了。

還需要安裝支持 kubernetes 的 spark 客戶端,在這裡下載:github.com/apache-spark

根據使用的鏡像版本,我下載的是 v2.1.0-kubernetes-0.3.1

運行 SparkPi 測試

./bin/spark-submit n --deploy-mode cluster n --class org.apache.spark.examples.SparkPi n --master k8s://https://172.20.0.113:6443 n --kubernetes-namespace spark-cluster n --conf spark.executor.instances=5 n --conf spark.app.name=spark-pi n --conf spark.kubernetes.driver.docker.image=sz-pg-oam-docker-hub-001.tendcloud.com/library/kubespark-spark-driver:v2.1.0-kubernetes-0.3.1 n --conf spark.kubernetes.executor.docker.image=sz-pg-oam-docker-hub-001.tendcloud.com/library/kubespark-spark-executor:v2.1.0-kubernetes-0.3.1 n --conf spark.kubernetes.initcontainer.docker.image=sz-pg-oam-docker-hub-001.tendcloud.com/library/kubespark-spark-init:v2.1.0-kubernetes-0.3.1 nlocal:///opt/spark/examples/jars/spark-examples_2.11-2.1.0-k8s-0.3.1-SNAPSHOT.jarn

關於該命令參數的介紹請參考:apache-spark-on-k8s.github.io

注意: 該 jar 包實際上是 spark.kubernetes.executor.docker.image 鏡像中的。

這時候提交任務運行還是失敗,報錯信息中可以看到兩個問題:

  • Executor 無法找到 driver pod
  • 用戶 system:serviceaccount:spark-cluster:defaul 沒有許可權獲取 spark-cluster 中的 pod 信息。

提了個 issue Failed to run the sample spark-pi test using spark-submit on the doc #478

需要為 spark 集群創建一個 serviceaccount 和 clusterrolebinding:

kubectl create serviceaccount spark --namespace spark-clusternkubectl create rolebinding spark-edit --clusterrole=edit --serviceaccount=spark-cluster:spark --namespace=spark-clustern

該 Bug 將在新版本中修復。

開發文檔

編譯

Fork 並克隆項目到本地:

git clone https://github.com/rootsongjc/spark.gitn

編譯前請確保你的環境中已經安裝 Java8 和 Maven3。

## 第一次編譯前需要安裝依賴nbuild/mvn install -Pkubernetes -pl resource-managers/kubernetes/core -am -DskipTestsnn## 編譯 spark on kubernetesnbuild/mvn compile -Pkubernetes -pl resource-managers/kubernetes/core -am -DskipTestsnn## 發布ndev/make-distribution.sh --tgz -Phadoop-2.7 -Pkubernetesn

第一次編譯和發布的過程耗時可能會比較長,請耐心等待,如果有依賴下載不下來,請自備梯子。

詳細的開發指南請見:github.com/apache-spark

構建鏡像

使用該腳本來自動構建容器鏡像:github.com/apache-spark

將該腳本放在 dist 目錄下,執行:

./build-push-docker-images.sh -r sz-pg-oam-docker-hub-001.tendcloud.com/library -t v2.1.0-kubernetes-0.3.1-1 buildn./build-push-docker-images.sh -r sz-pg-oam-docker-hub-001.tendcloud.com/library -t v2.1.0-kubernetes-0.3.1-1 pushn

注意:如果你使用的 MacOS,bash 的版本可能太低,執行改腳本將出錯,請檢查你的 bash 版本:

bash --versionnGNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)nCopyright (C) 2007 Free Software Foundation, Inc.n

上面我在升級 bash 之前獲取的版本信息,使用下面的命令升級 bash:

brew install bashn

升級後的 bash 版本為 4.4.12(1)-release (x86_64-apple-darwin16.3.0)。

編譯並上傳鏡像到我的私有鏡像倉庫,將會構建出如下幾個鏡像:

sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver:v2.1.0-kubernetes-0.3.1-1nsz-pg-oam-docker-hub-001.tendcloud.com/library/spark-resource-staging-server:v2.1.0-kubernetes-0.3.1-1nsz-pg-oam-docker-hub-001.tendcloud.com/library/spark-init:v2.1.0-kubernetes-0.3.1-1nsz-pg-oam-docker-hub-001.tendcloud.com/library/spark-shuffle:v2.1.0-kubernetes-0.3.1-1nsz-pg-oam-docker-hub-001.tendcloud.com/library/spark-executor:v2.1.0-kubernetes-0.3.1-1nsz-pg-oam-docker-hub-001.tendcloud.com/library/spark-executor-py:v2.1.0-kubernetes-0.3.1-1nsz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver-py:v2.1.0-kubernetes-0.3.1-1n

運行測試

在 dist/bin 目錄下執行 spark-pi 測試:

./spark-submit n --deploy-mode cluster n --class org.apache.spark.examples.SparkPi n --master k8s://https://172.20.0.113:6443 n --kubernetes-namespace spark-cluster n --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark n --conf spark.executor.instances=5 n --conf spark.app.name=spark-pi n --conf spark.kubernetes.driver.docker.image=sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver:v2.1.0-kubernetes-0.3.1-1 n --conf spark.kubernetes.executor.docker.image=sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-executor:v2.1.0-kubernetes-0.3.1-1 n --conf spark.kubernetes.initcontainer.docker.image=sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-init:v2.1.0-kubernetes-0.3.1-1 nlocal:///opt/spark/examples/jars/spark-examples_2.11-2.2.0-k8s-0.4.0-SNAPSHOT.jarn

詳細的參數說明見:apache-spark-on-k8s.github.io

注意:local:///opt/spark/examples/jars/spark-examples_2.11-2.2.0-k8s-0.4.0-SNAPSHOT.jar 文件是在 spark-driver 和 spark-executor 鏡像里的,在上一步構建鏡像時已經構建並上傳到了鏡像倉庫中。

執行日誌顯示:

2017-09-14 14:59:01 INFO Client:54 - Waiting for application spark-pi to finish...n2017-09-14 14:59:01 INFO LoggingPodStatusWatcherImpl:54 - State changed, new state:nt pod name: spark-pi-1505372339796-drivernt namespace: spark-clusternt labels: spark-app-selector -> spark-f4d3a5d3ad964a05a51feb6191d50357, spark-role -> drivernt pod uid: 304cf440-991a-11e7-970c-f4e9d49f8ed0nt creation time: 2017-09-14T06:59:01Znt service account name: sparknt volumes: spark-token-zr8wvnt node name: N/Ant start time: N/Ant container images: N/Ant phase: Pendingnt status: []n2017-09-14 14:59:01 INFO LoggingPodStatusWatcherImpl:54 - State changed, new state:nt pod name: spark-pi-1505372339796-drivernt namespace: spark-clusternt labels: spark-app-selector -> spark-f4d3a5d3ad964a05a51feb6191d50357, spark-role -> drivernt pod uid: 304cf440-991a-11e7-970c-f4e9d49f8ed0nt creation time: 2017-09-14T06:59:01Znt service account name: sparknt volumes: spark-token-zr8wvnt node name: 172.20.0.114nt start time: N/Ant container images: N/Ant phase: Pendingnt status: []n2017-09-14 14:59:01 INFO LoggingPodStatusWatcherImpl:54 - State changed, new state:nt pod name: spark-pi-1505372339796-drivernt namespace: spark-clusternt labels: spark-app-selector -> spark-f4d3a5d3ad964a05a51feb6191d50357, spark-role -> drivernt pod uid: 304cf440-991a-11e7-970c-f4e9d49f8ed0nt creation time: 2017-09-14T06:59:01Znt service account name: sparknt volumes: spark-token-zr8wvnt node name: 172.20.0.114nt start time: 2017-09-14T06:59:01Znt container images: sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver:v2.1.0-kubernetes-0.3.1-1nt phase: Pendingnt status: [ContainerStatus(containerID=null, image=sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver:v2.1.0-kubernetes-0.3.1-1, imageID=, lastState=ContainerState(running=null, terminated=null, waiting=null, additionalProperties={}), name=spark-kubernetes-driver, ready=false, restartCount=0, state=ContainerState(running=null, terminated=null, waiting=ContainerStateWaiting(message=null, reason=ContainerCreating, additionalProperties={}), additionalProperties={}), additionalProperties={})]n2017-09-14 14:59:03 INFO LoggingPodStatusWatcherImpl:54 - State changed, new state:nt pod name: spark-pi-1505372339796-drivernt namespace: spark-clusternt labels: spark-app-selector -> spark-f4d3a5d3ad964a05a51feb6191d50357, spark-role -> drivernt pod uid: 304cf440-991a-11e7-970c-f4e9d49f8ed0nt creation time: 2017-09-14T06:59:01Znt service account name: sparknt volumes: spark-token-zr8wvnt node name: 172.20.0.114nt start time: 2017-09-14T06:59:01Znt container images: sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver:v2.1.0-kubernetes-0.3.1-1nt phase: Runningnt status: [ContainerStatus(containerID=docker://5c5c821c482a1e35552adccb567020532b79244392374f25754f0050e6cd4c62, image=sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver:v2.1.0-kubernetes-0.3.1-1, imageID=docker-pullable://sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver@sha256:beb92a3e3f178e286d9e5baebdead88b5ba76d651f347ad2864bb6f8eda26f94, lastState=ContainerState(running=null, terminated=null, waiting=null, additionalProperties={}), name=spark-kubernetes-driver, ready=true, restartCount=0, state=ContainerState(running=ContainerStateRunning(startedAt=2017-09-14T06:59:02Z, additionalProperties={}), terminated=null, waiting=null, additionalProperties={}), additionalProperties={})]n2017-09-14 14:59:12 INFO LoggingPodStatusWatcherImpl:54 - State changed, new state:nt pod name: spark-pi-1505372339796-drivernt namespace: spark-clusternt labels: spark-app-selector -> spark-f4d3a5d3ad964a05a51feb6191d50357, spark-role -> drivernt pod uid: 304cf440-991a-11e7-970c-f4e9d49f8ed0nt creation time: 2017-09-14T06:59:01Znt service account name: sparknt volumes: spark-token-zr8wvnt node name: 172.20.0.114nt start time: 2017-09-14T06:59:01Znt container images: sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver:v2.1.0-kubernetes-0.3.1-1nt phase: Succeedednt status: [ContainerStatus(containerID=docker://5c5c821c482a1e35552adccb567020532b79244392374f25754f0050e6cd4c62, image=sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver:v2.1.0-kubernetes-0.3.1-1, imageID=docker-pullable://sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver@sha256:beb92a3e3f178e286d9e5baebdead88b5ba76d651f347ad2864bb6f8eda26f94, lastState=ContainerState(running=null, terminated=null, waiting=null, additionalProperties={}), name=spark-kubernetes-driver, ready=false, restartCount=0, state=ContainerState(running=null, terminated=ContainerStateTerminated(containerID=docker://5c5c821c482a1e35552adccb567020532b79244392374f25754f0050e6cd4c62, exitCode=0, finishedAt=2017-09-14T06:59:11Z, message=null, reason=Completed, signal=null, startedAt=null, additionalProperties={}), waiting=null, additionalProperties={}), additionalProperties={})]n2017-09-14 14:59:12 INFO LoggingPodStatusWatcherImpl:54 - Container final statuses:nnnt Container name: spark-kubernetes-drivernt Container image: sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver:v2.1.0-kubernetes-0.3.1-1nt Container state: Terminatednt Exit code: 0n2017-09-14 14:59:12 INFO Client:54 - Application spark-pi finished.n

從日誌中可以看到任務運行的狀態信息。

使用下面的命令可以看到 kubernetes 啟動的 Pod 信息:

kubectl --namespace spark-cluster get pods -wn

將會看到 spark-driver 和 spark-exec 的 Pod 信息。

依賴管理

上文中我們在運行測試程序時,命令行中指定的 jar 文件已包含在 docker 鏡像中,是不是說我們每次提交任務都需要重新創建一個鏡像呢?非也!如果真是這樣也太麻煩了。

創建 resource staging server

為了方便用戶提交任務,不需要每次提交任務的時候都創建一個鏡像,我們使用了 resource staging server

kubectl create -f conf/kubernetes-resource-staging-server.yamln

我們同樣將其部署在 spark-cluster namespace 下,該 yaml 文件見 kubernetes-handbook 的 manifests/spark-with-kubernetes-native-scheduler 目錄。

優化

其中有一點需要優化,在使用下面的命令提交任務時,使用 --conf spark.kubernetes.resourceStagingServer.uri 參數指定 resource staging server 地址,用戶不應該關注 resource staging server 究竟運行在哪台宿主機上,可以使用下面兩種方式實現:

  • 使用 nodeSelector 將 resource staging server 固定調度到某一台機器上,該地址依然使用宿主機的 IP 地址
  • 改變 spark-resource-staging-service service 的 type 為 ClusterIP, 然後使用 Ingress 將其暴露到集群外部,然後加入的內網 DNS 里,用戶使用 DNS 名稱指定 resource staging server 的地址。

然後可以執行下面的命令來提交本地的 jar 到 kubernetes 上運行。

./spark-submit n --deploy-mode cluster n --class org.apache.spark.examples.SparkPi n --master k8s://https://172.20.0.113:6443 n --kubernetes-namespace spark-cluster n --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark n --conf spark.executor.instances=5 n --conf spark.app.name=spark-pi n --conf spark.kubernetes.driver.docker.image=sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-driver:v2.1.0-kubernetes-0.3.1-1 n --conf spark.kubernetes.executor.docker.image=sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-executor:v2.1.0-kubernetes-0.3.1-1 n --conf spark.kubernetes.initcontainer.docker.image=sz-pg-oam-docker-hub-001.tendcloud.com/library/spark-init:v2.1.0-kubernetes-0.3.1-1 n --conf spark.kubernetes.resourceStagingServer.uri=http://172.20.0.114:31000 n ../examples/jars/spark-examples_2.11-2.2.0-k8s-0.4.0-SNAPSHOT.jarn

該命令將提交本地的 ../examples/jars/spark-examples_2.11-2.2.0-k8s-0.4.0-SNAPSHOT.jar 文件到 resource staging server,executor 將從該 server 上獲取 jar 包並運行,這樣用戶就不需要每次提交任務都編譯一個鏡像了。

詳見:apache-spark-on-k8s.github.io

設置 HDFS 用戶

如果 Hadoop 集群沒有設置 kerbros 安全認證的話,在指定 spark-submit 的時候可以通過指定如下四個環境變數, 設置 Spark 與 HDFS 通信使用的用戶:

--conf spark.kubernetes.driverEnv.SPARK_USER=hadoop n --conf spark.kubernetes.driverEnv.HADOOP_USER_NAME=hadoop n --conf spark.executorEnv.HADOOP_USER_NAME=hadoop n --conf spark.executorEnv.SPARK_USER=hadoop n

詳見:github.com/apache-spark

參考

Spark動態資源分配-Dynamic Resource Allocation

Running Spark on Kubernetes

Apache Spark Jira Issue - 18278 - SPIP: Support native submission of spark jobs to a kubernetes cluster

Kubernetes Github Issue - 34377 Support Spark natively in Kubernetes

Kubernetes example spark

github.com/rootsongjc/s

原文地址:運行支持kubernetes原生調度的spark程序 : jimmysong.io

推薦閱讀:

TAG:Kubernetes | Spark | cloudnative |