李斌作者簡介

李斌

阿里巴巴 高階技術專家

現在阿里雲負責容器服務的開發,在加入阿里之前在 IBM 工作多年,主要從事企業應用以及雲端計算的研發和運維。

前言

本文分享會有三個方面的內容:

  • 第一是單體應用和微服務,我們會討論在微服務當中容器和容器技術提供什麼的支援;
  • 第二是容器即服務;
  • 第三是容器即服務在微服務的開發運維當中起什麼作用;

1、單體應用和微服務

1.1 什麼是單體應用

談到微服務,相對應的就是單體應用,單體應用的抽象示例大家可以看這個照片。

單體應用

單體應用把所有的東西放在一起,內部通過模組呼叫完成所有的工作。好處就是上手非常快,上手快的好處就是變現也特別快,流量上的也非常快。

慢慢你發現單體應用架構上的問題就出來了,這些問題最大的情況就是自己內部依賴特別強的情況下,升級維護都有很多的麻煩。這也是微服務需要解決的問題,這背後的原因是什麼,大家可能討論了很多。

大家也許聽說過康維定律這個概念,系統的架構上和組織架構是一一對映的,你可以想象程式做得越好,公司發展越快,內部組織架構也會變化的很快,慢慢就會發生組織架構和應用架構不匹配的情況。

這種情況會引起很多麻煩。康維定律並不是有好有壞,只是一個現實,存在即合理,如果真的是想解決這個問題,就是要專業人做專業的事情。

1.2 什麼是微服務

微服務

有一篇文章討論微服務相關的概念,把一個 Java 的應用當成像一個 Unix 程式一樣,每個程式只做一件事情,做到最好。大的系統通過多個程式組合而成。這篇文章探討了一個在實際專案當中怎樣把一個 Java 應用做到這一點。

我的理解單體應用就是把所有的雞蛋放在一個籃子裡頭,這裡一個籃子就是一個程序。微服務就是把所有的雞蛋放在所有的籃子裡頭,在這種情況下,微服務的好處直接解決了單體應用的問題,升級部署都會好很多。

但是問題就馬上出來了,我們可以想像如果是你原來只有一個應用要維護,你的維護成本和你如果有一千個服務,一萬個服務,維護的工作量差異會非常大,複雜性也非常大。

1.3 微服務神器Docker

Docker 能解決很多問題,有應用分發的一致性,保證應用在中心各個環節裡頭可是可以都使用的。

第二個解決了隔離性的問題,如果你一個環節裡頭很多個應用,出現各種依賴的問題以後很難解決,你維護的惡夢就開始了,採用 Docker 技術後,一個節點可以跑多個容器,容器之間是隔離的。

容器映象作為一個標準打包格式,能夠分發,作為一種服務部署和分發模式會非常好,我們可以用 Docker 做微服務。

1.4 理想與現實

 理想與現實

這張圖,我們想象的微服務像一個戰隊一樣,星戰重點描述的是駕駛員的勇氣,後面有一個支撐平臺,如果沒有這個支撐平臺,英雄就變成了無頭蒼蠅的一堆隕石飛來飛去。

我們在微服務的實踐當中碰到了非常多的問題,怎麼解決。我今天的題目就是用一個CaaS平臺解決微服務在做的過程當中都有哪些事情。

1.5 微服務和Docker

Docker

有人問 Docker 到底做什麼,本身 Docker 是一種打包的映象模式,並且是一種執行的方式,能夠讓映象以一種標準方式在各個環節裡跑,這是國外的調查,有很多公司把 Docker 作為自己雲戰略的核心。

另外一個就是做微服務,  Docker 和微服務之間有一些千絲萬縷的聯絡,最後一個是  Devops,如果一旦有了容器了,把交付標準化了,就相當於集裝箱標準化以後把物流標準化一樣,這就是如果咱們要用 Docker。

2、容器即服務CaaS

CaaS

這是一個 CaaS 圖,如果大家自己使用過 Docker 的話,可能很多人覺得這個東西上手太容易了,我們用它來解決業務問題就非常容易。

在自己的膝上型電腦上裝一個 Docker 引擎,映象拉起來應用就跑起來了,如果做一個簡單的應用映象,上手也非常容易。這會給大家造成一個很大的錯覺,就是 Docker 用在生產環境裡頭是很容易的事情。

好多文章說 Docker  遍地都是坑遍地都是雷,不是那麼容易的事情。比如說容器的排程、控制、監控、服務發現、日誌管理,甚至高可用,很多事情都要做,這實際上不是一個軟體分發的機制就能解決的了。

所以 CaaS 平臺出來的目標就是,CaaS 平臺會讓使用者擺脫自己重新搭建這麼一個平臺的難度,讓你專注於應用本身,專注於應用的釋出和執行。所以這張圖只是告訴大家如果一個 CaaS 平臺大概會做什麼事情,CaaS 平臺最好的解釋也是在網上大家可以看到的,就是構建,然後釋出和執行。

2.1 實現Caas能提供哪些開發和運維的支援

在微服務的實踐當中,這個 CaaS 到底能幫助做什麼?

 CaaS

  • 第一個是服務的發現和路由

原來的時候應用之間互相呼叫的話可以用一個IP地址來互相連結,但是在雲上,容器啟動會非常快,也會消失遷移之類的,這是一個特性,不能假定IP地址永遠在那,也不能假定這個服務的例項就某個特定的例項。

在這種情況下,最重要的就是服務發現機制,服務發現包括註冊的機制和服務的路由。一個請求,到底是讓哪個服務的例項來實現,有兩類,一類是內部的請求,一類是外面的請求進來了,怎麼路由到內部的服務。

  • 第二是釋出策略和彈性伸縮
    釋出策略這件事情是上線最後一個環節,我們知道現在已開發測試已經自動化了,真正上線的時候,可以很多釋出策略可以選用。CaaS 平臺能不能提供這樣一些支援?用了容器以後大家看重的一個好處是能不能在業務量發生變化的時候進行動態的容器伸縮。
  • 最後是服務管控和SLA

服務管控和SLA等下會介紹,這是不完全的列表,不是說微服務當中只有這些問題,也不是說 CaaS 平臺只解決這些問題,只不過拿這個平臺做一個例子,如果一個 CaaS 平臺對微服務進行支援,到底會支援成什麼樣。

2.2 Routing Mesh

首先介紹服務發現服務路由以及相關的東西。在 Docker1.12,新出了一個很有意思的概念叫做 Routing  Mesh,routing 就是路由,Mesh 就是人人為我我為人人的意思。 Routing Mesh

一個請求進來以後會在每個節點上都會有一個類似路由器這樣一個東西,這個路由器的東西可以把請求分發到叢集裡面任何一個其他的節點上,這樣的好處就是不是一個集中式的東西,這有點像負載均衡,也有點像全員參與的負載平衡。如果 CaaS 平臺已經用了 Docker1.12 天生就有這個能力了。

2.3 服務發現與負載均衡

如果有人說現在還沒到 Docker1.12,那麼可以通過一個內部的負載均衡和服務發現結合起來,完成兩件事情。一個是服務發現一個是負載均衡,外面的請求進來以後,怎麼定位後面的服務例項,請求是由誰來完成的,這是發現服務,可以理解為一個數據庫。

後面所有的例項啟動以後都會向發現服務報告一下我在這兒。我的IP地址等各種資訊,路由器根據的負載把請求傳送到一個具體的服務例項上面,這本質上講是負載均衡,實際上完成了服務發現的功能,這是一個比較容易理解的架構。

我們不喜歡使用者寫一段指令碼自己編排運維這些東西,所以我們說在部署模板描述檔案裡能不能把這種東西描述出來。

舉例,如果接觸過 Docker 的會知道這是一個 Docker 的部署模版,描述了一個服務,這是映象,這些服務之間什麼關係,如果沒有接觸過 Docker,你就可以理解成這就是一個部署模板。

在部署模板中大家都知道是宣告式的,而不是程式設計式的,怎麼樣用宣告式的方式描述剛才我說的這些關係,這些關係就是說現在已經有了的這些基礎架構。

首先使用者寫的這個服務,我對外的80埠被宣告成一個;其次就是自動伸縮的能力,右邊兩個綠色的,我們真正使用者提交上來的服務,啟動的時候部署的時候直接起兩個例項。

還有就是 probe url,讓系統平臺怎麼知道容器裡的應用是活著的,這裡很簡單直接訪問80埠根目錄,只要是200我就是活著的,如果測試80埠沒反應,說明應用就死掉了,以後的流量就別往這兒來了。

我們不需要使用者自己寫一段指令碼做配置,也不需要在服務上掛一個鉤子的東西,只需要一個宣告的方式表達我想要的結果。解決了在外面我服務發現的問題,這個服務請求一旦進來以後,我就到了後面就是一個負載均衡,從這個頁面可以看出一個很也意思的概念—架構即程式碼

說明:架構即程式碼—就是說我描述的不是過程,我要描述的是最終結果,最終結果可以像程式碼一樣被管理起來,這裡就反映出這樣的一些概念。

2.4 日誌集中和分析

集中和分析

剛才是服務發現和服務路由的情況,如果用了 Docker 如果做了微服務以後,日誌管理和監控這件事情怎麼做。原來如果有五臺十臺服務的時候,出了問題自己上伺服器上拉日誌。自己也可以搭建一個 ELK,主要解決的是集中的問題。

作為容器服務平臺,就要替使用者解決日誌集中的問題,把集中的的日誌檔案通過一個管道送給分析服務,如果容器裡應用直接往標準輸出寫日誌,系統會自動把這些日誌集中起來。

如果應用把日誌寫到檔案目錄裡,這個能不能抓去呢?也可以,只要宣告一個日誌目錄的一個標籤,說明日誌在某某路徑之下,那麼容器服務也會自動把這些日誌收集起來。

日誌收集好了,還要分析。日誌的集中和分析方案非常多,假定使用者在應用已經有了自己的日誌和監控,是不是必須放棄掉原來的用系統的這個呢?不是, Docker 很重要的一點是生態,有很多這樣的一些開源工具也可以完成這樣的任務,都是可以和系統接起來的。

2.5 監控與彈性伸縮

彈性伸縮這件事情實際上聽起來很高大上,但是實際上真正執行起來有非常多的複雜性,這裡展現的就是如何彈性伸縮,監控系統會把所有的這些指標都監控起來,包括容器的、虛擬機器的、網路的,還有其他的服務都監控起來。

定義一個策略,一旦某種情況發生以後需要做什麼事情,也是用宣告的方式。上面第一句話的意思是平滑後的CPU利用率超過的70%後,可以按照按兩個容器的步長增加的速度來擴充套件。這裡沒有指定下限,所以這個策略只漲不跌。

 監控與彈性伸縮

我們看這個圖,對請求處理上是分佈在兩個不同的節點上的。雲監控發現CPU指標達到了設定的閾值後會通知叢集,叢集的控制節點會起兩個容器。這兩個容器是平臺排程的,會選擇最合適的負載能力的節點去做,這個圖裡面有兩個節點,都有資源,所以這兩個新的容器就會被平均分配在這上面。

3、CaaS在微服務運維開發中的作用

3.1 SLA保證

下面這塊對大家的影響平常顯示不出來,如果出現問題有巨大的作用,這就是 SLA 的保證。 SLA 的意思就是作為一個服務提供商,怎麼保證實現我說的要做的一些業務指標承諾,比如實現高可用。

SLA保證

  • 自定義命令/HTTP等健康檢查
    再比如說自定義的 HTTP 命令,定義負載均衡的時候,可以指定一個URL,表明容器裡的服務是不是健康的。

    沒有這個功能的時候,系統只知道 Docker 這個容器是不是正常在跑,沒辦法判斷 Docker 裡面的應用是不是真的是活著的。自定義命令和 HTTP 這種方式是在 從Docker1.12 開始引入的。在這之前,阿里雲的容器服務已經實現了這個功能。

  • 按照資源約束的排程和再平衡。
    資源約束的意思是這個應用需要多少資源,根據資源約束來部署執行容器。
  • 節點故障自動重排程

我們經常碰到的一個問題是容器是沒有狀態的,容器掛掉了,或者容器所在的節點掛掉了,另外一個容器起的時候要保證當初掛的那些儲存要跟著遷移過去。

有的服務天生就喜歡和有的服務在一塊,比如說一個 Web 應用就喜歡和資料庫服務待在一個節點上。有些服務天生不喜歡在一塊,假定做了一個數據庫主備別把它們放在一個節點上。

跨可用區排程意思是,假定我的應用必須是高可用的,例項要分配在多個可用區中。這些要求也可以通過宣告的方式來描述,不用寫指令碼。

3.2 微服務上線釋出策略

最後一個是服務的釋出策略,做 Devops,關注自動化從頭到尾只是解決了第一步,第二步是部署,部署和上線釋出的策略問題。

我們知道新服務的第一次部署可能在公司建立的第一天就完成了,隨後每天都是在升級都是在釋出,釋出如果解決不好了,Devops 做的就是比較華而不實了。

現在業界有很多討論,我們到底有哪些釋出策略,這是網上的一些圖:

  • 有藍綠髮布,老服務在這執行著,部署新的服務,我們稱之藍色服務,服務起來了以後,不把流量切換到藍色服務上,驗證藍色服務,如果沒問題了再切換過去,把綠色服務刪掉。

    在這個過程當中只有短暫的一個流量切換的過程,這是藍綠髮布,意思就是兩個叢集的流量從零到百分之百,要麼是零要麼是百分之百。下面這個圖大家可能看不太清楚,跟這個很類似,這是老的這是新的服務,這裡面流量不是百分之百,應該是5%或者是95%,意思是逐步切換,。

  • 還有一種模式是金絲雀釋出模式,正常老的服務都是粉色的,金絲雀是新版,叫金絲雀是因為在礦井裡面,金絲雀對瓦斯特別敏感,稍微有點危險訊號就死掉了,我們先放一個金絲雀,如果程式碼沒有問題,就可以慢慢把所有的服務升級上去。
  • 最後一個圖是AB測試,實際上是一種驗證措施,假定新上線的頁面,我們需要檢驗它的作用,可以把流量分成兩半,對於使用者來講看到的是同一個頁面,但是後面左右兩個不同的服務,通過一段時間的觀察,看看同樣的流量情況下面,執行的效果是不是都有變化。

所有的這些釋出模式,在網上都有很多討論,也都有很多實踐,如果自己完全都是從頭搭也可以。但是如果裡用了 CaaS 服務,平臺應該提供這些能力,你不用再自己搭了。所以說在容器服務裡面,Devops 最後環節裡面最後這一公里給你解決了。

小結

這裡我說微服務是冰山一角,冰山下面實際是最大的一砣,分散式系統部署運維,服務治理,還有一個我們剛才沒說的應用服務化改造。

這裡總結一點,我們看微服務冰山一角是非常亮的,但是底層的支援東西是非常重要也是非常大的,這是我們運維人員要做的事情,也是一個 CaaS 平臺想為運維人員所能提供的一點幫助,這個幫助就是我剛才提到的六個方向。

文章來自微信公眾號:高效運維