最近閒了點,寫個大活:部署Dotnet應用到K8s。html
一直想完成這個主題。但這個主題實在太大了,各類拖延症的小宇宙不時爆發一下,結果就拖到了如今。前端
這個主題,會是一個系列。在這個系列中,我會討論將應用部署到K8s時須要的各個內容和知識,以及各類刨過的坑。node
爲了不這個系列被擴得過大,我不深刻討論K8s的技術,也不去解釋如何創建K8s集羣之類的問題。這個主題會側重在開發人員方面,側重於如何開發適合K8s的應用,以及在K8s上部署。數據庫
另外,這個主題也不會關注Docker。在我看來,Docker是一個附加技術,而不是必要內容。小程序
在項目中,是否須要使用K8s,算是一個問題。從各個方面來看,不少中大型的項目都傾向於往這個方面去作,但咱們必須清楚,使用K8s增長了項目的複雜度。若是構建的是一個獨立的應用程序,那用K8s實在沒有必要。而即使是一個大的系統,其實也沒有必要從開頭就加入K8s。api
本主題中的內容大多來自我本身部署Dotnet Core到K8s集羣的經驗。若是有任何問題,能夠在評論中告訴我。bash
爲防止非受權轉發,這兒給出本文的原文連接:http://www.javashuo.com/article/p-dtchseay-nu.html微信
前邊說了,這個主題咱們僅關注部署應用程序相關的部分,而不討論K8s的所有。網絡
面向開發,面向部署,咱們須要瞭解下面幾個概念:app
這幾個概念,是整個內容的基礎。
在K8s中,Node對應的是虛擬機或物理硬件,是K8s實際運行容器的地方。
通常來講,有兩類節點:
一個典型的K8s集羣會像下面圖中的樣子:
固然,在實際應用中,看K8s的規模。必要時,也能夠作成單機,主節點運行控制服務的同時,也運行應用程序。
在集羣中,節點越多,能夠運行的應用或容器就越多,節點宕機時的容錯能力也就越大。
K8s中最小的管理單元,不是一個個獨立的容器,而是Pod。
要在K8s中運行應用程序,須要將其打包到一個容器(一般是Docker容器)中,並讓K8s運行它。Pod是可讓K8s運行的最小單元。它包含一個或多個容器。當一個Pod被建立或銷燬時,它裏面的全部容器也會被建立或銷燬。
在網上,不少的文章都介紹說:若是有一個依賴於數據庫的應用,那應該把應用容器和數據庫容器部署在同一個Pod中,以便同步建立或銷燬。
以個人經驗來講,這個說法很不許確,並且容易形成對K8s應用的誤解。在K8s的實際應用中,只包含單個容器的Pod會更經常使用,也更好用。就好像「支付API」或「訂單API」這樣的,每一個API都有不一樣的擴展需求、部署要求和迭代速度,所以單獨設置Pod給它們是很是合理的。一樣,數據庫容器也應該部署在獨立的Pod中,由於它與應用/服務/API會有不一樣的生命週期。
還有一個比較經常使用的是SideCar模式,就是在一個Pod下的主容器旁邊部署「SIdeCar「容器,用來充當代理,爲主應用程序進行身份證認處理,或服務發現,以及服務通信,甚至能充當應用性能監控的接收器來用。
一個典型的節點下的Pod是下面的樣子:
再重申一下:一個節點下面能夠有多個Pod。一個Pod在K8s中會做爲一個總體單元進行調度。一個Pod可能包含一個容器,也可能包含多個容器。容器用於部署應用或API。
在個人概念中,K8s主要作了兩件事:
K8s的部署,主要完成的是第一件事,即管理容器的生存週期。因此,部署能夠看作是定義K8s如何部署Pod以及若是管理Pod的一組規則。
比方,咱們可能這樣定義一個部署:
定義完後,K8s就會嚴格執行這個規則。若是應用崩潰了,K8s會刪除Pod並安排一個新的Pod,以保證規則規定的副本數量。若是Pod須要更多內存,K8s會選擇一個運行容器較少的節點上運行它,或者結束並從新部署它。當應用更新一個新版本時,K8s會建立一個新的部署,來替換舊版本,並將運行轉到新的版本。
固然,上面這個例子作了必定的簡化。不過,基本上K8s的基本工做就是這麼作的。
這裏的關鍵就是:部署定義了規則,K8s在這個部署的整個生命週期中維護並保持這個規則。
前面說過,部署能夠用來建立跨多個節點(Node)的Pod的多個副本。這其實就是K8s提升性能及提升可用性的主要原理。
服務是應用對外的部分,供其它API去調用。而在K8s內部,服務能夠看做是Pod在集羣內的負載均衡器。當咱們建立部署時,一般還會建立一個與該應用的Pod關聯的服務。
在上面的例子中,當咱們建立部署時,也會建立一個「Payment API」的服務,供其它API調用。
而當其它Pod須要與這個支付API的Pod通信時,實際不會與支付API的一個Pod直接聯繫,而是將請求發給服務,而後由服務將請求傳遞給某一個Pod的實例。
這個過程參見下面的圖:
服務與網絡相關。所以,服務有多種不一樣的網絡模式。這裏不詳細說了,只拿一個經常使用的模式舉個例子:
K8s將服務分配到一個DNS記錄,並經過這個記錄將請求從一個Pod轉發到另外一個Pod。
假設咱們有一個支付服務,而咱們的購買服務須要調用這個服務。K8s不須要知道Pod的真實IP,咱們只須要分配一個DNS記錄給服務:
payment-api.xxx.local
經過這個域名,購買服務能夠調用支付服務,而不須要知道支付服務對應的Pod的真正IP。
這個工做方式與Dotnet體系徹底同樣。經過這種方式,能夠實現對資源的邏輯分組,這是題外話。
入口與服務很像,但有本質的不一樣。
服務本質上是K8s集羣內部的東西,用來實現Pod之間的內部調用。而入口將HTTP/HTTPS從集羣外部路由到內部的服務,這樣,外部應用,例如前端、APP或小程序就能夠經過這個入口,調用內部服務來處理請求。
同時,入口也能夠當成提供外部負載均衡,即跨多個節點平衡對給定服務的請求。
除此以外,入口也能夠提供其它一些特性,例如主機名或基於路徑的路由。一般,咱們能夠爲每一個應用或API配置一個入口。
還有,入口設置也能夠用來作應用的反向代理。例如經過一個Nginx實例來配置入口。這都是能夠的,並且這樣的方式,可讓API隱藏在反向代理以後,而不用直接暴露在外網。這個部分,在後面的文章,我會專門寫。
這篇文章是這個系列的一個引子。
當咱們在K8s中部署一個Dotnet Core的應用時,咱們須要配置Pod部署,添加服務來在K8s內部公開這些Pod,並添加一個入口來公開服務。
本系列的後續文章中,我會從開發的各個環節來解釋如何使用這些組件來部署Dotnet Core應用到K8s。
敬請關注!!!
(未完待續)
微信公衆號:老王Plus 掃描二維碼,關注我的公衆號,能夠第一時間獲得最新的我的文章和內容推送 本文版權歸做者全部,轉載請保留此聲明和原文連接 |