KubeFlow-Pipeline及Argo實現原理速析


Argo是一個開源原生容器工作流引擎用於在Kubernetes上開發和運行應用程序。Argo Workflow流程引擎,可以編排容器流程來執行業務邏輯,在20年4月8日進入CNCF孵化器組。

而KubeFlow的Pipeline子項目,由Google開源,其全面依賴Argo作為底層實現,並增強持久層來補充流程管理能力,同時通過Python-SDK來簡化流程的編寫。

一. Argo流程引擎

Argo的步驟間可以傳遞信息,即下一步(容器)可以獲取上一步(容器)的結果。結果傳遞有2種:

1. 文件:上一步容器新生成的文件,會直接出現在下一步容器里面。

2. 信息:上一步的執行結果信息(如某文件內容),下一步也可以拿到。

下面我們就來解讀一下,Argo怎么實現“信息”在容器間的傳遞的,以及它和其他的流程引擎實現傳遞的區別。

1.1文件怎么從上一個容器跑到下一個容器里的?

Argo流程,可以指定2個步驟之間,傳遞結果文件(Artifact)。即假設流程為:A->B,那么A容器跑完,B容器可以取得上一個容器的輸出文件。

如下:A容器生成一個 /tmp/hello_world.txt 文件,Argo將這個文件,放到了B容器里面,並重命名為 /tmp/message文件。

注意:流程上的每個步驟,都對應執行一個容器。 在A跑完后容器就退出了,然后才跑的B(這時候已經沒有A容器在運行了)。

所以Argo怎么把一個文件從A容器“拷貝”到B容器里面的?

1.1.1容器間通過共享存儲?(NO)

一般容器間共享文件,首先想到的都是:咱使用共享存儲呀,大家都掛載同一個PVC不就行了。

確實共享存儲可以實現容器共享文件,但是這里Argo可以:

(1)任意指定文件傳遞。(2)傳遞后文件可以改名字。

這2個是共享Volume做不到的,畢竟容器掛載目錄得提前設定好,然后文件名大家看到的也是一樣的。所以顯然文件傳遞,不是通過共享PVC掛載實現的。

(Ps:不過Argo也在考慮這種實現方式,畢竟共享目錄不需要任何額外IO,透傳效率更高。見:

1.1.2通過管理面中轉?(YES)

沒有共享目錄,那中轉文件,只能是通過先取出來,再塞回去的方式嘍。實際上Argo也確實這么做的,只是實現上還有些約束。

(1)“臨時中轉倉庫”需要引入第三方軟件(Minio)

(2)文件不能太大

(3)需要在用戶容器側,增加“代理”幫忙上傳&下載文件。

1.1.3中轉文件具體實現(docker cp)

現在我們打開Argo看看具體怎么實現的。因為你要取一個容器里面的文件,或者把一個文件放入一個容器,也不容易實現呢。

(1)小滑頭Argo居給用戶容器設置了一個SideCar容器,通過這個SideCar去讀取用戶的文件,然后上傳到臨時倉庫。

(2) 一個Pod里面的兩個Container,文件系統也是獨立的,並不能直接取到另一個Container的文件。所以Sidecar容器為了取另一個容器里的文件,又把主機上面的docker.sock掛載進來了。這樣就相當於拿到了主機Root權限,可以任意cp主機上任意容器里面的文件。

事實上,Sidecar里面取文件的實現是:

docker cp -a 023ce:/tmp/hello_world.txt - | gzip > /argo/outputs/artifacts/hello-art.tgz

感覺稍微有點暴力。

1.1.4中轉實現的其他方式

實際上,通過sidecar容器提權到root權限,然后從用戶的容器里面copy任意文件(即 docker cp命令),只是Argo默認的實現。畢竟它自己也發現這樣做安全上有點說不過去。

所以呢,它也留了其他方式去copy用戶容器里面的文件。比如:kubectl 也是可以cp容器里面的文件的嘛。其他方式可參見:

1.2 下一步容器怎么拿到上一步容器的結果?

Argo流程,2個步驟之間,除了傳遞文件,還可以傳遞結果信息(Information)。如:A->B,那么A容器跑完,B容器可以取得上一個容器的一些Information(不是整個文件)。

一般流程引擎透傳信息,都是中轉:

不過顯然Argo自己沒有存儲Information的臨時倉庫,所以它得找個地方記錄這些臨時待中轉的information(雖然Argo找了Minio這個對象存儲用來暫存中轉文件,但是顯然這貨只能存文件,沒有存Metadata元數據功能)。這里Argo又找了Pod里面的Annotation字段,當做臨時中轉倉庫。先把信息記這里,下一步容器想要,就來這里取。

相信這里應該是有更好的實現方式的,這種把信息記錄到Annotation的做法,約束比較大的(特別是ETCD的單個對象不能超過1M大小)。

可以考慮使用單獨的Configmap來中轉也可以。

二. KubeFlow-Pipeline項目

KubeFlow-Pipeline項目(簡稱KFP),是Kubeflow社區開源的一個工作流項目,用於管理、部署端到端的機器學習工作流。KFP提供了一個流程管理方案,方便將機器學習中的應用代碼按照流水線的方式編排部署,形成可重復的工作流。

2.1為什么要在Argo之上重新開發一套?

部署一套Argo很簡單,啟動一個K8s-Controller就行。可是部署一套Kubeflow-Pipeline系統就復雜多了,總共下來有8個組件。那是Argo什么地方不足,需要新開發一套KFP,並搞這么復雜呢?主要的原因還在於Argo是基於K8s雲原生這套理念,即ETCD充當“數據庫”來運行的,導致約束比較大。

像:流程模板,歷史執行記錄,這些大量的信息很明顯需要一個持久化層(數據庫)來記錄的,單純依賴ETCD會有單條記錄不能超過1M,總記錄大小不能超過8G的約束。

所以一個完整的流程引擎,包含一個數據庫也都是很常規的。因此KFP在這一層做了較大的增強。

另外,在ML領域的用戶界面層,KFP也做了較多的用戶體驗改進。包括可以查看每一步的訓練輸出結果,直接通過UI進行可視化的圖形展示。

2.2 Kubeflow-Pipeline后續演進點

見:

Dag引擎組件的水平擴展(HPA)是其重要的一個特性,也是要成為一個成熟引擎所必要的能力。

當前KFP在穩定性以及組件的水平擴展上都還有待改進,因此商業使用還需要一段時間,這將是KFP未來的一個重要目標。

同時,使用權限過於高的Sidecar容器作為其實現步驟之間元數據傳遞的途徑,也會是KFP生產級使用的一道門檻。或許在權限控制方面,KFP需要思考一下其他規避途徑,至少需要稍微增強一下。

概括一下:(1)水平擴展(HPA),(2)生產級可靠性,(3)安全增強。

三. 流程引擎核心&分層

3.1 DAG核心

一個DAG流程引擎,核心代碼也就7行大概能實現了:

例如下圖示例:遍歷發現步驟D沒有依賴其他步驟,那么本次可以執行D步驟。

所以一般程序員一周時間總能開發一個“還能用”的流程引擎。但是完整的流程引擎卻並不輕松

3.2 世界上為什么有這么多的流程引擎

DAG基礎核心非常簡單,同時,各個領域想要做的事情卻迥然不同。即使一個簡單的步驟,大數據步驟說:“這一步要執行的SQL語句是xxx”,而K8s任務步驟卻說:“這一步執行需要的Docker鏡像是yyy”。

所以,各種各樣的流程引擎就自然的出現了。

舉幾個例子:

AWS:Cloudformation編排,Batch服務,SageMaker-ML Pipeline,Data Pipeline

Azure:Pipeline服務,ML Pipeline,Data Factory

Aliyun:函數Pipeline服務,ROS資源編排,Batch服務,PAI-Studio

大數據領域:Oozie,AirFlow

軟件部署:Puppet,Chef,Ansible

基因分析:DNAnexus,NextFlow,Cromwell

每個領域總能找出一兩個流程引擎,來控制誰先干活誰后干活。

總結一下:

(1)DAG引擎核心很小

(2)各領域步驟的描述方式不一樣

這就是為什么各個領域,總會有一個自己的流程引擎,而不像K8s能一統容器平台一樣,出現一個能一統江湖的流程引擎。

3.3 DAG引擎分層架構

成熟的流程引擎,應該有如下4層架構:

第一層:用戶交互層。如:模板語法規則,Console界面等

第二層:API持久化層。如:模板記錄,歷史執行記錄等

第三層:引擎實例層。如:能否水平擴容,流程是否有優先級等

第四層:驅動層。如:一個步驟能干什么活。跑一個容器還是跑一個Spark任務。

基本比較成熟的引擎都符合這種架構,例如AirFlow流程引擎,華為雲的應用編排(AOS)引擎,數據湖工廠(DLF)引擎等都是如此。

目前Argo以及Kubeflow-Pipeline在引擎核心組件的水平擴展上,也即第三層引擎能力層稍有不足。同時其驅動層,目前也只能對接K8s(即只能跑容器任務)。在選型的時候需要考慮進去。

 

點擊關注,第一時間了解華為雲新鮮技術~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM