自動化我們的基礎設施來武裝工程師

jopen 9年前發布 | 5K 次閱讀 工程師
 

【編者的話】segment是一家客戶數據中心,致力于幫助數千家公司收集、處理數據,本文主要講了segment在自動化基礎設施方面的實踐,主要包括同步開發環境、映射開發環境和生產環境、本地開發和部署到生產環境。

發展企業是艱難的,發展一個支撐企業發展的工程團隊可以說是更加困難的。但是沒有一套穩定的基礎設施,做這兩件事基本是不可能的。特別是對于高速發展的企業,必須授權每一個工程師在編碼、測試和交付代碼方面具有高度的自主權。

過去的一年中,我們增加了達60個新的 集成環境 (總數超過160個),為合作伙伴建立了一個 平臺 ,用以編寫他們自己的集成,發布了 Redshift (紅移)集成,同時發表了幾個重大的產品公告。那段時間,圍繞多環境管理、部署代碼和通常的開發工作流程,我們經歷了許多成長的煩惱。之后,我們的工程師 是最幸福、最具生產力的,因為他們的時間都花在發布商品,打造工具和擴展服務上。開發流程和它所支持的基礎設施簡單易用、擴展靈活是至關重要的。

這就是為什么我們自動化了自己的基礎設施的眾多方面。下面我將分享關于我們當下的一些更加詳細的設置,主要包括這幾個領域:

一起來深入的探討一下吧!

同步開發環境

由于代碼的復雜性的增長和工程團隊的擴大,在所有的工程師中保持開發環境的一致會變得更加困難。

在我們現有解決方案出現之前,我們的工程師所面臨的一個大問題是同步開發環境。我們有一個Github庫,里面有一組shell腳本,所有新來的工程師執行這些腳本,將必要的工具和身份驗證令牌裝到他們本地的機器上,這些腳本也會建立Vagrant和一個虛擬機。

但是這個虛擬機是在每臺電腦上進行本地構建,如果你修改了虛擬機的狀態,那么為了使得讓它恢復到與其他工程師的虛擬機同樣的狀態,你必須從頭構建 一切。而當有工程師更新了虛擬機,你必須在Slack上告訴每個人,讓他們從Github VM庫中拉取代碼并重新構建。這是一個痛苦的過程,因為 Vagrant很慢。

對于一個竭盡全力快速前行的發展中團隊來說,上面的方法并不是一個好的解決方案。

當我們初次嘗試使用 Docker 時,我們很喜歡其在一個可復用和隔離的環境中運行代碼的能力。我們想要復用Docker的這些原則和經驗,從而在不斷擴大的工程團隊中保持開發環境的一致。

我們寫了一堆工具為新來的工程師配置虛擬機,從基礎鏡像狀態升級或是重置。當我們的工程師初次配置虛擬機的時候,需要Github憑證和AWS令牌,然后從 Docker Hub 中拉取最新的鏡像并構建。

自動化我們的基礎設施來武裝工程師

每次運行時,我們會通過查詢Docker Hub API來確保虛擬機是最新的。這個過程會更新工程師每天所需的包、工具等。這將耗費5秒鐘,為了確保一切運行正常,這也是必要的。

此外,由于我們的工程師使用Mac電腦,我們從 boot2dockerVirtualBox 虛擬機切換到了托管于boot2docker實例的 Vagrant ,以便我們可以充分利用NFS的優勢來共享主機和客戶機的volumn。在本地部署的時候,使用NFS,性能得到大大提升。最后一點,NFS允許工程師在虛擬機外部所做的改變可以即時地在虛擬機內部反映出來。

通過這個解決方案,我們大大減少了需要在宿主機上安裝依賴的數目。現在唯一需要的是Docker、 Docker Compose 、Go和 GOPATH 配置。

映射開發環境和生產環境

理想的情況是在開發環境和生產環境中運行相同的代碼,然而這樣分離,開發環境中的代碼可能永遠不會對生產環境中的代碼產生影響。

之前我們將AWS狀態(由 Terraform 生成)存儲在Terraform的文件中,但它并不是一個完美的系統。例如,如果兩個人異步操作并應用了不同的改變,狀態將會改變,最后推送代碼的人將很難搞定合并沖突。

我們盡可能以最簡單的方式實現了staging和production環境的映射:

從一個文件夾復制文件到另一個文件夾。Terraform使我們在修訂基礎設施、部署新服務和做出改進方面節省了大把時間。

在應用之前,我們通過編寫定制的構建過程以及確保恰當的安全因素已考慮在內來集成Terraform和 CircleC

自動化我們的基礎設施來武裝工程師

目前,我們在Github上有一個名為 基礎設施 的單一庫,其中包含了Terraform的腳本集合,用以為每一個容器配置環境變量和設置容器。

當我們想要改變基礎設施中的某些東西時,將必要的修改寫進Terraform腳本,并在新的pull請求之前運行它們以便基礎設施團隊中的其他成 員來review它。一旦pull請求合并到主分支,CircleCI就會啟動部署進程:狀態變為pulled,本地被修改,并再次存入到S3。

本地部署

種子庫

本地開發的時候,使用虛擬數據填充本地數據庫是很重要的,這樣會讓我們的應用看起來更真實。所以,種子庫是配置開發環境的共同組成部分。

我們依賴CircleCI、Docker和 volumn容器 來提供獲取虛擬數據的便捷途徑。volume容器是靜態數據的便攜鏡像。我們決定使用volume容器,因為數據模型和邏輯越來越松耦合而且容易維護。這樣做也是以防萬一,在我們的基礎設施的其他地方可以用到這些數據(比如測試等,誰知道呢)。

當我們在開發過程中啟動app服務器時,就會自動加載種子數據到我們的本地開發環境中。例如,當 app (我們的主應用)容器在開發環境中啟動, app 的docker-compose.yml腳本就會從Docker Hub中拉取最新的 種子 鏡像,并在虛擬機中掛載原生數據。

Docker Hub中的種子鏡像產生自Github倉庫中的種子,作為我們導入到數據庫中的原生對象,它就是一組JSON文件。為了更新種子數據,我們將 CircleCI配置到倉庫上,以便任何到主分支的推送都會構建(從Docker Hun中賺錢我們的mongodb容器和redis容器)并向Docker Hub中推送新的種子鏡像,這樣我們就能在app中使用這個容器了。

生成微服務

由于Segment數據密集型的特性,我們的app已經依賴幾個微服務(db,redis,nsq等)。為了使我們的工程師可以開發app,我們需要一個簡單的方法在本地構建這些服務。

Docker再一次使得這種工作流變的非常容易。

類似于我們使用 種子 volume容器掛載數據到本地虛擬機那樣,我們以同樣方式來使用微服務。我們使用doker compose文件從Docker Hub抓取鏡像來進行本地構建、設置地址并最終將復雜性降低到一條終端命令就可以讓一切啟動并運行。

部署到生產環境

你編寫代碼,但從不將代碼部署都生產環境,這種情況真的發生過嗎?

部署代碼到生產環境是開發工作流程中的一個組成部分。在Segment,圍繞部署代碼到生產環境,我們優先考慮難易程度和靈活性,因為這使得工程師可以快速的行動而富有成效。我們還創造了足夠多的工具來為處理錯誤,回滾和監視構建的狀態保駕護航。

我們使用Docker、 ECS 、CircleCI和Terraform來盡可能地自動化持續部署。

自動化我們的基礎設施來武裝工程師

無論何時代碼被推送或者被合并到 主分支 ,CircleCI腳本就會構建容器并將容器推送到Docker Hub上。

然后,我們有一個單獨的 構建 服務來更新ECS中的任務定義,這是對于由request請求所觸發服務的預設(這樣可以讓我們通過 Slack slash命令 進行部署)。

使用這種設置,我們可以為任何服務定義配置,使得我們的工程師創建和部署新的微服務變得非常容易。正如Calvin在以前的文章中所提到的,“ 使用Docker、ESC和Terraform重構基礎設施 ”:

我們不再需要一組復雜的供應腳本或是AMI--我們只需將生產集群交給鏡像。也沒有更多的狀態實例,我們可以保證在staging和prod環境中運行完全相同的代碼。

部署的自動化和易用不僅對我們的工程師產生了積極影響,我們的成功以及市場團隊可以在一些倉庫中更新markdown文件,當要合并到主分支時,踢出自動部署進程以便可以在幾分鐘內看到這些改變。

快速響應和成

由于我們選擇花費精力重新思考和自動化我們的開發流程及其配套的基礎設施,使得我們的工程團隊反應更加迅速和自信。我們花費更多時間研究我們所熱愛的高杠桿工作--發布產品、打造內部工具,并減少花費在 yak shaving 的時間。

也就是說,這絕不是我們的基礎設施自動化的最后一次迭代。我們不斷地嘗試新的工具并測試新的想法,來看看我們可以探索出什么可以進一步提高效率的東西。

對于我們來說,這是一個漫長的學習過程,我們很樂意傾聽社區中其他人有關他們開發工作流相關的實踐。如果你最終要實現這樣的事情(或者已經實現), 讓我們知道 !我們很想聽聽你做了什么,對于遇到相似問題的人,你所做的哪些對他們有所幫助,哪些是不奏效的。

原文鏈接: Automating Our Infrastructure to Empower Engineers (翻譯: 李加慶

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!