落地案例|用 Kubernetes 將 Skytap 雲微服務架構現代化

Skytap 是全球性公有云提供商,爲客戶提供保存、克隆複雜環境的性能服務。咱們的客戶包括在混合雲上運行應用的企業,教育機構虛擬培訓實驗室之類,用戶只須要便於管理的開發測試實驗室,以及擁有各類各樣的開發運維工做的機構。node

咱們以前以較快的速度拓展咱們的業務——咱們的用戶基礎和咱們工程機構也在持續增加。使人興奮!然而,要作到順利地縮放應用和機構也是十分困難的,咱們目前正在朝這個目標努力。當咱們第一次開始關注工具設置的時候,發現傳統的 OS 虛擬化並非完成縮放目標的有效方法。咱們發現虛擬機的持久性能鼓勵工程師建立、維持定製的「 pet 」虛擬機;這跟咱們願望沒太大關係,咱們的願望是用穩定的、可預測的狀態來建立能夠重複使用運行時間的環境。 Docker 和 Kubernetes 社區的增加跟咱們的增加密切掛鉤,並且目前社區內的爆炸式增加也幫助這些工具走向成熟。後端

在這篇文章中,咱們會探索 Skytap 如何將 Kubernetes 做爲服務中的關鍵組件在 Skytap 雲上處理工做。 爲了繼續維持這種敏捷的速度,繼續經過軟件開發生命週期來啓用組件全部權,咱們又新增了工程師成員。這就要求咱們程序的關鍵層面高度模塊化,高度一致。之前,咱們經過虛擬機和環境模版從新進行系統級別打包,可是隨着規模的彈性伸縮,做爲打包機制的容器變得愈來愈重要了,由於它相對輕便、運行環境控制精準。api

除了打包靈活這個優勢,容器還提升了資源利用率,團隊將資源混合入更大、更高性能的虛擬機時,也變得更加複雜;而容器則幫助阻止這種複雜性上升。好比,咱們的操做團隊爲了監控健康和資源利用率安裝相應工具,開發團隊部署服務,安全團隊則安裝流量監控;將全部這些都結合到一臺單個的虛擬機上,很大程度上就增長了測試負擔,並且還會常常形成恐慌。安全

服務中,用 Docker 將單個組件容器化是至關瑣碎的。開始很容易,可是任何建立過度布式系統的人都知道,真正的困難在於部署、彈性擴容、可用性和持久性,以及集羣中每一個單元之間的交流。網絡

進行容器打包負載均衡

咱們要將 pet 虛擬機換成 cattle 。框架

分佈式系統的挑戰在於,它不是簡單地建立一些容器就能夠了的。咱們將 Docker Swarm , Mesosphere 和 Kubernetes 進行對比,發現 Mesosphere 用法模型跟咱們的需求不匹配,由於咱們須要的是管理虛擬機的能力,跟 Mesosphere 「分佈式操做系統」模型不匹配; Docker Swarm 如今則不是那麼成熟。因此,咱們最終選擇了 Kubernetes 。運維

發佈 Kubernetes ,建立新的分佈式服務相對來講會容易一點。可是,咱們須要將容器管理和咱們已經存在的平臺、基礎設施整合到一塊兒。平臺的一些組件最好由虛擬機提供,咱們須要的就是將這些服務進行迭代更新。 咱們將整合問題進行了整理分類,以下所示:socket

1 、服務控制和部署 2 、內部 service 交流 3 、基礎設施整合 4 、工程支持和教育分佈式

服務控制和部署

咱們使用 Capistrano (咱們稱之爲「 Skycap 」)的定製拓展版原本部署服務,管理執行運行的服務。經過單個的、構建良好的框架來管理容器化、傳統的 service 。咱們同時也須要讓 Skycap 擺脫不可避免的內在缺點,這些缺點來自於相似於 Kubernetes 這樣的開發工具。

爲了處理這個,咱們引入封裝器到服務中,來幫助控制用於在 Skycap 後隔離 kubectl 的框架,而且處理僞造日誌信息被忽略的問題。

Deployment 爲咱們添加了一層複雜性。打包軟件用 Docker 鏡像最好,可是有個歷史遺留問題,就是咱們已經從資源那裏部署了,而不是從打包的時候部署。咱們的工程團隊但願對資源做出有效修改,發佈他們的工做;開發人員不但願再有額外的打包步驟了。因爲容器化的緣由,除了從新建立咱們整個的部署和編排框架,還須要爲容器化服務使用持續集成管道。咱們爲每一個提交都自動建立了新的 Docker 鏡像,而後咱們用 Mercurial ( Hg )來給提交內容打標籤。從 Skycap 角度來講,特定 Hg 版本的部署會拉取 Docker 鏡像,這些鏡像會被打上同樣的版本號。

咱們在多個環境上從新使用容器鏡像。這就要求特定的環境配置被添加到每一個容器實例。直到最近,咱們本着相似於基於資源的準則注入這些配置值:每一個容器都會從 Hg 經過 cURL - ing raw 文件拷貝相關的配置文件,這些文件來源於運行的 repo 。網絡可用性和變量能避免就避免,因此咱們如今把配置加入到 Kubernetes 的 ConfigMap 功能中。這不只僅簡化了咱們的 Docker 鏡像,還讓 pod 啓動速度更快、更可預測(由於容器再也不須要從 Hg 下載文件了)。

內部 service 交流

service 交流主要有兩種方法。第一種,消息代理——一般用於 Skytap 平臺,進程與進程之間的通訊。第二種則是直接經過點對點 TCP 鏈接——一般用於 service 跟外部(好比網頁 service )的交流。下一節咱們會具體說一下這個 TCP 方法,它實際上是整合基礎設施的一個組件。

用 service 可以理解的方法來直接管理 pod 之間的鏈接是比較複雜的。再者,容器化的 service 須要跟典型的基於虛擬機的 service 進行交流。爲了下降複雜性,咱們主要使用已經存在的消息隊列系統。它能夠幫助咱們在處理 pod 和非 Kubernetes service 之間的流量的時候,避免使用基於 TCP 的 service 發現和負載均衡系統。

這就減小了咱們的配置負載—— service 只須要了解如何跟信息隊列交流就能夠了,而不須要跟每個有聯繫的 service 都進行聯繫。對於管理 pod 的運行狀態;當節點重啓,信息在隊列中進行緩衝的時候,咱們也有額外靈活性。每次 pod 被添加或者從集羣中被移除的時候,咱們避免重置 TCP 端點。還有,有了 MQ 模型,咱們就能夠用 「 pull 」的方法來管理負載均衡,這種方法更加精準,由接受者決定他們何時準備好能夠處理一個新消息,而不是用試探的方法(好比最少鏈接)來簡單地利用 open socket 的數量來對負載進行估計。

轉移使用複雜的基於 TCP 方法的 service (或者是使用負載均衡鏈接的 service ),還不如轉移啓用 MQ service 到 Kubernetes 來得簡單。還有,由消息代理中間件提供的隔離意味着,從經典的 service 到基於容器的 service 的轉換本質上對於其它啓用 MQ 的 service 來講是很簡單的。

基礎設施整合

做爲基礎設施提供商,咱們在配置 Kubernetes 使用咱們的平臺的時候,面對一些特殊的挑戰。 AWS 和 GCP 提供即時可用的解決方案,能夠簡化 Kubernetes 規劃,可是關於底層基礎設施的假設跟咱們的現實不匹配。一些組織者爲了特殊的目的還建立了數據中心。這個選項就要求咱們禁止已經存在的負載均衡基礎設施,除了工具,咱們還建立了基於 Puppet 規定的系統,邀請了一些專家。咱們無心禁用工具,也無心使用咱們以往的經驗,咱們須要找到一種管理 Kubernetes 的方法,可以跟咱們所處的環境相整合的方法,而不是重建。

因此,咱們使用 Puppet 來供應、配置虛擬機來運行 Skytap 平臺。咱們使用定製部署腳本在這些平臺上安裝 Kubernetes ,咱們跟操做團隊合做,爲 Kube-master 和 Kube-node 宿主機作容量規劃。

在以前的章節,咱們提到,點對點基於 TCP 的交流。對於用戶面對的 service , pod 須要一種方法跟 Skytap 的第 3 層網絡基礎設施進行交互。在 Skytap 的例子包括咱們的網頁應用,經過 HTTPS 的 API ,經過網頁 Socket 的遠程桌面, FTP , TCP/UDP 端口轉接 service ,徹底公開的 IPs 等等。咱們須要當心管理的是外部流量的網絡出入口,基本上用的是 F5 負載均衡器。

用內部 service 的 MQ 基礎設施來處理這個工做其實不太合適,由於不一樣客戶端使用的協議都比較定製化,而 TCP 則是最低版本的協議。

爲了使咱們的負載均衡器跟 Kubernetes 的 Pod 進行交流,咱們會在每一個節點上運行 kube-proxy 。負載均衡器路由到節點上, kube-proxy 會切換到合適的 pod 。

要記住的一點就是, Kubernetes 須要在 pod 之間路由流量。 Calico 插件用於 Kubernetes 網絡,當 Kubernetes 發佈,或者產生 pod 的時候,咱們能夠用特定的 service 來從新部署 F5 。 Calico 使用 BGP 來處理路由公告,這就簡化了跟 F5 的整合。

當 pod 加入集羣,或者從集羣中被移除的時候, F5 本身的 load balancing pool 須要從新配置。 F5 設備會保留負載均衡的後端;容器化 service 的入口是直接經過這個 pool 來傳輸到 service pod 所在的節點的。這對於靜態網絡配置來講是最直截了當的方法——可是既然咱們使用 Kubernetes 來管理 pod replication 和可用性,那麼咱們的網絡狀態就變成動態的了。要處理這些修改,咱們有一個「負載均衡器」 pod ,它能夠監視 Kubernetes svc 對象的變化;若是 pod 被移除或者添加,「負載均衡器」 pod 會經過 svc 對象檢測到這個修改,而後經過設備的網頁 API 更新 F5 配置。這樣的話, Kubernetes 會處理 replication 和 failover/recovery ,而動態的負載均衡器配置則會讓這個進程對 service (或者用戶發起請求)設置不可見。一樣的, Calico 虛擬網絡和 F5 負載均衡器的結合意味着, TCP 鏈接應該連貫地運行在傳統的 VM 基礎設施上,或者是轉移到容器上。

有了網絡的動態配置, Kubernetes 的 replication 結構使得水平式擴充以及 failover/recovery 很是直截了當。咱們尚未完成相應縮放的 milestone ,可是咱們已經在 Kubernetes 和 Calico 的基礎設施上奠基了基礎,找出一種能夠直接實現的方法。

-爲 service replication 配置上下層 -建立負載分析層和縮放 service (這個仍是很容易的) -若是負載模式跟縮放 service 內配置好的 triggers 相匹配(好比,特定邊界上的請求速率或者數據卷)

issue : kubectl scale —— replicas = COUNT rc NAME

這就容許咱們在平臺層面對自動縮放進行細粒度控制,而不是從應用自身——可是咱們也會評估 Kubernetes 中的水平 pod 自動縮放;這就會跟咱們的須要相匹配而不須要定製服務。

歡迎關注咱們的 Github 帳戶以及 Skytap 博客;面對技術成熟等問題,咱們但願跟你們分享咱們在社區中所作的。

工程支持

例如像容器化這樣的過渡項目須要工程師,還涉及到管理以及貢獻到平臺,修改他們的工做,爲建立 service 以及排除故障 service 學習新的方法。

由於不少學習模式須要多方面的方法,咱們的處理方法有三種: 1 、用文檔, 2 、直接向外拓展聯繫到工程師(也就是,經過 brownbag 會議或者指導團隊), 3 、經過提供容易訪問的專門支持。

咱們也會繼續輔助收集提供指導性的文檔,從傳統的 service 過渡到 Kubernetes ,這些文檔會提供指導,建立新的 service ,操做容器化服務。

文檔也不是對每一個人都適用的,有時候它會丟失或者不完整(儘管咱們已經盡力去完善了),因此咱們也須要有一個進行內部 Kube 求助的 Slack 頻道,能夠進行線上求助,或者進行有深度的在線面對面討論。

咱們還有一個很強大的工具支持:咱們自動建立、測試相似於 prod 的環境,包括 Kubernetes 基礎設施,這就容許工程師在很大程度上能夠自由地進行 Kubernetes 試驗。在這篇帖子中,咱們更加細節地探索了自動環境交付。

結語

整體上來講,咱們在 Kubernetes 和容器化服務上得到了極大的成功,可是咱們也發現要跟已經存在的全棧環境進行整合還面臨很大的挑戰。從企業生命週期立場來看,不存在即插即用的 Kubernetes 平臺,但它的靈活性和可配置性對於建立模塊化 service 生態系統來講,是十分強的工具。

咱們喜歡將應用程序現代化的這個挑戰。 Skytap 平臺很是適合這類遷移工做——咱們在 Skytap 適用 Skytap ,固然,它在 Kubernetes 整合項目中也起了很大的做用。若是你打算本身嘗試將它現代化,請聯繫咱們,咱們很樂意提供幫助!

相關文章
相關標籤/搜索