容器化近年來備受關註,圍繞著容器技術很多不同的專案也誕生了。這些專案中的一類就涉及到容器編排。當前已出現了許多不同的方案,針對雲專有的解決方案,例如Amazon ECS,開源的解決方案有如Kubernetes。這些方案都有一個相同的標的,那就是使容器編排更簡單。但是,這些工具所提供的真的如它們所聲稱那樣,管理更簡單,部署更簡單嗎? 在本文中,我們先簡要談論下容器化概念,後面我將使用兩種不同的編排方法來部署一個AI-API架構,一個包含簡單API的AI聊天機器人。一種是使用Kubernetes,另外一種是隻使用基於容器的手動控制管理平面。 容器與虛擬機器 在AWS開始在雲上提供虛擬機器(VM)後,全球大多數伺服器部署現在都在使用某類虛擬化系統。如果你始終可以100%利用資源的話,那麼在價格與效能方面,虛擬機器往往更加昂貴。假設你是購買基於它們構建的免費服務層的話,例如RDS,它們現在能更容易,更快地部署,更易於管理並且需要的維護更少。就像物理伺服器和虛擬機器之間的差異一樣,容器化使得管理和部署伺服器或服務變得更加容易。 雖然虛擬機器可以共享物理資源,但它們必須在其之上引入自己的作業系統,當然包括核心。雖然這能建立一個理想的隔離環境,但它也會產生自己的問題,例如執行多個內核和作業系統時浪費的資源以及出於安全原因的更新和維護。容器化就是透過利用核心名稱空間建立具有自己的檔案系統的隔離工作區。因此僅使用一個作業系統並共享相同的核心,來執行多個(伺服器)應用程式,這就是容器的意義所在。 容器同時也具備分層映象的功能,雖然虛擬機器解決方案中也存在這樣的東西,但它沒有像容器那樣充分利用。大多數應用程式有時需要數小時才能構建和安裝,而一個應用程式映象甚至可以在幾秒鐘內下載並執行。如果你需要執行容器化的WordPress安裝,那麼你需要執行Docker來執行WordPress。容器映象可以快取無需多次重覆下載。 接下來我們開始討論容器編排。 容器編排 建立和管理容器的便捷性使許多自動化工作流程得以實現。在最初,所有基於容器的部署都使用一些專有技術棧來編排和執行它們。但是在Docker開源並開始統治該領域之後,它逐漸成為執行容器的標準,因此Docker映象也逐漸成為分發容器映象的標準方式。所以很多關於自定義編排的專案出現時都會以Docker為基礎。 下圖是我想要建立的第一種編排型別。但我需要解決的一個很重要的問題就是啟動時間。我們的軟體啟動時間很長,所以我們希望始終有一個服務處於就緒狀態可以服務於每個請求。在我的架構中,我希望有一個控制器容器可以在我準備新的容器時作為負載均衡器以及HTTP伺服器將請求轉發到正確的AI容器去。 我使用docker-py庫來完成這項工作,並使用了flask來提供HTTP請求。Docker.py庫有著很好的檔案而且很容易使用,只需為控制器和AI應用分別建立了一個Dockerfile。這個過程很簡單,在開發過程中我學到了更多關於Docker的知識。雖然這是我建立的一個非常原始的專有容器編排解決方案,但它總算完成自己的使命。 好了,接下來是時候介紹下Kubernetes了,因為基本上它為編排提供了類似的目的,我已經建立了基於Kubernetes的解決方案來減少需要編寫的程式碼量。 為了在Kubernetes中應用相同的思路,我不得不從一開始就重新思考我的架構。因為Kubernetes僅僅只需要你提供一個部署的樣式(像Amazon ECS那樣)並嘗試將該樣式保持在穩定狀態。當我為下次請求建立自己的容器時,編排系統應該能適時在類似這樣的過程中準備或是處理一些事情,經過一番搜尋,我發現可以使用Kubernetes的標簽功能來完成我的程式。 我的想法是將所有新建立的AI容器打上assigned:not_assigned的標簽,使之應用到每個容器。我需要宣告,我想要其中3個包含標簽assigned:not_assigned。當新請求到來時,我的控制器容器應該將此標簽更改為assigned:assigned。更改標簽會引起狀態改變,3個已部署容器中的2個將會帶有assigned:not_assigned的標簽。當Kubernetes觀察到狀態被變更時,它將用assigned:not_assigned標簽啟動另一個新的容器。 因此,只是為了管理Kubernetes叢集,我又編寫了另一個類。它實際上並不需要實現如建立或管理容器的某些功能,但它需要能轉發請求並刪除標簽。完成這個工作刪除了大量程式碼,可想而知維護的程式碼行數量也減少了,這意味著攻擊面更小了。在Pod中建立與Kubernetes主機的連線非常簡單。此後我又花了一些時間來建立服務並將請求路由到正確的容器。 結論 在這個試驗中,我嘗試使用現成的容器編排解決方案和我自己編寫的編排工具。編寫我自己的編排解決方案很快,其中的概念並不陌生,並且會有很多文章指導如何去做。但是當切換到Kubernetes時,一切都變了。為了能夠使用Kubernetes,關於容器的知識是不夠的,我必須學習新的概念和一種新的思維方式以便能夠按我的需求來使用它,例如在Kubernetes中部署和服務作為第一公民,而不是容器。但最後,我們可以放心地假設,使用Kubernetes進行容器編排能使我的架構更安全,更穩定,因為我的軟體中的大多數複雜的部分,例如維持穩定數量的容器,這些都是在Google使用並推廣的一個開源專案的幫助下完成的。 原文連結:https://medium.com/next-level-german-engineering/comparison-of-two-different-approaches-towards-container-management-4e5298736d42 已推薦到看一看 你的朋友可以在“發現”-“看一看”看到你認為好看的文章。 取消 推薦 我知道了 已取消,“好看”想法已同步刪除 知道了 已推薦到看一看和朋友分享想法 最多200字,當前共字 傳送 已傳送 朋友將在看一看看到 確定 分享你的想法… 取消 分享想法到看一看 確定 </div> <p><span class=”like_comment_msg” id=”js_b_like_comment_msg” style=”visibility: hidden;”>最多200字,當前共<span id=”js_b_like_current_cnt”/>字</span> </div> </div> <div class=”like_comment_primary_mask” id=”js_mask_2″/> </div> <div id=”js_loading” style=” display: none;”> <div class=”weui-mask_transparent”/> <div class=”weui-toast”> <i class=”weui-loading weui-icon_toast”/></p> <p class=”weui-toast__content”>傳送中</p> </div> </div> <div id=”js_fail” style=”display:none”> <div class=”weui-mask”/> <div class=”weui-dialog”> <div class=”weui-dialog__bd”> 網路異常,請稍後重試 </div> <div class=”weui-dialog__ft”> <a class=”weui-dialog__btn weui-dialog__btn_primary” href=”javascript:;” id=”js_fail_inform”>知道了</a> </div> </div> </div> <div class=”weui-desktop-popover weui-desktop-popover_pos-up-center weui-desktop-popover_img-text” id=”js_pc_weapp_code” style=”display: none;”> <div class=”weui-desktop-popover__content”> <div class=”weui-desktop-popover__desc”> <img id=”js_pc_weapp_code_img”/><br /> 微信掃一掃<br/>使用小程式<span id=”js_pc_weapp_code_des”/> </div> </div> </div> <div id=”js_minipro_dialog” style=”display:none;”> <div class=”weui-mask”/> <div class=”weui-dialog”> <div class=”weui-dialog__bd”>即將開啟”<span id=”js_minipro_dialog_name”/>”小程式</div> <div class=”weui-dialog__ft”> <a class=”weui-dialog__btn weui-dialog__btn_default” href=”javascript:void(0);” id=”js_minipro_dialog_cancel”>取消</a><br /> <a class=”weui-dialog__btn weui-dialog__btn_primary” href=”javascript:void(0);” id=”js_minipro_dialog_ok”>開啟</a> </div> </div> </div> </div>