標籤:

容器化應用的設計原則

本文轉載自我的blog: martinliu.cn

本文來自於Red Hat諮詢顧問Bilgin Ibryam所編寫的一篇白皮書,名為《PRINCIPLES OF CONTAINER-BASED APPLICATION DESIGN》。這篇文章在作者的Blog上發表後,作者的twitter被Kubernetes官方twitter轉發。白皮書在Red Hat官網的下載地址:redhat.com/en/resources 文本是對這篇文章的學習和整理。

先回顧經典的軟體設計原則:

  • 保持簡單,愚蠢(KISS)
  • 不要重複自己(DRY)
  • 你不會需要它 (YAGNI)
  • 關注點分離(SoC)
  • Single responsibility, Open/closed, Liskov substitution, Interface segregation, Dependency inversion (SOLID)

然後是Red Hat的雲原生容器設計原則:

  • 唯一關注性原則(SCP)
  • 高度可觀測性原則(HOP)
  • 生命周期一致性原則(LCP)
  • 鏡像不可變性原則(IIP)
  • 進程可處置性原則(PDP)
  • 自包含性原則(S-CP)
  • 運行時約束性原則(RCP)

很多組織都理解雲原生的重要性和必要性,但是並不知道從哪裡開始。那麼請確保:雲原生平台和容器化應用能無縫的運行在一起,並且具備抵禦故障的能力,甚至在底層的基礎架構出現宕機的時候,也能通過過彈性擴展的方式表現出可靠性。本文描述了容器化應用時需要遵循的基本準則,實施這些原則有助於使之與雲原生平台Kubernetes更加適配。

唯一關注性原則 SINGLE CONCERN PRINCIPLE(SCP)

在許多方面,唯一關注性原則與來自SOLID的SRP是類似的,它建議一個類應該只有一個責任。SRP背後的動機是每個責任是變更的一個軸心,一個類應該有,且也只有一個需要改變的理由。SCP原則中的「關注」一詞強調關注是一種更高層次的抽象的責任,而且它更好地將範圍描述為一個容器而不是一個類。雖然SRP的主要動機是變化原因的唯一性,而SCP的主要動機是容器鏡像重用和可替換性。如果你創建一個解決單個問題的容器,並且以功能完整的方式來實現,不同應用程序中的容器鏡像重用的可能性就會更高。

因此,SCP原則規定每個集容器都應該解決一個問題,並做得很好。 實現這一點,通常比在面向對象的世界中實現SRP更容易,容器通常管理的一個單一的進程,大多數情況下一個進程解決一個問題。

如果你的容器化微服務需要解決多個問題,它可以使用這樣的模式,將多個容器用sidecar和init-containers的模式合併成一個部署單元(pod),這樣每個容器仍然是處理單個問題。同樣,您可以替換處理同樣問題的容器。 例如,將Web伺服器容器或隊列實現容器,更新為更具可擴展性的容器。

高度可觀測性原則 HIGH OBSERVABILITY PRINCIPLE(HOP)

容器提供了一種統一的方式來打包和運行應用程序,將它們視為一個黑盒子對象。 但任何旨在成為雲原生公民的容器都必須提供API支持,要為運行時環境編寫介面(API),以觀察容器的健康狀況和行為。 這是自動化容器更新和生命周期回收的基本先決條件和統一的方式,從而提高系統的彈性和用戶體驗。

實際上,您的容器化應用程序必須至少為其提供不同類型的健康檢查的API–活動和就緒等狀態。更好的應用程序的行為則必須提供其他手段來觀察容器化應用程序的狀態。應用程序應該將重要事件記錄到標準錯誤(STDERR)和標準輸出(STDOUT)中,從而通過統一的日誌聚合工具(諸如Fluentd和Logstash之類的工具)進行分析,並與跟蹤和指標收集庫相結合,例如OpenTracing,Prometheus等。

將您的應用程序視為黑盒子,但實施所有必要的API以幫助平台對其進行觀測,並以最佳方式管理您的應用程序。

生命周期一致性原則 LIFE-CYCLE CONFORMANCE PRINCIPLE(LCP)

HOP規定了你的容器提供供平台觀測的API。 LCP則規定:您的應用程序有辦法讀取來自平台的事件。 此外,除了獲得事件以外,容器還應該對這些事件相應地作出反應。這就是此原則名字由來。這幾乎就像在應用程序通過一個「寫入API」與平台進行交互。

來自管理平台的各種事件都是為了幫助您管理您的容器的生命周期的。決定處理哪些事件取決於您的應用程序 以及是否對這些事件做出反應。

但有些事件比其他事件更重要。例如,任何需要一個乾淨的關閉進程,這就需要捕獲信號:終止(SIGTERM)消息,並儘可能迅速關閉。 這是為了避免通過強制關閉信號:kill(SIGKILL),之後跟隨一個SIGTERM。

還有其他事件,例如PostStart和PreStop,可能對您的應用程序生命周期管理也非常重要。 例如,某些應用程序需要在服務之前進行預熱請求和一些需要在關閉乾淨之前釋放資源。

鏡像不可變性原則 IMAGE IMMUTABILITY PRINCIPLE(IIP)

IMAGE IMMUTABILITY PRINCIPLE(IIP)容器化的應用程序是不可變更的,鏡像一旦完成了構建,預計在不同的環境中運行都不會改變。這意味著在因外部環境的不同,在需要的時候需要使用外部手法處理所依賴的外部配置數據,而不是每個環境修改或者構建不同的容器。而容器應用程序中的任何變更,都應該因此觸發構建新的容器映像,並在所有環境中重用它。相同於這個原理的,不可變伺服器和不可變基礎架構的概念也很受歡迎,並且對於伺服器/主機管理也是如此。

在遵循IIP原則的情況下,應該防止為不同的環境創建相似的容器鏡像,要始終堅持為所有環境只配置一個容器映像。 這個原則允許在應用程序更新期間,採用自動回滾和前滾等做法,這是雲原生自動化的重要方面。

進程可處置性原則 PROCESS DISPOSABILITY PRINCIPLE(PDP)

遷移到容器應用程序的主要動機之一是:容器需要儘可能做到臨時性,並做好在任何時候被另一個容器實例替換的準備。需要更換容器的原因有很多,比如:健康檢查失敗、縮容、應用程序將容器遷移到不同的主機,平台資源匱乏或其它的問題。

這意味著容器化的應用程序必須保持其狀態為向外擴展的或分散式和冗餘的。這也意味著應用程序應該快速啟動和關閉,甚至為徹底的硬體故障做好準備。 實施這一原則的另一個有用的做法是創建小容器。 容器在雲原生環境可以自動調度並在不同的主機上啟動。較小的容器可以實現更快啟動時間,因為在重新啟動之前容器鏡像需要被物理地複製到主機系統。

自包含性原則 SELF-CONTAINMENT PRINCIPLE(S-CP)

這個原則規定一個容器應該在構建時包含所有需要的東西。容器的存在應該僅僅依賴於Linux?內核,在並添加相關額外的庫,在容器構建時加入它們。除了庫之外,它還應該包含語言運行時,應用程序平台(如果需要),以及運行所需的其他依賴關係,等運行容器化應用所需要的諸如此類的東西。

唯一的例外是:由於不同環境之間差異,並且只能在運行時提供的配置; 例如,通過Kubernetes提供的ConfigMap。

某些應用程序由多個容器組件組成。 例如,容器化的Web應用程序也可能需要資料庫容器。 根據這個原則,並不建議合併兩個容器。相反,它建議的是資料庫容器只包含運行資料庫所需的所有內容,Web應用程序容器只包含運行Web應用程序所需的所有內容,如Web伺服器。 在運行時,Web應用程序容器將根據需要依賴於並訪問資料庫容器。

運行時約束性原則 RUNTIME CONFINEMENT PRINCIPLE(RCP)

S-CP從構建時的角度查看容器,並關注於生成的二進位文件及其內容。但是容器不僅僅是磁碟上一個只有尺寸大小的單一維度的黑盒子。 容器運行時有多個維度,例如內存使用維度,CPU使用維度等資源消耗維度。

這個RCP原則建議每個容器申報資源需求,並發送信息到平台。它應該分享容器的資源配置文件,從CPU,內存,網路,磁碟的角度聲明。這影響到平台如何執行調度,自動擴展,容量 管理以及容器常規的服務級別協議(SLA)等。

除了向平台聲明容器的資源需求之外,還有一點也很重要, 應用被約束在使用所聲明的資源需求內。如果應用程序對資源的使用保持在約束的範圍內,則當資源匱乏發生時,平台不太可能將其終止和遷移。

結論

雲原生不僅僅是一種最終狀態 - 它也是一種工作方式。 本份白皮書描述了一系列容器應用的基本原則,必須遵守才能成為優秀的雲原生公民。

除了這些原則之外,創建良好的容器應用程序還需要熟悉其他容器相關的最佳實踐和技術。 儘管上述原則非常根本,適用於大多數用例,下面列出的最佳實踐在應用和不應用的時候,則需要判斷力。以下是一些與容器相關的更常見的最佳實踐:

  • 鏡像要儘可能的小。 通過清理臨時文件,並避免安裝不必要的軟體包來構建小尺寸鏡像。 這減少了容器的尺寸,構建時間和複製容器鏡像的網路傳輸時間。
  • 支持任意用戶ID。 避免使用sudo命令或要求特定用戶名運行你的容器。
  • 標記重要的埠。 雖然可以在運行時指定埠號,然而使用EXPOSE命令在運行的時候指定,則可以讓鏡像的使用者更輕鬆。
  • 為持久數據使用卷。 在容器摧毀之後還需要保存的容器數據的,必須將數據寫入一個數據卷。
  • 設置鏡像元數據。 以標籤和注釋形式存在的鏡像元數據可以使您的容器鏡像更加實用,從而為使用您的容器的開發人員提供了更好的體驗。
  • 使主機和鏡像同步。 一些容器應用需要容器在某些屬性(如時間和機器ID)上與主機同步。

這裡是指向各種模式和最佳實踐的資源的鏈接,以幫助您能有效地實現上述目標:

  • ? slideshare.net/luebken/
  • ? docs.docker.com/engine/
  • ? docs.projectatomic.io/c
  • ? docs.openshift.com/ente
  • ? usenix.org/system/files
  • ? leanpub.com/k8spatterns
  • ? https://12factor.net

推薦閱讀:

4大維度3大預測,基於容器生態擴張的DevSecOps為啥引關注?
在 2016 年做 DevOps 是一種什麼樣的體驗?
四大語言,八大框架|滴滴全鏈路壓測解決之道

TAG:DevOps |