Kubernetes 落地案例|在線課程平臺 Descomplica 使用 Kubernetes 5 個月的體驗

在過去一年內,Descomplica 計劃往核心組件服務化的方向發展,咱們一開始使用 Elastic Beanstalk 將這些服務編排到 AWS。html

那時候來講,這個決定是明智的。整體來講,Elastic Beanstalk 挺好用的,並且比較容易學習;全部小組爲他們各自的項目使用,也不會花費太多時間。前端

早在幾個月以前,一切都還運行得好好的。可是在一些舊問題解決以後,新的問題接踵而至。數據庫

成本問題

在 Elastic Beanstalk,每一個 EC2 實例只運行一個應用程序容器。這也就意味着,若是你遵循可靠性最佳實踐,一個應用程序就會有兩個或者多個實例(跨越部署在多個可用域)。除了生產環境,若是你還有其餘環境的話(好比預生產環境),那麼你可能就須要更多實例。網絡

不管如何,你都要爲每一個服務根據不一樣的工做負載部署多個專用實例,而且大部分時間這些實例都很閒。負載均衡

咱們須要找到一個方法更加明智地使用咱們的可用計算資源。工具

 

贏家

後來咱們才發現,Kubernetes 就是咱們一直在尋找的 ECS 的替代品。post

Kubernetes 是一個容器編排工具,創建在谷歌 15 年運行產品的基礎之上,與最佳想法、社區實踐相結合。學習

雖然 Kubernetes 是一個功能豐富的項目,可是隻有其中的幾個關鍵功能引發了咱們的注意:命名空間,自動滾動升級和回滾,經過 DNS 的服務發現,基於資源使用的容器自動擴容,以及,允諾的自我修復系統。測試

Kubernetes 圍繞「容器應該如何被組織,如何經過網絡聯絡」的理念,可是若是你的服務是聽從 Twelve-Factor 實踐的,那麼這個理念對你來講也不是什麼問題。spa

 

咱們的生產化之路

爲了確保 Kubernetes 是個可行的選擇,咱們作的第一件事就是作些可靠性測試來確保它可以處理「不可用節點,Kubelet/Proxy/Docker daemons 終止,和可用區域運行中斷」這類的故障模式。

預測全部的故障,這是不太可能的,可是最後,咱們仍是被 Kubernetes 解決這些故障的能力深深折服。

那時候,咱們用 kube-up 來建立咱們的測試集羣。雖然這個工具按照它的目標來服務,但不是每一次都符合預期;它暴露出了很是多的問題,好比說不合理的默認設置,隨機超時致使沒有徹底建立成功的程序棧,以及在刪除集羣時不肯定的行爲致使一些資源的遺留。

那時候咱們一致贊成要選擇用 Kubernetes,因此咱們須要一個更加可靠的方法來建立或者刪除 Kubernetes 集羣。

使用「kube-aws」

Kube-aws 這個工具是由 CoreOS 的幾我的建立的。它最厲害的地方在於,在 hoods 下,使用 CloudFormation,這對於咱們來講有利無弊。

最顯著的優勢就是,用這個工具建立或者刪除集羣十分容易,並且刪除後還不會留下任何的遺留。

另外一個功能在於,與 kube-up 不一樣,你能夠在已經存在的 VPC 上建立集羣,這樣全部運行在 Kubernetes 上的服務均可以當即訪問你的 AWS 資源(好比關係型數據庫)。

事實上,你能夠同時在同一個 VPC 上運行多個集羣。這樣就會帶來一個良性的反作用,就是你能夠把每一個集羣都當作是不變的基礎設施,你不須要修改正在運行的集羣——冒着破壞其中一些什麼的風險,你只須要建立一個新的集羣,而後用影響最小的方法慢慢地把流量從舊集羣轉移到新集羣。

最後一個功能(也多是最有用的一個),你能夠經過配置輕鬆定製集羣的任何方面來知足你的需求。在咱們的這個案例中,咱們添加集羣層面的日誌記錄,攝取應用程序日誌到 Sumologic,用 InfluxDB 和 Grafana 進行集羣監控,基於 ABAC 的受權認證,以及一些其它的事情。

第一個環境

在解決了集羣建立,集羣刪除問題以後,咱們有信心開始着手遷移咱們的預生產環境到 Kubernetes了。

爲第一個 Deployment 手動建立 yaml 配置十分簡單,可是咱們須要自動化地在應用鏡像被持續集成系統構建完畢以後當即進行部署。

爲了證實這個概念,咱們很快在 AWS Lambda(基於這篇文章)開闢了一個小的功能,這個功能能夠在它收到一個測試經過了的合併通知,自動升級相應的部署單。

這個小 Lambda 功能如今涉及到咱們的交付管道,也編排 deployments 到其它環境,包括生產環境。

有了這個,將預生產環境服務從 Beanstalk 遷移到 Kubernetes 就至關容易了。首先,咱們爲每一個服務(一開始指的是在 Elastic Beanstalk 上遺留的部署)都建立了 DNS 記錄,確保全部的服務都是經過這個 DNS 互相訪問的。而後,就只要修改這些 DNS 記錄來指向相應的 Kubernetes 管理的負載均衡器。

爲了確保管道的每一個部分都按照預期的來運行,咱們監控全部的預生產環境部署,尋找 bug,而後盡咱們所能地修復它,完善功能。

測試得越多,學習到得越多

在部署咱們的第一個產品服務到 Kubernetes 以前,咱們作了一些壓力測試,來找到每一個服務最佳的資源需求配置,也爲了找出咱們須要多少 pods 才能夠支撐住目前的流量。

 

觀察你的 services 在負載下是如何工做的,以及他們須要多少計算量。

一樣,花些時間來理解 Kubernetes 的服務質量等級,這樣你就能夠更好地控制哪個 pod 在內存壓力下會被終止掉。若是你跟咱們同樣,跟全部環境都分享了同一個集羣,那麼這一點對你來講相當重要。

提示:啓動 Cross-Zone Load Balabcing(AWS)

這一點在 Kubernetes1.4 中已經修改,可是如今,若是你經過 LoadBalancer type 來暴露你的服務,不要忘記爲相應的 ELB 手動啓動 cross-zone load balancing;若是你沒有這麼作,你應該會發現分佈在不一樣的可用域當中的應用 pod 的負載不均衡。

提示: 多瞭解 kube-system

若是你曾經嘗試用過 Kubernetes,你可能就會注意到 kube-system namespace 上有很是多的東西;花點時間來理解它們的意義。好比,拿 DNS add-on 來講;常常能看到人們遇到 DNS 問題,由於他們忘記了隨着負載增加而要增長更多的 DNS Pod。

上線

不要當即轉換全部的流量,就如同咱們在預生產環境中所作的,咱們想的是,須要採起一個更加仔細的方法,用加權路由規則,慢慢轉換流量到 Kubernetes 集羣。

一旦咱們注意到已經沒有請求能夠到達遺留的 Beanstalk 環境了,咱們就繼續向前,而且終止他們。

2016,9月21日更新內容:全部主要的服務都已經被遷移到咱們新的平臺啦!

如下是最終數字:
每個月減小約53-63%開銷
實例的數量減小72-82%

生產環境以外

Kubernetes 能夠用絕不費力的方式塑造交付管道,這是咱們想都不敢想的體驗。咱們的開發環境就是這樣的一個例子。

不管何時有人打開了 Pull Request 給咱們一個項目,我以前提到的 AWS Lambda 功能就會建立一個臨時環境運行 PR 當中修改後的代碼。

一樣,不管何時 push 新的代碼,一旦他們經過測試,這個環境就會自動更新。最後,當 PR 被合併(或者關閉),環境也就被刪除了。

這個功能使得咱們的代碼審查更加完全,由於開發人員可以看到修改的東西在運行。這對於前端服務的 UX 來講就更有價值了;設計師和產品經理有機會看到修改生效,也能夠在 PR 合併以前驗證修改和分享想法。爲了要發送 Github Status 通知,能夠看到這些圖片中,咱們用 Go 實現了一個守護進程,來監控到開發環境的部署並不斷更新各個版本的部署狀態。

結論

Kubernetes 是一款很複雜的軟件,旨在解決複雜的問題,因此在把它用到你的項目以前要先花點時間瞭解一下它的那些功能是如何有條理地運行在一塊兒的。

Kubernetes 是爲生產準備的,因此要避免受到誘惑,不要嘗試在它上面運行全部的東西。在咱們的經驗裏,Kubernetes 並無給可能遇到的一系列問題提供簡單有效的統一方法,好比說有狀態應用。

其實文檔也不怎麼樣,可是好比 Kubernetes Bootcamp 以及 Kelsey Hightower 的《Kubernetes The HardWay》給了我但願,相信在不遠的未來這些都將不是問題。

若是沒有 Kubernetes,我不知道咱們這個小團隊要怎麼在這麼短的時間內解決這麼多的問題。咱們但願繼續在 Kubernetes 上工做,確保交付平臺更加有活力,更贊!

原文連接 轉載請聯繫咱們 -3-

相關文章
相關標籤/搜索