Spinnaker 介紹 – Netflix 的持續交付平台
- 2020 年 1 月 21 日
- 筆記
Spinnaker 是 Netflix 在2015年開源的一款持續交付平台,它繼承了 Netflix 上一代集群和部署管理工具 Asgard:Web-based Cloud Management and Deployment的優點,同時根據公司業務以及技術的的發展拋棄了一些過時的設計:提高了持續交付系統的可復用性,提供了穩定可靠的API,提供了對基礎設施和程序全局性的視圖,配置、管理、運維都更簡單,而且還完全兼容 Asgard,總之對於 Netflix 來說 Spinnaker 是更牛逼的持續交付平台。
在深入了解 Spinnaker 之前,先扯一扯 Netflix 的技術文化:這是一家全面擁抱雲的公司,據報道數據中心完全部署在 AWS 上,是 AWS 的超級大客戶。在上雲後他們發現故障仍然避免不了,為了更加從容的應對這些故障,就搞了一個工具 Chaos Monkey 會隨機停止生產環境中的虛擬機,通過觀察系統在真實故障中的表現來確保程序的健壯性,也通過實戰來驗證各種高可用技術是否靠譜。接着冒出了 Chaos Gorilla,會停止一整個可用域中的所有機器;最後還有Chaos Kong,直接停掉一整個 Region,非常有挑戰精神(喪心病狂)。
為了更好的觀察系統在故障時的情況,還研發了全局可視化系統,代號 Flux,可以將整個系統的邏輯架構和各服務之間的流量可視化在大屏幕上,效果圖如下:

他們每個月有一個活動:將一個 Region 里的機器全部關掉,看 Netflix 服務是否正常。有興趣看視頻的可以移步這裡。
另外,Netflix 除了雲服務,還有自建CDN,即 Open Connect 項目,這個項目的邊緣設備是地地道道的物理設備,並且從硬件到軟件全部是自己定製的。關於 Open Connect 的詳細介紹,以及使用的技術棧可以看 Netflix 的分享,還有他們如何做 CDN 監控的。
主要功能
回到 Spinnaker,他主要管理 Netflix 的雲服務,並不管理 OpenConnect 相關的設備和服務。Spinnaker 是基於雲的 CD 平台,提供快速、可靠、穩定的軟件變更服務。主要包含兩類功能:集群管理(Cluster management)和部署管理(deployment management)。
1. 集群管理
集群管理主要用於管理雲資源,Spinnaker 所說的「雲」可以理解成 AWS,即主要是 IaaS 的資源,比如 OpenStack,Google雲,微軟雲等,後來還支持了容器,但是管理方式還是按照管理基礎設施的模式來設計的。

Spinnaker 中管理如下資源:
Server Group:最基本的邏輯資源,包括了若干使用相同配置和鏡像的虛擬機,若干負載均衡(load balancer),以及安全組。 安全組規則(Security Group):就是 AWS 中的安全組,可以理解成防火牆。 負載均衡(Load Balancer):AWS 中的 ELB,也可能是安裝在虛擬機中的負載均衡。
2. 部署管理
管理部署流程是 Spinnaker 的核心功能,他負責將軟件包(可能是手工創建的或者 jenkins 創建的)打成一個鏡像,用這個鏡像生成對應的虛擬機,讓服務真正運行起來:

pipeline
在 Spinnaker 中一個部署流程叫做pipeline,由若干個操作組成,每個操作又叫做一個 stage
。觸發一個 pipeline 方式非常靈活,可以手動觸發,也可以用 jenkins、CRON 等。同時,可以配置 pipeline 向外發送一些通知信息,比如「開始」,「結束」,「失敗」等。
stage
pipeline 中的一個操作,stage 之間可以有先後順序,也可以並行。Spinnaker 中預定義了一些 stage 的類型,這些類型的 stage 往往使用頻率比較高:
- Bake:在某個 region 中製作虛擬機的鏡像。Netflix 推崇不可變基礎設施的理念,所以他們將軟件打包進鏡像的方式來部署服務。創建鏡像的核心基於 Packer(Hashicorp 開源的鏡像烘焙工具,Vagrant 就出自該公司 CEO 之手)。如果部署時用 docker,則打包過程就交由
docker build
完成。 - Deploy:用 Bake 中創建的鏡像部署成一台虛擬機。
- Jenkins: 執行一個 Jenkins 的 job。
- Manual Judgment : 暫停,等待用戶的許可後再繼續。
- Pipeline : 執行另外一個 pipeline。
- Script :執行任意的腳本。
- Wait : 等待一段時間。

從 pipeline 的定義看,Spinnaker 和 Jenkins 有幾分相似,不過兩者的設計出發點的不同,stackoverflow上有相關的討論。總結來看,jenkins 偏向 CI,產出物是軟件包;Spinnaker 是 CD,將軟件包分發到服務器/虛擬機上,保持軟件正常運行,它的目標只是讓「部署」的過程更容易更可擴展。有一個例子可以說明兩者的關係:Netflix 內部有人不用 Spinnaker 的 pipeline,而只是將 Spinnaker 看為一個部署工具,直接在 jenkins 中調用它的 API 來部署服務。
邏輯架構
Spinnaker 自己是一個微服務架構,由若干組件組成,所有組件都開源在github上,整個邏輯架構如下圖所示:

Deck:AngularJS 寫的 WebUI。 Gate:提供 API 接口給外部程序,Deck 也是其中之一,Spinnaker 的大門。 Cloud Driver:對接各種雲服務提供商,比如AWS, GCP, Azure 等。她負責所有對這些雲服務的讀寫操作。 Orca :處理 pipeline 和任務編排,比如創建一個虛擬機,等待它創建完成,然後執行其他操作。 Rosco 基於 Packer 的鏡像創建服務,她將一個 Debian 或者 RedHat 的包封裝到虛擬機鏡像中,這個過程有點像烘焙,所以也叫 image bake。 Front50 存儲所有pipeline,應用,通知的原信息。 Igor 對接 Jenkins 的服務,比如 pipeline 中需要調用 jenkins,那麼就依賴這個服務。 Echo 提供通知服務,對接各種各樣的服務商:Slack, Hipchat, SMS (via Twilio) , Email。 Rush 腳本執行引擎。
管理方法
Spinnaker 看起來也是一個複雜的微服務架構,由不少服務組成,所以本身也遵循一些運維準則:
- 每個 Spinnaker 的服務(如 deck,gate,orca)都運行在獨立的 cluster 中。
- 每個服務都將自己的運行指標推送到 Atlas 中,用於繪製儀錶盤和報警。Atlas 是Netflix的一個內存時間序列數據庫。
- 每個服務都將自己的日誌發送到 ELK 集群中。
- 每個內部服務除了deck 和 gate 必須用 mutual TLS,並且證書和認證通過 Lemur 進行管理。不允許任何外部流量進入內部服務中。所有的 API 調用必須經過 gate。
- 每個外部服務(除了gate)都要支持 mTLS 或者 SSO。
- 如果某個服務有數據存儲的需求,那麼只能存在自己的數據庫中,服務之間不共享數據存儲。
為了保證兼容性,Spinnaker 在開發過程中還會准守一些準則:
- 保證足夠的單元測試和覆蓋率。
- 在 code review 的時候特別注意是否會破壞API兼容性。
- 7×24 不間斷的執行集成測試。有兩種集成測試,一種是一個 jenkins job,會不斷調用 API 接口,確保API是按照預想的在工作,另一種是一個 Spinnaker 的 pipeline,用來執行日常任務(比如創建鏡像,部署環境等)。
- 當發現未知的失敗是,首先執行回滾操作,直到這個問題被修復。
總結
Netflix 是一個優秀的企業,有着自由的精神和先進的技術,崇尚 DevOps 文化。而 Spinnaker 是他們在踐行 DevOps 文化時創造出的優秀工具,通過這些工具我們能窺見他們對微服務和敏捷開發的深刻理解,希望能夠給國內的開發者一些啟發和幫助。