為了降低成本、改善可伸縮性,大部分組織都搬遷到了AWS上。但通過搬到AWS上,至少有一家公司發(fā)現(xiàn)這既能節(jié)省成本、改進(jìn)控制,還能維持一個(gè)健壯的服務(wù)器基礎(chǔ)設(shè)施。在舊金山舉行的KubeCon大會(huì)上,Vonli的CTO Paolo Kinney解釋了他們?cè)谧詣?dòng)化Kubernetes基礎(chǔ)設(shè)施來促進(jìn)這一過程中所學(xué)到的東西。
Vinli是個(gè)車聯(lián)網(wǎng)平臺(tái),能把數(shù)據(jù)從聯(lián)網(wǎng)的智能汽車上傳到云端。該公司讓開發(fā)者可以通過一組API來訪問這一數(shù)據(jù),從而簡(jiǎn)化了為消費(fèi)者創(chuàng)建應(yīng)用的過程。開發(fā)者可以利用低級(jí)的遙測(cè)API以及安全、旅行、汽車分析以及行為服務(wù)等方面的高級(jí)API。
Kinney說Vinli決定用托管于Docker容器的微服務(wù)來部署整個(gè)后端基礎(chǔ)設(shè)施以便進(jìn)行定制化。所有的后端邏輯和前端模塊都是基于容器發(fā)布的。因此該公司每天都要在自己的基礎(chǔ)設(shè)施上加載和卸載數(shù)百個(gè)Docker鏡像。
從AWS撤走
他們的微服務(wù)架構(gòu)原來是部署在AWS Elastic Beanstalk上的。它運(yùn)轉(zhuǎn)得很好,但Kinney說隨著后端增長(zhǎng)超過15到20項(xiàng)服務(wù)而需要負(fù)載均衡時(shí),成本就開始變得很高。后來由于Vinli必須負(fù)載均衡的服務(wù)數(shù)接近200,成本開始失去控制。
Kinney決定試用Kubernetes作為服務(wù)基礎(chǔ)設(shè)施編排的手段。一個(gè)周末,他跟一支小規(guī)模團(tuán)隊(duì)重構(gòu)了整個(gè)微服務(wù)架構(gòu),讓它在Kubernetes上面跑。該基礎(chǔ)設(shè)施包含有跨4個(gè)軟件棧的大約45個(gè)應(yīng)用、服務(wù)和Worker等。
這種過渡的關(guān)鍵部分是基于Kubernetes基元開發(fā)最后一層的應(yīng)用管理層。簡(jiǎn)化Vinli內(nèi)部團(tuán)隊(duì)開發(fā)工作的策略之一是保持需求的簡(jiǎn)單性。開發(fā)者實(shí)現(xiàn)其代碼進(jìn)Docker容器,而這些容器是可以命名并迅速發(fā)布出去的。開發(fā)者和設(shè)計(jì)師唯一的內(nèi)部需求是通知運(yùn)營(yíng)團(tuán)隊(duì)有新服務(wù)了,并讓他們進(jìn)行應(yīng)用級(jí)的健康檢查。
像農(nóng)夫一樣思考
Vinli為自己的基礎(chǔ)設(shè)施開發(fā)了若干簡(jiǎn)單的Kubernetes基元來優(yōu)化集群管理器。它們的命名都跟農(nóng)場(chǎng)運(yùn)營(yíng)有關(guān):牧羊人(Shepherd)、領(lǐng)班(Foreman)、農(nóng)夫(Farmer)、Burn(燒除草木)和屠夫(Butcher)。Kinney說整個(gè)編排基礎(chǔ)設(shè)施實(shí)際上相當(dāng)簡(jiǎn)單。所有這些獨(dú)立的流程大概用200行代碼就跑完了。它們從觀察服務(wù)間的共性開始,然后在圍繞著這些共性來開發(fā)工具。
Shepherd可以簡(jiǎn)化和加速把現(xiàn)有服務(wù)推到新的更新的過程。Kinney說標(biāo)準(zhǔn)的Kubectl集群控制工具只用30秒來做出新服務(wù)。Shepherd主要替Vinli的基礎(chǔ)設(shè)施優(yōu)化了服務(wù)的轉(zhuǎn)換,用時(shí)只需要5秒鐘。這使得Vinli可以移動(dòng)容器時(shí)不需要擔(dān)心從一個(gè)棧移到另一個(gè)棧的配置和管理。
Worker是Kubernetes內(nèi)部的微服務(wù)進(jìn)程,可幫助編排應(yīng)用容器的加載和停轉(zhuǎn)。這些需要以不同的節(jié)奏進(jìn)行伸縮以配合不斷變化的應(yīng)用負(fù)載。Vinli創(chuàng)建了另一個(gè)叫做Foreman的內(nèi)部工具來管理編排其他Docker進(jìn)程的worker容器的生命周期。它還可以配合另一款叫做Famer的工具來增加或減少Docker容器的復(fù)制數(shù),從而對(duì)服務(wù)負(fù)載做出響應(yīng)。
Vinli總是會(huì)刪除Kubernetes容器的pod。“我們?nèi)拥魀od只是為了讓新的pod能上來,”Kinney說:“這能夠幫助我們避免長(zhǎng)時(shí)間的運(yùn)行日志或內(nèi)存問題。”名為Burn的工具會(huì)根據(jù)需要把一組里面的所有的pod都干掉、配合Butcher一起工作還可以殺死一個(gè)或多個(gè)pod,處理cron jobs(周期性指令),發(fā)布更新到開發(fā)者和運(yùn)營(yíng)團(tuán)隊(duì)使用的內(nèi)部Slack IRC源。
定期剔除集群來保持新鮮
每天Vinli都要把所有的pod干掉一遍,幾秒鐘之內(nèi)整個(gè)基礎(chǔ)設(shè)施都會(huì)備份并重新運(yùn)行。Kinney說,“有了Kubernetes,一切都變得可以極度地隨便舍棄。我們希望讓東西能夠自我刷新。”
另一個(gè)關(guān)鍵是讓應(yīng)用基礎(chǔ)設(shè)施盡可能一次性使用來消除微服務(wù)架構(gòu)的持久性。所有的持久層數(shù)據(jù)都用Redis和Elasticsearch保存在服務(wù)外面。這確保了新容器或新配置推送到生產(chǎn)環(huán)境時(shí)不會(huì)有任何數(shù)據(jù)丟失。“這讓我們保持敏捷,”Kinney說。