8 個構建容器應用的最佳實踐
容器是未來在共有雲和私有雲進行應用開發的主要趨勢,但是容器到底是什麼,為什麼它們成為了一種廣受歡迎的部署機制,而且你需要怎樣來修改你的應用來為容器化的環境優化它?
什麼是容器?
容器技術的歷史始於 2000 年的 SELinux 和 2005 年的 Solaris zones。今天,容器是由包括 SELinux、Linux 命名空間和控制組(cgroup)等幾項內核特性構成,提供了用戶進程、網路空間和文件系統空間的隔離。
為什麼它們如此流行?
最近容器技術大規模的應用在很大程度上是由於旨在使容器更加易於使用的標準的發展,例如 Docker 鏡像格式和分布模型,這個標準使用 不可變鏡像 ,這正是容器運行時環境的起點,不可變鏡像可以保證開發團隊發布的鏡像就是經過測試的,和部署到生產環境中的鏡像是同樣的鏡像。
容器所提供的輕量級隔離為一個應用組件提供了一個更好的抽象。在容器中運行的組件將不會干擾其它可能直接運行在虛擬機上的應用。它們可以避免對系統資源的爭奪,而且除非它們共享一個持久卷,否則不會阻止對同一個文件的寫請求。容器使得日誌和指標採集的實踐得以標準化,而且它們可以在物理機和虛擬機上支持更大的用戶密度,所有的這些優點將導致更低的部署成本。
我們應該如何構建一個基於容器的應用呢?
將應用改為運行在容器中並不是什麼很高的要求。主要的 Linux 發行版都有提供了基礎鏡像,任何可以在虛擬機上運行的程序都可以在上面運行。但是容器化應用的趨勢是遵循如下最佳實踐:
1. 實例是一次性的
你的應用的任何實例都不需要小心地保持運行。如果你的一個運行了許多容器的系統崩潰了,你還能夠轉移到其它可用的系統去創建新的容器。
2. 重試而不是崩潰
當你的應用的一個服務依賴於另一個服務的時候,在另一個服務不可用的時候它應該不會崩潰。例如,你的 API 服務正在啟動而且監測到資料庫不能連接。你應該設計它使得其不斷重試連接,而不是運行失敗和拒絕啟動。當資料庫連接斷開的時候 API 可以返回 503 狀態碼,告訴客戶端服務現在不可用。應用應該已經遵守了這個實踐,但是如果你正在一個一次性實例的容器環境中工作,那麼對這個實踐的需要會更加明顯。
3. 持久性數據是特殊的
容器是基於共享鏡像啟動,它使用了寫時複製(COW)文件系統。如果容器的進程選擇寫入文件,那麼這些寫的內容只有在直到容器存在時才存在。當容器被刪除的時候,寫時複製文件系統中的那一層會被刪除。提供給容器一個掛載的文件系統目錄,使之在容器存活之外也能持久保存,這需要另外的配置,而且會額外消耗物理存儲。明確的抽象定義了什麼存儲是持久的,催生出了實例是一次性的觀點。擁有一個抽象層也使得容器編製引擎可以處理掛載和卸載持久卷的複雜請求,以便這些持久卷可以用於容器。
4. 使用 stdout 而不是日誌文件
現在你或許會思考,如果持久的數據是特殊的,那麼我用日誌文件來做什麼事情?容器運行時環境和編製引擎項目所採用的方法是進程應該寫入 stdout/stderr,而且具有歸檔和維護容器日誌的基礎設施。
5. 敏感信息(以及其它配置信息)也是特殊的
你絕不應該將敏感信息例如密碼、密鑰和證書硬編碼到你的鏡像中。通常在你的應用與開發服務、測試服務,或者生產服務相交互時,這些敏感信息通常都是不同的。大多數開發者並沒有訪問生產環境的敏感信息的許可權,所以如果敏感信息被打包到鏡像中,那麼必須創建一個新的鏡像層來覆蓋這個開發服務的敏感信息。基於這一點來看,你再也不能使用與你們開發團隊所創建的和質量測試所測試的相同的鏡像了,而且也失去了不可修改的鏡像的好處。相反的,這些值應該被存儲在環境變數中文件中,它們會在容器啟動時導入。
6. 不要假設服務的協同定位
在一個編排好的容器環境中,你會希望讓編排器將你的容器發送到任何最適合的節點。最適合意味著很多事情:它應該基於那個節點現在擁有最多的空間、容器所需的服務質量、容器是否需要持久卷,等等。這可能意味這你的前端、API 和資料庫容器最終都會放在不同的節點。儘管給每個節點強制分配一個 API 容器是可以做到的(參考 Kubernetes 的 DaemonSets),但這種方式應該留給執行監控節點自身這類任務的容器。
7. 冗餘/高可用計劃
即使你沒有那麼多負載需要高可用性的配置,你也不應該以單路方式編寫服務,否則會阻止它運行多份拷貝。這將會允許你運用滾動式部署,使得將負載從一個節點移動到另外一個節點非常容易,或者將服務從一個版本更新到下一個版本而不需要下線。
8. 實現就緒檢查和靈活性檢查
應用在響應請求之前會有一定的啟動時間是一件很正常的事情,例如,一個 API 伺服器需要填充內存數據緩存。容器編排引擎需要一種方法來檢測你的容器是否準備好服務用戶請求。為一個新的容器提供就緒檢查可以允許我們進行滾動式部署,使得舊容器可以繼續運行直到不再需要它,這可以防止服務宕機。類似的,一個存活檢查也是一種容器編排引擎持續檢查容器是否在健康可用狀態的方法。決定容器健康或者說「存活」應該由容器應用的創建者說了算。一個不再存活的容器將會被結束,而且一個新的容器會被創建來替代它。
想查找更多資料?
我將會出席十月份的格雷絲霍普計算機女性峰會(Grace Hopper Celebration of Women in Computing),你可以在這裡來看一下關於我的訪談:應用的容器化:是什麼,為什麼,和如何實現。今年不去 GHC 嗎?那你可以在 OpenShift 和 Kubernetes 的項目站點來了解關於容器、編排和應用的相關內容。
via: https://opensource.com/life/16/9/8-best-practices-building-containerized-applications
作者:Jessica Forrester 譯者:LinuxBars 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive