微服務架構日益成熟,不但得到了初創公司和創新型公司的認可,一些傳統企業也在逐步接受微服務架構。我們仍然在學習如何利用其在擴展性,易於維護和構建等方面的優勢。當然我們也必須承擔微服務增加的成本,比如從SOA架構的遷移,編排,備份,以及對技能提升的需求等等。
一個典型的微服務架構可能是這樣的:
-
Touchbase,一個Node.js寫的應用作為技術棧的核心;
-
Nginx,作為Touchbase節點的負載均衡;
-
Couchbase,作為數據層;
-
Consul,服務發現;
-
Containerbuddy,服務發現;
-
CloudFlare-watcher,DNS更新;
-
CloudFlare DNS,DNS服務;
每個組件可能都有備選方案,可以替換,只要改 docker-compose.yml文件就可以。
為什么Docker很適合這樣的架構呢?以下將分別從Docker的優缺點以及在生產環境中使用Docker可能會遇到的挑戰來進行分析,首先讓我們來看Docker帶來的優勢。
優勢
1隔離,抽象,可移植性
容器是操作系統內存中的應用隔離,我們並不知道這些相關的服務是不是運行在同一個機器上,通過容器抽象來共享主機的操作系統資源。得益於Docker,我們可以從頭建立一個分布式應用,根據應用的需求定制環境,並復用在所有Docker主機上。還可以省去不重要安裝,環境依賴,將環境改變控制在容器內,從而保持操作系統的『純凈』。
2輕量級
Docker輕量級,開銷很少,這使得它成為一個開發immutable infrastructure的絕佳工具,並且所有組件都很容易被替代。使用Docker 可以在同一台主機上運行更多的服務和應用,不會產生性能損失和額外的容量。
3版本化的鏡像
Docker通過Docker鏡像來交付環境,你可以用Docker的強大的tag機制指定你的鏡像的版本。這意味着你可以版本化你的整個微服務環境,不管你的應用s用是Java、Python、Ruby還是其它完全獨立於主機操作系統的語言寫的,都可以擁有一個同質的打包系統。
4可復用
Docker組件是可以重用的。之前精心設計的鏡像,可以通過base imge被重用,並且不需要從零開始構建。
5可測試
Dockerfile描述了Docker的環境,以及能夠使我們的應用運行於其上的必要的步驟。每次Docker構建的過程,都是對這個步驟的測試,測試其能否為我們的應用程序執行創建一個完美的運行環境。
6DevOps的思維方式
得益於上述幾點,開發團隊更容易從傳統思維過渡到DevOps的思維方式,關注完整的軟件交付生命周期。Docker可以將IT運維部門從一個繁忙的、簡易的交付批准/拒絕導向的團隊,變成一個有效率的,交付授權的部門,而且開發人員可以在容器內定制自己的運行環境,同時不會影響其他應用。
如此強大的工具!我們為什么不馬上開始開發幾十或者上百個微服務?好吧,因為所有事物都有兩面性。Docker真的是很靈活的工具,但與傳統的,基於虛擬機的解決方案非常不同。
缺陷
1編排
最大的挑戰是容器的生命周期管理。傳統的虛擬機啟動緩慢,在運行時將其狀態保存進虛擬機鏡像,下一次重啟時使用這個改變了的鏡像來繼續運行。它在硬件資源上有顯著的開銷,模塊化程度更低,需要復制鏡像來擴大規模。
Docker對於分層,只讀的鏡像采取了不同的策略,對於給定的容器只存儲變化的部分,這種方式好壞參半。好是因為我們可以從同一個Docker鏡像中快速做出多個實例(即使在多台主機上),其啟動和開銷是最小的。這些屬性使Docker成為了一個出色的immutable infrastructure的工具,但是在Docker中運行有狀態的服務,就需要在寫dockerfiles和管理持久化數據時做一些額外的處理。
2持久化
默認情況下,Docker不會在容器中存儲持久化數據。它只存儲鏡像和容器實例之間的差異。如果你刪除一個容器,你會失去所有數據。為了保持數據獨立於容器生命周期,你應該定義數據卷。
您有2個選擇可以將數據持久化為卷:主機卷或容器卷。主機卷是一個與容器共享的Docker主機上的物理文件夾。容器卷是一個主機上隔離的,私有的空間,並且多個容器共享。管理卷比簡單的虛擬機數據持久化更為復雜。
3調度
在雲中的調度,比一個單一的主機環境更有挑戰性。如何分配任務和應該安排多少實例?如何追蹤雲來擴展任務的生命周期。在Docker容器中使用配置文件是困難的,尤其是在分布式的環境中。調度一個鏡像作為容器可靠地運行,我們需要一個分布式的調度平台例如: ApacheMesos的Chronos或者你可以使用SystemdTimers。無論你選擇哪種方式,都要跟蹤容器的運行狀態等相關細節,並且它應該是系統容錯和默認重啟的。
4Docker不是虛擬機
Docker的設計初衷是為應用提供隔離的環境,並跟蹤文件系統的變化,獨立於主機操作系統的配置。對於長時間運行和復雜的進程也不是那么合適,但我也不那么保守地建議一個應用對應一個容器。現實生活不同於紙上談兵,不是嗎?
5安全性
在公有的服務器上運行Docker容器,與他人共享有一些安全風險,我們需要非常仔細地設計我們的Docker基礎架構。生態系統發展這么快,你應該投入時間研究最新的安全工具,以防止來自容器的安全威脅。
6成熟度
Docker此刻(在推出1.8版本后)還是不成熟的。Docker compose不能在多主機狀態下編排,Docker swarm本身距離商用狀態還有很長的路要走,網絡模式也在試驗中。完全基於Docker的組件還不能建立一個完整的生產環境,但第三方供應商如SaltStack, Kubernetes, ApacheMesos或stackengine、tutum等雲基礎供應商正在非常好地彌補這些缺口。
挑戰
以上從個人觀點闡述了Docker的一些優點和缺點,就讓我們看看當我們實踐的時候會遇到的挑戰和需要注意的地方。
1版本/標簽
Docker鏡像可以由三個要素來描述:namespace,名稱和標簽。namespace是您在公共hub中的用戶名或私有庫的名稱。你可以用它來區分鏡像的功能,比如dev,int,prod;鏡像名稱(hub稱其為庫)是你artifact的名稱;標簽是描述鏡像版本的一個很好的機制,但你應該盡量不用lastest標簽。
2構建自動化
基礎鏡像的手動更新是不可靠的,有風險的。也應測試基礎鏡像並且標記lastest標簽,以保證基礎鏡像的最新版本。
3Rollback and roll forward
在最新的版本發生任何問題的情況下,明確的鏡像版本使rollback變得容易;還可以通過roll forward觸發通過修正的提交。你也可以使用分層釋放/修復和立即改變一組運行實例。
4使用域
Docker不僅可以為你的應用程序提供一個靈活的運行環境,而且你可以建立一整個交付管道,它包括CI / CD服務器和他們的附屬機器,根據需求來動態分配現有的資源。