隨著kubernetes的發展,大資料體系擁抱k8s成為了必經之路。
從Spark 2.4 版本開始,Spark 實驗性支援 Kubernetes 作為資源管理器。不過雖然是實驗性質,但是已經有很多單位將之用於生產環境了,並取得很好的效果,在可移植性,可擴充套件性,成本等方面都取得了收益。
本文主要解讀一下Spark 3.0 對於kubernetes的增強。
本文共分為5個部分,每個部分都有一個功能類別。你將首先看到配置更改,然後是執行時環境和安全性增強。之後,將瞭解Kubernetes的主要發展之一-pod模板。到文章末尾,將瞭解到從貢獻者的角度來看發生了什麼變化。
配置此類別的第一個重要更改是配置驗證。從Apache Spark 3.0開始,與模式 [-._a-zA-Z][-._a-zA-Z0-9]* 不匹配的Kubernetes屬性(帶有 spark.executorEnv 字首)將被忽略並顯示警告訊息如下:
Invalid key: ... a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit.
在3.0版本中,可以使用 spark.kubernetes.driver.request.cores 屬性為 driver 請求特定數量的CPU核。而 executor 的屬性(spark.kubernetes.executor.request.cores)自Spark 2.4.0起可用。
除此之外,還添加了一些時間控制屬性。使用 spark.kubernetes.submission.connectionTimeout 和 spark.kubernetes.submission.requestTimeout ,可以控制連線和請求超時,以在客戶端模式下啟動 executor 程式。還存在兩個類似的屬性來處理請求 driver 的相同超時( spark.kubernetes.driver.requestTimeout , spark.kubernetes.driver.connectionTimeout )。
執行時環境另一類功能與執行時環境有關。首先,對於PySpark的使用者,Python 3是Docker映象中的預設繫結(仍支援版本2)
// Default change in the config val PYSPARK_MAJOR_PYTHON_VERSION = ConfigBuilder("spark.kubernetes.pyspark.pythonVersion") .doc("This sets the major Python version. Either 2 or 3. (Python2 or Python3)") .version("2.4.0") .stringConf .checkValue(pv => List("2", "3").contains(pv), "Ensure that major Python version is either Python2 or Python3") .createWithDefault("3") // was "2" in Spark 2.4.0
如果對繫結感到好奇,可以仔細研究以下的程式碼:
# /resource-managers/kubernetes/docker/src/main/dockerfiles/spark/entrypoint.shif [ "$PYSPARK_MAJOR_PYTHON_VERSION" == "2" ]; then pyv="$(python -V 2>&1)" export PYTHON_VERSION="${pyv:7}" export PYSPARK_PYTHON="python" export PYSPARK_DRIVER_PYTHON="python"elif [ "$PYSPARK_MAJOR_PYTHON_VERSION" == "3" ]; then pyv3="$(python3 -V 2>&1)" export PYTHON_VERSION="${pyv3:7}" export PYSPARK_PYTHON="python3" export PYSPARK_DRIVER_PYTHON="python3"fi
關於Scala-Spark API,第一個執行時演進涉及JDK版本。你可能已經知道,Apache Spark 3.0直接跳過了版本9和10的相容性工作之後,添加了對JDK版本11(SPARK-24417)的支援。在Kubernetes部分中實現了這一支援,並提供了一個示例,該示例使用來自docker-image-tool.sh 的Java 11標記構建的Spark Docker映象:
$0 -r docker.io/myrepo -t v3.0.0 -b java_image_tag=11-jre-slim build
最後,為了最佳化測試執行,Apache Spark 3.0測試映象使用JRE而不是JDK。
安全增強在下一類別中,可以找到所有重要的安全增強功能。關於容器,最佳實踐之一是不在映象中使用root使用者。在以前的版本中,從專案的docker-image-tool.sh構建的映象使用根目錄。它在3.0中進行了更改,因為該指令碼設定了可以用 -u 引數覆蓋的預設使用者。
第二個重要演變是關於secret編輯。在Apache Spark 3.0之前,UI和日誌中僅顯示帶有“ secret”或“ password”之類的配置屬性的值。在3.0中,針對該Kubernetes伺服器身份驗證中使用的 spark.kubernetes.authenticate.submission.oauthToken 屬性,向該列表添加了一個新配置“令牌”。
最後,Apache Spark 3.0還添加了在叢集和客戶端模式下對Kerberos的支援。回想一下,Kerberos是一種基於票證的網路身份驗證協議,用於解決非安全網路中的身份問題。在Apache Spark上下文中,此功能有助於與HDFS或任何其他kerberized服務進行安全通訊。
可擴充套件性下一個重要功能是可擴充套件性。 Kubernetes附帶了一個稱為Pod模板的YAML規範,可用於建立和執行新Pod。 社群選擇它作為定製請求的替代方法。在此之前,必須將任何新的Kubernetes選項新增到Apache Spark配置檔案中。從長遠來看,這可能會增加Kubernetes和Spark之間的差距,並使該專案難以維護。
擴充套件在Kubernetes上執行的Apache Spark Pod的一種靈活方法是使用這些屬性中的Pod模板,即 driver 的 spark.kubernetes.driver.podTemplateFile 和 executor 的 spark.kubernetes.executor.podTemplateFile 。重要的是要注意,某些模板屬性永遠不會覆蓋Apache Spark配置管理的值,例如,用於名稱空間或pod重啟策略的屬性。
隨著Kubernetes的發展,Pod的引數會逐步增加,單純依靠命令列引數,會變得越來越複雜。對於Pod模板的支援,一是可以降低spark 對於k8s版本的耦合,二是表達力更加豐富。
測試最佳化新版本的Apache Spark測試中用更加輕量級更強大的Minio取代了Ceph。
此外,還為secret測試添加了更好的錯誤訊息處理。同樣,具有不可預測的Thread.sleep的併發控制元件也被偵聽器和基於CountDownLatch的編排所替代(有關Java類的更多資訊,請參見CountDownLatch)。
除此之外,還為Apache Spark 2.4中引入的功能添加了一些額外的整合測試。其中之一涉及持久卷。
結論按照社群規劃,從Apache Spark 3.1.0開始,Kubernetes資源管理器的狀態將從試驗性變為一般可用性,並會增加很多新功能。在翻譯本文的時候,Apache Spark 3.1.0 已經release,是時候將我們的spark 執行到 k8s 中了。