前言
寫Dockerfile是構建Docker鏡像最通常的方式,接觸過Docker的童鞋多少了解一些。前段時間研究OpenShift(paas的一種),發現了另外一種構建Docker鏡像的方式:S2I。
S2I介紹
S2I是Source-to-Image的縮寫。
S2I是一套工具包和工作流程,用於從源代碼構建重復性Docker鏡像。
S2I是一個框架,它使寫鏡像變得簡單。它把程序源代碼作為輸入,生成一個運行已組裝應用程序的新鏡像並作為輸出。
S2I的詳細介紹以及使用方法可以參考以下官方文檔。本文就不復述(fan yi)了。
兩種構建方式的過程
Talk is Cheap, Show me the Picture.
先上圖。
源代碼只是構建鏡像的多種輸入的一種,還有二進制文件等其它輸入。鏡像構建的過程也比較復雜。下圖是為了清晰地進行對比,所以畫得簡單一些。
由上圖可以看出,Dockerfile方式的構建過程比較直接:
- 根據Dockerfile定義的步驟,讀取源代碼,生成鏡像(成品)。
而S2I方式的構建過程比較“曲折”:
- 根據Dockerfile定義的步驟,准備鏡像環境、讀取S2I腳本,構建鏡像(中間)<又稱構建器鏡像 Builder Image>。
- 基於上一步生成的鏡像(中間),讀取源代碼,根據S2I腳本定義的步驟編譯源代碼、部署二進制程序、八戒影院預備服務啟動,構建鏡像(成品)。
從上述過程可以看出,S2I方式比Dockerfile方式多了一步,多了兩樣東西:S2I腳本和鏡像(中間)。
S2I腳本介紹
S2I腳本有4種。
- assemble: 負責構建程序,即編譯、部署程序。
- run: 負責啟動應用。
- save-artifacts: 負責增量構建(鏡像),目前尚未使用。
- usage: 負責打印構建器鏡像的使用說明。
S2I方式的好處
關於引入S2I構建鏡像的好處,書面類的描述可以參考官方文檔,這里談談實踐下來個人的感受和理解。
首先,要了解為什么要引入S2I。
如果一定要把構建鏡像分為兩部分,可以分為
-
環境准備
- 定義基礎鏡像;
- 安裝所需部件,如Maven、Java JDK;
- 拷貝/移動文件/目錄;
- 定義用戶;
- 暴露端口等。
-
源代碼相關
- 編譯源代碼;
- 部署二進制程序;
- 定義服務啟動方式等。
引入S2I的目的就是為了分離
這兩部分的工作。
其中環境准備工作交給了構建器鏡像,
構建器鏡像一旦生成將保持不變,可理解為靜態部分。
而源代碼相關工作交給了S2I腳本。
在構建鏡像(成品)過程中,S2I將根據S2I腳本定義的步驟進行源代碼編譯、二進制程序部署、服務啟動預備,可以理解為動態部分。
這樣的分離帶來了如下好處。
- 對於環境依賴相近、構建部署啟動過程相似的程序,由於有構建器鏡像的存在,構建過程不需要再次進行環境准備工作,從而節省了構建鏡像(成品)的時間。
- 分工明確。構建工作的分離允許應用程序開發人員對他們的代碼進行更改,而不用知道Dockerfile或Docker鏡像的細節。如果鏡像構建交付給S2I或PaaS(platform as a service)平台,開發工程師不需要理解Docker來對項目作出貢獻。第九影院這在一個由很多人組成的企業環境中是非常有用的,這些人都有不同的專業方向,而且並不直接涉及到他們項目的構建過程。