如何使用Kubernetes構建12要素應用程序?

聽說有12個因素定義了雲原生應用程序。也有人說Kubernetes專爲雲原生計算而設計。那麼如何使用Kubernetes建立12要素應用程序?讓咱們來看看到底什麼是十二因子應用程序,以及它們與Kubernetes的關係。git

什麼是12 因素應用?

十二因子應用程序是Heroku建立的軟件即服務架構的宣言。這個想法是,爲了真正適合SaaS並避免軟件侵蝕的問題-隨着時間的流逝,未更新的應用程序將與最新的操做系統,安全補丁等不一樣步-應遵循一個應用程序這12條原則:github

  • 基準代碼
    在修訂控制中跟蹤一個代碼庫,許多部署
  • 依賴
    明確聲明和隔離依賴項
  • 配置
    將配置存儲在環境中
  • 後端服務
    將支持服務視爲附加資源
  • 構建,發佈,運行
    嚴格分開的構建和運行階段
  • 進程
    將應用程序做爲一個或多個無狀態進程執行
  • 端口綁定
    經過端口綁定導出服務
  • 併發
    經過流程模型進行橫向擴展
  • 易處理
    經過快速啓動和正常關閉最大程度地提升魯棒性
  • 開發環境和線上環境等價
    保持開發,測試和生產環境儘量類似
  • 日誌
    將日誌視爲事件流
  • 管理進程
    一次性運行管理/管理任務

讓咱們看一下這一切對Kubernetes應用程序的意義。sql

原則 I. 基準代碼

12因子應用程序的原則1是「一份基礎代碼庫,經過版本管理,實現多個部署」。數據庫

對於Kubernetes應用程序,該原理實際上已嵌入到容器編排自己的本質中。一般,您使用git repo之類的源代碼控制存儲庫建立代碼,而後將特定版本的鏡像存儲在Docker Hub中。當您定義要做爲Kubernetes Pod,Deployment,DaemonSet的一部分進行編排的容器時,還能夠指定鏡像的特定版本,以下所示:編程

... 
    spec:
       containers:
       - name: AcctApp
         image: acctApp:v3
 ...

這樣,您可能會在不一樣的部署中運行多個版本的應用程序。後端

應用程序的運行方式也可能有所不一樣,具體取決於配置信息。安全

原則 II. 依賴

12因素應用程序的原則2是「顯式聲明和隔離依賴項」。服務器

實際上,要確保知足應用程序的依賴關係。對於12因子應用程序,這不只包括確保可使用特定於應用程序的庫,還不包括期望操做系統,並假設系統庫(例如curl)在那裏。 12因子應用程序必須是獨立的。網絡

這包括確保應用程序足夠隔離,不會受到主機上可能安裝的衝突庫的影響。架構

幸運的是,若是應用程序確實有任何特定或不尋常的系統要求,則容器能夠輕鬆知足這兩個要求。容器包括應用程序所依賴的全部依賴關係,而且還提供了容器在其中運行的合理隔離的環境。 (與流行的見解相反,容器環境不是徹底隔離的,可是在大多數狀況下,它們足夠好。)

對於模塊化且依賴於其餘組件(例如HTTP服務和日誌提取器)的應用程序,Kubernetes提供了一種將全部這些組件組合到單個Pod中的方法,以實現適當封裝這些組件的環境。

原則 III. 配置

12因素應用程序的原則3是「在環境中存儲配置」。

該原理背後的思想是,應用程序應徹底獨立於其配置。換句話說,您應該可以將其移動到另外一個環境,而無需改變源代碼。

一些開發人員經過建立某種類型的配置文件,指定詳細信息(例如目錄,主機名和數據庫憑據)來實現此目標。這是一項改進,可是確實存在有人將配置文件簽入源代碼控制存儲庫的風險。

相反,有12個因子的應用程序將其配置存儲爲環境變量。正如宣言所述,它們「不太可能被偶然檢查到存儲庫中」,而且它們獨立於操做系統。

Kubernetes使您能夠經過Downward API在清單中指定環境變量,可是因爲這些清單自己確實受到檢查的int源代碼控制,因此這不是一個完整的解決方案。

相反,您能夠指定環境變量應由Kubernetes ConfigMap或Secrets的內容填充,這些內容能夠與應用程序分開保存。例如,您能夠將Pod定義爲:

a-01.jpg

如您所見,此Pod接收三個環境變量SECRET_USERNAME,SECRET_PASSWORD和CONFIG_VERSION,前兩個來自引用的Kubernetes Secrets,第三個來自Kubernetes ConfigMap。這使您能夠將它們保留在配置文件以外。

固然,仍然存在有人對用於建立這些對象的文件進行錯誤處理的風險,可是將它們放在一塊兒並制定安全的處理策略比清除散佈在部署中的數十個配置文件要大。

並且,社區中的一些人指出,即便環境變量因爲其自身的緣由也不必定是安全的。例如,若是應用程序崩潰,則可能會將全部環境變量保存到日誌中,甚至將其傳輸到另外一個服務。 DiogoMónica指出了一種可與Kubernetes一塊兒使用的名爲Keywhiz的工具,可建立安全的祕密存儲。

原則 IV. 後端服務

12因素應用程序的原則4是「將後端服務做爲附加資源」。

在12因子應用程序中,不屬於核心應用程序的任何服務(例如數據庫,外部存儲或消息隊列)都應做爲服務(經過HTTP或相似請求)進行訪問,並在配置中指定,以即可以更改服務源,而不會影響應用程序的核心代碼。

例如,若是您的應用程序使用消息隊列系統,則應該可以從RabbitMQ更改成ZeroMQ(或ActiveMQ甚至其餘功能),而無需更改配置信息。

對於基於Kubernetes的應用程序,此要求有兩個含義。

首先,這意味着您必須考慮應用程序如何接收(和分發)信息。例如,若是您有一個支持數據庫,那麼即便將其複製到其餘實例,您也不想擁有一個本地Mysql實例。相反,您但願有一個單獨的容器來處理數據庫操做,並使這些操做可經過API調用。這樣,若是您須要更改成PostgreSQL或遠程託管的MySQL服務器,則能夠建立一個新的容器鏡像,更新Pod定義,而後從新啓動Pod(或更多是由Deployment或StatefulSet管理它)。

一樣,若是您將憑據或地址信息存儲在ConfigMap支持的環境變量中,則能夠更改該信息並替換Pod。

請注意,這兩個示例均假設儘管您未對源代碼(甚至主應用程序的容器鏡像)進行任何更改,但仍須要替換Pod;作到這一點的能力其實是12因素應用程序的另外一項原則。

Principle V. 構建,發佈,運行

12 Factor App的原則5是「嚴格分開的構建和運行階段」。

現在,很難想象會有這樣的狀況,可是十二要素應用程序必須具備單獨的構建階段。換句話說,您應該可以構建或編譯代碼,而後將其與特定的配置信息結合起來以建立特定的發行版,而後有意地運行該發行版。

發佈應該是可識別的。您應該能夠說「此部署正在運行此應用程序的1.14版本」或相似的內容,就像咱們說咱們在運行「 OpenStack Ocata版本」或「 Kubernetes 1.6」同樣。它們也應該是不變的。任何更改應致使新版本。若是這聽起來使人生畏,請記住,當咱們說「應用程序」時,咱們再也不在談論大型的總體發行版。取而代之的是,咱們談論的是很是具體的微服務,每一個微服務都有其本身的發行版,而且能夠在不引發使用服務錯誤的狀況下提升發行版。

全部這些都是爲了讓應用程序運行時,該「運行」過程能夠徹底自動化。十二因子應用程序須要可以以自動化方式運行,由於它們須要可以在出現問題時從新啓動。

將其轉換爲Kubernetes領域,咱們已經說過,該應用程序須要存儲在源代碼管理中,而後使用其全部依賴項進行構建。這就是您的構建過程。咱們討論了分離配置信息,所以須要將其與構建結合在一塊兒以發佈版本。自動運行應用程序或應用程序的多個副本的能力正是Kubernetes像Deployments,ReplicaSets和DaemonSets那樣構造的。

原則 VI. 進程

12因素應用程序的原則6是「將應用程序做爲一個或多個無狀態進程執行」。

無狀態進程是雲本機應用程序背後的核心思想。每一個十二要素應用程序都須要在單獨的,無共享的流程中運行。這意味着,每當您須要保留信息時,就須要將其存儲在數據庫等支持服務中。

若是您是雲應用程序編程的新手,那麼這看似簡單。許多開發人員習慣於「粘性」會話,並在下一個請求將到達同一服務器的狀況下將信息存儲在會話中。可是,在雲應用程序中,絕對不能作這個假設。

相反,若是您運行的是託管特定Pod的多個副本的基於Kubernetes的應用程序,則必須假定後續請求能夠到達任何地方。要解決此問題,您將須要使用某種後備卷或數據庫來實現持久性。

對此原則的一個警告是,Kubernetes StatefulSets可使您建立具備穩定網絡身份的Pod,所以從理論上講,您能夠將請求定向到特定Pod。從技術上講,若是該過程實際上沒有存儲狀態,而且能夠刪除和從新建立Pod並仍能正常運行,那麼它能夠知足此要求。

原則 VII. 端口綁定

12 Factor App的原則7是「經過端口綁定導出服務」。

在咱們假設不一樣功能由不一樣進程處理的環境中,很容易就能夠經過諸如HTTP之類的協議來實現這些功能的鏈接,所以,一般在Web服務器(如Apache)以後運行應用程序或Tomcat。可是,十二要素應用程序不該該以這種方式依賴於其餘應用程序。請記住,每一個功能都應處於本身的進程中,與其餘全部事物隔離。相反,《 12因子應用宣言》建議添加一個Web服務器庫或與應用自己相似的東西,以便該應用能夠在已定義的端口上等待請求,不管是使用HTTP仍是其餘協議。

在基於Kubernetes的應用程序中,這部分是經過應用程序自己的體系結構完成的,部分是經過確保應用程序具備全部依賴項做爲建立應用程序所基於的基礎容器的一部分來完成的。

原則 VIII. 併發

12 Factor App的原則8是「經過進程模型進行橫向擴展」。

在編寫包含十二個要素的應用程序時,請確保將其設計爲橫向擴展而不是縱向擴展。這意味着,爲了增長容量,您應該可以向運行該應用程序的計算機添加更多實例,而不是添加更多內存或CPU。請注意,這特別意味着可以在其餘計算機上啓動其餘進程,幸運的是,這是Kubernetes的一項關鍵功能。

原則 IX. 易處理

12 Factor App的原則9是「經過快速啓動和平穩關閉來最大化魯棒性」。

彷佛該原理是針對容器和基於Kubernetes的應用程序量身定製的。進程應爲一次性的想法意味着,在任什麼時候候,一個應用程序均可能死亡,而且不會由於任何其餘事情要代替它,由於它會從新啓動而對用戶形成影響,或者二者兼而有之。

固然,容器是基於此原理構建的,即便面對問題(例如ReplicaSets),Kubernetes結構也能夠管理多個實例並保持必定級別的可用性,從而構成了完整的部署。

原則 X. 開發環境和線上環境等價

12因素應用程序的原則10是「保持開發,測試和生產儘量類似」。

這彷佛是另外一條原則,但彷佛比大多數人認爲的要深。從表面上看,這確實意味着您應具備儘量相同的開發,階段和生產環境。實現此目的的一種方法是使用Kubernetes命名空間,使您可以(理論上)在相同的實際集羣上針對相同的實際系統運行代碼,同時仍保持環境分離。在某些狀況下,您還可使用Minikube或kubeadm-dind-cluster之類的工具來建立生產系統的近克隆。

不過,從更深層次上講,如《十二個因子》應用宣言所說,它涉及三種不一樣類型的「鴻溝」:

  • 時間鴻溝:開發人員可能須要花費數天,數週甚至數月的時間才能完成生產的代碼。
  • 人員方面的鴻溝:開發人員編寫代碼,由運維工程師進行部署。
  • 工具之間的鴻溝:開發人員可能正在使用Nginx,SQLite和OS X之類的堆棧,而生產部署則使用Apache,MySQL和Linux。

這裏的目標是建立一個持續集成/持續部署的狀況,在這種狀況下,更改幾乎能夠當即投入生產(固然,在測試以後!),由編寫該更改的開發人員進行部署,以便他們能夠實際使用相同的版本在生產中看到它。實際編寫代碼的工具,以最大程度地減小環境之間的兼容性錯誤的可能性。

固然,其中一些因素不在Kubernetes的範圍內。例如,人員缺口是一個文化問題。可是,時間和工具上的差距能夠經過兩種方式來彌補。

對於時間間隔,基於Kubernetes的應用程序固然基於容器,而容器自己是基於存儲在版本控制系統中的鏡像的,所以它們適合CI / CD。還能夠經過滾動更新來更新它們,若是出現問題能夠回滾,所以它們很是適合這種環境。

就工具差距而言,基於Kubernetes的應用程序的體系結構使管理變得更加容易,既能夠經過簡化本地依賴關係將其包含在各類鏡像中,也能夠經過模塊化應用程序以使外部支持服務成爲可能。標準化。

原則 XI. 日誌

12 Factor App的原則11是「將日誌做爲事件流處理」。

儘管大多數傳統應用程序將日誌信息存儲在文件中,但十二要素應用程序卻將其做爲事件流定向到stdout。執行環境負責收集這些事件。這可能就像將stdout重定向到文件同樣簡單,可是在大多數狀況下,它涉及使用日誌路由器(例如Fluentd)並將日誌保存到Hadoop或服務(例如Splunk)。

在Kubernetes中,您至少有兩個選擇能夠進行自動日誌記錄捕獲:若是您使用的是Google Cloud,則爲Stackdriver Logging;若是您不使用的是,則爲Elasticsearch。

原則 XII. 管理進程

12 Factor App的原則12是「將管理/管理任務做爲一次性進程運行」。

該原則涉及將管理任務(如遷移數據庫或檢查記錄)與應用程序的其他部分分開。儘管它們是分開的,可是它們仍必須在與應用程序相同的環境中運行,而且在與應用程序相同的基本代碼和配置下運行,而且它們的代碼必須與應用程序一塊兒提供,以防止漂移。

您能夠在基於Kubernetes的應用程序中以多種不一樣方式實現此功能,具體取決於應用程序自己的大小和規模。例如,對於小型任務,您可使用kubectl exec在特定的容器上進行操做,也可使用Kubernetes做業來運行獨立的應用程序。可是,對於涉及變動編排的更復雜的任務,您還可使用Kubernetes Helm。

您在實際開發中遵照多少這些因素?

除非您仍在構建桌面應用程序,不然您頗有可能會遇到至少一些十二要素應用程序的基本原則。可是,您可能還會發現至少一兩個可能會更加努力地工做。

相關文章
相關標籤/搜索