我從開源項目中學習到的Docker經驗
最近幾周從一個Web開發儼然搖身一變成了“運維”,在GitHub上面為 re:dash 做Docker化的支持。在整個Code Review的過程中汲取了一些Docker的經驗。
不要build
不要在構建Docker鏡像的時候build。這里的build指的是將代碼編譯至production-ready的過程。例如,在一個Web應用中,用make將靜態資源最小化(minify)、拼接(concatenate),以及配置文件的生成等。

仔細思考Docker要解決的主要問題,就是如何跨越操作系統的限制進行部署。因此構建Docker鏡像的過程中,我們也只應該專注鏡像本身環境的搭建,例如系統軟件、python依賴項等。python的依賴項是比較特殊的,因為它們一般是安裝在系統層面上的。
如果是Node.js的非全局依賴項,那么也無需在鏡像中來下載安裝,而是在build的過程中下載,然后直接在 Dockerfile 中Copy到鏡像中。
合理地將相同的指令結合
Docker在構建鏡像的過程中,每運行 Dockerfile 的一個指令,都會構建出一個 layer 。一個鏡像就是由許多的 layer 疊加而成的,這樣的設計允許Docker能夠緩存我們鏡像中特定的一些部分,之后如果對 Dockerfile 進行修改的話,一般情況下能通過緩存加快構建的效率。
RUN apt-get update RUN apt-get -y install libpq-dev postgresql-client
上面兩條RUN指令分別會創建兩個layer。當指令數量過多的時候,layer就會多到爆了,甚至會提示你磁盤空間已經不夠用了。
更好的方式是將兩條相同的指令合理地合成一條。
RUN apt-get update && \ apt-get -y install libpq-dev postgresql-client
這樣構建過程中就只會產生一個layer,減少磁盤空間的消耗。
鏡像應該各司其職
每個鏡像應該各司其職,這背后的主要目的是為了可擴展性考慮。
如果你有一個這樣的鏡像……

那么你可能覺得很方便!的確,你只要簡單地docker run一下就可以結束工作,到一旁喝咖啡了。
但是當你的應用需要擴展(scale)的時候,你可能就要抓耳撓腮了。將所有的東西通通放在一個容器里面,你就沒有辦法做橫向的擴展。
橫向擴展,也稱作 X-axis scaling ,主要通過復制現有的服務來提高該服務的可用性、并通過負載均衡將請求分散給該服務的諸多“復制品”,提供服務的速率等。橫向擴展是3D擴展模型(# Dimensions to Scaling)中的一種。

其中,橫向擴展(X-axis scaling)通過復制的方式。縱向擴展(Y-axis scaling)通過將應用功能分解,每個服務運行的代碼都不同。最后一個Z-axis scaling通過將數據劃分成多塊,并由多個服務使用。每個服務上運行的代碼是一致的,而所負責的數據分區則不同。如果你感興趣,可以看 The Scale Cube 這篇文章(上面的圖片出于此)。
如果一個鏡像中同時打包了一個Web應用、postgres和nginx三個不同的服務,那么我們就無法單獨地對Web App本身進行復制,橫向擴展;也無法對單獨將postgres的數據進行擴展。
相反,如果這三個服務分別被構建到不同的Docker鏡像之后,我們就可以輕松地進行擴展了。在這之中,可以應用 Docker Compose 輕松啟動一系列的鏡像,并將它們互相連接在一起。