8月19日數(shù)人云Meetup上來自當當網(wǎng)的高洪濤老師做了《當當云原生DevOps實踐》的主題分享,從應(yīng)用改造入手,重點講述了運維核心—監(jiān)控的相關(guān)內(nèi)容。
數(shù)人云提醒:8000字長文值得分享與收藏!
今天跟大家分享下,目前比較流行的云原生概念個人關(guān)注要點:
- 首先:在于整個應(yīng)用的改造,包括Infrastructure,有12個要素
- 其次:運維的核心——監(jiān)控,主要講一下核心指標如何確定
- 第三:當當運維網(wǎng)絡(luò)采用的Service Mesh架構(gòu)相關(guān)內(nèi)容
- 第四:日志的搜集等

云原生即Cloud Native,最早來源于如Landscape此類做微服務(wù)的公司,線路圖包括幾層:
第一層:應(yīng)用的定義與開發(fā),開發(fā)要符合云原生的標準,如何讓應(yīng)用在開發(fā)階段達到此標準,是本次分享首先要探討的內(nèi)容。
第二層:編排和管理,大家對這個概念了解較多,如DCOS、Kuberentes、Mesos以及Docker Swarm,包括像Docker Conpose的一些配置化管理可能也會在編排里。
第三層:運行態(tài),環(huán)境從外部獲得相關(guān)的一些概念。
第四層:迷你環(huán)境的配置與安裝,一部分人可能原來用過,最早如Puppet、Self以及最近的Ansible,此類組件都會作為這一層使用。
最底層:普通的IaaS層、包括邏輯、運營商。
若應(yīng)用符合多層的規(guī)范,即可輕松的橫向擴展、在不同云間做遷移,能在公有或私有云上跑,但這比較難,因為很多應(yīng)用上云之前要經(jīng)過改造,所以個人認為云原生本身是對架構(gòu)的挑戰(zhàn),其讓應(yīng)用可以在云中間來回穿梭,而不會不適應(yīng)。

上圖是網(wǎng)上的開源圖:Cloud Native Computing Foundation即常說的CNSAD,一個云原生基金會組織,其實就是一些云原生品牌大聯(lián)盟,若從上到下都使用此體系,那么你也是云原生的了。
例如,最左邊是語言,最頂級為GO語言,號稱最適合做微服務(wù)的語言,然后是一些編排工具:持續(xù)集成工具,以及比較流行基于服務(wù)的中間件,第二層編排工具,首先是Nginx,如常用的Mesos、Nomad,中間是配置工具:Etcd、ZK,后面是一些網(wǎng)絡(luò)服務(wù)管理,當當使用比較多的是GRPC,以及本次分享會涉及到的Linkerd,它旁邊是Buoynt,也是Linkerd的開發(fā)者。
對于運行態(tài)來說,基礎(chǔ)的運行S3較為常見,如Docker、Rkt就是運行環(huán)境的容器,云原生目前提供幾個方便的如CALICQ(當當目前正在研究),OVS,再底層是構(gòu)建工具:如ANSIBLE。最底層如微軟的相關(guān)產(chǎn)品,AWS進入中國后發(fā)展也比較迅速。另外還有阿里云、京東云等類似的公有基礎(chǔ)服務(wù)平臺對外提供一些服務(wù),供商家運行調(diào)用,以及一些邊緣服務(wù),如Splunk、如當當?shù)腅lastic流水線。
云原生應(yīng)用的12條軍規(guī)
前面的整套產(chǎn)品線用下來,即可認為應(yīng)用是云原生的,而什么是云原生標準的套路呢?個人認為有12個因素,即云原生應(yīng)用的12條軍規(guī),有些概念和微服務(wù)重合,但云原生的概念要大于微服務(wù)。

上圖是當當目前內(nèi)部運維的作業(yè)平臺,整合了整個DevOps理念,有人講DevOps時首先強調(diào)的是Developer和Operater,但我認為其核心在于測試,當當內(nèi)部以測試為核心帶動開發(fā)和運維,保證服務(wù)的可用性,三個團隊緊密配合將整個服務(wù)推向一個穩(wěn)定的局面。

上圖是12條因素即12條軍規(guī),這里挑幾個重要進行講解:
Codebase:和整個測試環(huán)境有關(guān),大家拉基線是為了整個版本的穩(wěn)定性。
依賴:要解決依賴的問題,若用Java的話,意義不大,原始上會有依賴管理,但電商公司有各種語言都非常原始,直接依賴于源代碼,若其版本發(fā)生變化,有些API就編譯不過去。
Configuration:Java和其他語言非常沖突就在于此,做Java的同學(xué)都知道配置一般都會打在根應(yīng)用的生產(chǎn)日報里,會有大量的配置文件,上到云應(yīng)用,讓底層人員運行作業(yè)炸包,首先就要配置文件,一切配置要么走配置中心,連訪問配置中心的地址可能也是外部注入進來,不用再去配置上聲明整個中心是什么;要么是所有的配置都由平臺幫助注入,不能自己攜帶相關(guān)的Jap去做,原來整個構(gòu)建,底下會有一些構(gòu)建的模式,之前構(gòu)建最早版本非常有意思,比如大了一個測試環(huán)境的炸包,若沒問題,即可交給運維,因為配置VI里面完全不一樣,會在應(yīng)用和部署的公共機器時,有自動替換配置文件的動作,要替換的配置文件其實也是預(yù)先上傳到平臺上的,整個發(fā)布平臺會幫助做一個配置文件的替換,方式很原始,不是運行它去改配置,因為包本質(zhì)上是變化的,配置文件屬于包的一部分,因此它也是變動的,等于整個包的密封性被打破了,此時去上一個云原生的平臺,首先要做的是滅配置文件,要通過環(huán)境變量或啟動平參數(shù)的模式去啟動應(yīng)用,這時平臺能自動地把整個環(huán)境——生產(chǎn)、預(yù)發(fā)布、測試、以及延長等環(huán)境,將不同的配置設(shè)置好,所以這一點對開發(fā)來說改動比較大,正常上這種云應(yīng)用,最難的是將配置問題解決,因為大量的Java配置都是在文件中進行,包括內(nèi)部有框架的,特定的文件,將這些都清除掉。
Backing Services:即不要把依賴服務(wù)完全寫死,依賴服務(wù)也是通過環(huán)境注入進來,如數(shù)據(jù)庫連接,可以通過外部配置進來。
構(gòu)建、發(fā)布和運行:要流程化。
進程:進程是微服務(wù)的根基,應(yīng)用應(yīng)以進程的級別運行,跟原來的方式不同,很多功能都是達到一個進程,通過不同的線程運行,但有幾個不好的地方,類似于微服務(wù),發(fā)布可能會影響不應(yīng)影響的一些部分,追蹤也不是很好做,比如當當最近在做內(nèi)部的Tracing,目前只能做到進程間的Tracing,如果內(nèi)部的線程Tracing需要改造,還是有一些麻煩的。
端口:類似于一種端口的綁定解決方案,是由編排工具動態(tài)注入,要動態(tài)監(jiān)聽一些要發(fā)布的端口信息。日志:不應(yīng)生成文件,而是通過服務(wù)的方式將其進行傳遞,整個管理平臺應(yīng)有自動收集日志的功能,這也達到了云原生的態(tài)度,要將所要定位的信息不和應(yīng)用綁在一起,因為應(yīng)用很快會啟動或注銷,那么整個軌跡要持久化的保留,所以日志是整個云原生問題的核心,后面會進行詳細的講解。

上圖是當當內(nèi)部培訓(xùn)的圖,淺藍色是線下操作,是在云平臺之外的,因為都是第三方組件,包括開發(fā)、構(gòu)建過程,接著在云平臺上配置作業(yè)。藍色部分是開發(fā)或由測試提交,黃色部分由運維操作。團隊之間會通過這樣的配置去調(diào)整和審核,控制整個平臺的用量,因為用Mesos跟Lite版本不一樣的地方在于聲明時要聲明CPU和內(nèi)存,還會定義一些特性資源如:NFS,包括一些共享的存儲,這些會配置到配置里,此時也要有一個審核,讓其之間做個比較完美的交互。
監(jiān)控——核心指標設(shè)定

上面講了Dev,剩下的幾個環(huán)節(jié)講一下Ops有關(guān)內(nèi)容,首先:核心指標的設(shè)定。
上圖是我自己畫的云圖,來源于Diggtal Dog網(wǎng)站,它有一篇Blog講運維監(jiān)控指標,基本上是暗詞的權(quán)重,除了這個云層,另外比較主要的是Mertics,其實應(yīng)該過濾掉,如Error的數(shù)量,Success等各種指標,畫上圖最大的用意是讓大家看到——亂。
因為指標很多,Mesos所有的凈化API有20多個,它的指標可能有30—40個,但如此多的指標,每天都有大量的信息,各個指標間有很多聯(lián)動關(guān)系,大數(shù)據(jù)可以去聯(lián)系、判斷哪種指標在日常組合的情況下是影響系統(tǒng)發(fā)揮的,但目前的技術(shù)仍然難以做到,最簡單的方式是從這些紛繁的指標中找一個最適合自身的,在構(gòu)建自身監(jiān)控指標時,一定要找到一個上帝指標,若有人說,現(xiàn)在某個作業(yè)有問題,優(yōu)先看這項指標,如果這個指標沒有問題,那么狀況應(yīng)該不大。
SLO=>SLA
這個指標其實就是SLA,使用比較多,SRE對SLO到SLA的推導(dǎo)是有過程的:SLO是服務(wù)質(zhì)量的目標,在運維各個系統(tǒng)時,系統(tǒng)的服務(wù)質(zhì)量需求不同,某人過來找你,某作業(yè)非常重要,如果一天不運行,會丟掉多少單,但若細聊,會發(fā)現(xiàn)每個人的服務(wù)指標不一樣,能忍受的指標也各不相同,跟他去嘆號你的服務(wù)指標,是3個9、4個9或50%都可以,有些作業(yè)只要70%就夠,雖然偶爾失敗,或者70%的成功也不會影響服務(wù),將SLO設(shè)定好,即可推到SLA是什么,一旦確定,就是跟開發(fā)之間建立了一個生死契約,但跟市場不同,市場跟客戶簽,對方場上會寫個SLA,當然一般也不會去評估,開發(fā)不同,開發(fā)簽指標后,是要算績效的,所以一旦跟他說了能達到幾個9,就一定要做到,否則自己的獎金也發(fā)不出來。
好處是會約定雙方,開發(fā)不會提出過分的要求,比如偶然宕機,也不會找你,因為還未達到它的底線,如果有些嚴格指標,需要提供更好的服務(wù)給他,比如調(diào)度時會給他分配更好的服務(wù)器,做一些預(yù)先的割裂,將其和一些作業(yè)隔離開。
SLA=ST/ET
SLA指標在做系統(tǒng)時要注意怎么設(shè)置,平時方法很簡單,WEB應(yīng)用很好設(shè)置,訪問10次,有9次返回404,那這個SLA才10%,但作業(yè)其實不好衡量,本來說是每5分鐘要運行一次,但如何衡量?是處理數(shù)據(jù)量的多少嗎?自己的指標需要自己去設(shè)定,這個是ST/ET,S是真正運行次數(shù),即在10分鐘內(nèi)根據(jù)表達式,成功運行多少次,是有標準的。E是期望這段時間內(nèi)運行多少次,有一個口號表達式去計算即可在一個時間范圍內(nèi)算出應(yīng)該運行多少次,所以和一些應(yīng)用不同,這個有平臺的特點,是針對定制作業(yè)設(shè)計的SRE指標。

給大家分享一個實例,可以看到出了故障,目前已經(jīng)降到53%了,具體的作業(yè)已經(jīng)抹掉,由于自身寫錯應(yīng)用有BUG,造成執(zhí)行失敗,上面的曲線是Grafana的一個圖,整個SLA有時會100%有時會降到50%幾,下面是用來顯示SLA如何計算的綠線,可見除了偶爾波動外,比較均勻。底下這條線是實際運行次數(shù),偏離度較大,因此可以得出,在哪個時間段出了問題,幫助進一步定位。
所以關(guān)鍵的監(jiān)控指標,對于輕量級監(jiān)控是非常重要的,為什么只抓一個指標就夠?Mesos給的官方建議是如果集群內(nèi)的任務(wù)快速失敗,就會報警,當當基于此建立了報警,有時會出現(xiàn)報警,查一下這個指標,如果沒有問題,就可以認為是由于偶然的情況下做了一些失敗的專一,不會有太大的影響,這就是設(shè)置關(guān)鍵指標的好處。
監(jiān)控——監(jiān)控監(jiān)控系統(tǒng)

監(jiān)控系統(tǒng)是否需要被監(jiān)控?這是一個老生常談的問題,首先監(jiān)控系統(tǒng)也是系統(tǒng),是需要被監(jiān)控的。這里進行一下反推,如果監(jiān)控系統(tǒng)萬一Down了就只能再加一層了,下面是Prometheus去采集整個Mesos集群的白核監(jiān)控數(shù)據(jù),發(fā)給Master做告警,接到內(nèi)部的Tracker的系統(tǒng)會根據(jù)告警級別去發(fā)送郵件、短信或電話。上面有個叫雷達的系統(tǒng),目前監(jiān)控整套的監(jiān)控系統(tǒng),已經(jīng)用了很多年,因為Prometheus也是整套的監(jiān)控系統(tǒng),再由它去監(jiān)控一個監(jiān)控系統(tǒng),如果雷達也Down怎么辦?不管做了HA或其他,仍然會有Down的幾率,但如果兩個系統(tǒng)同時Down了呢?
大家可以回溯一下剛才講過這個問題,監(jiān)控系統(tǒng)本身也是一個系統(tǒng),到底要提供多大的SLA,要提供對外監(jiān)控4個9的目標嗎?另外上一套系統(tǒng)可以保證4個9,因為每套系統(tǒng)每年都會算一個SLA,將這個指標用上去以后,系統(tǒng)的可用度會上升,所以對系統(tǒng)的可用要量化、要度量,系統(tǒng)只要能用目前的方案達到SLA設(shè)置的目標,就可以停了,如果達不到就不能停。

再回到上面這個圖,后來之所以加了一檔,因為Prometheus最早上線那版,為了塊它是個單點,無法保證線程目標,所以又加了一套監(jiān)控系統(tǒng),如果將Prometheus、Alertmanager在一開始就構(gòu)建比較完整的服務(wù),那么可以不用第二層監(jiān)控。
Service Mesh實踐
接下來是Service Mesh,APM 最近在北京召開,這是一個全國比較大型的監(jiān)控告警的會議,會上當當總監(jiān)講了一下這個概念,這概念是當時運營整個Mesos的后臺,引用到內(nèi)部服務(wù)范根的,所以再給大家案例一下相關(guān)的技術(shù)。

上Kubernetes或Mesos集群的話,都會遇到一種網(wǎng)絡(luò)問題,如果對容器的編排調(diào)度都感興趣,可以在網(wǎng)上搜:Kubernetes網(wǎng)絡(luò)、容器網(wǎng)絡(luò)、會有一大堆的概念,上去會告訴你OAS怎么配,F(xiàn)LANNEL性能會損失多少,Calico怎么用的BTP協(xié)議,其實剛才看了第一個圖,將的網(wǎng)絡(luò)其實解決的是整個網(wǎng)絡(luò)IP層的問題,會讓機器有多少個IP,為什么要解決IP層的問題呢,因為因為容器。比如一臺容器一驅(qū)10,一驅(qū)12,一1驅(qū)15可能是最高的,原來有1萬的集群節(jié)點,那么現(xiàn)在要乘10,網(wǎng)絡(luò)規(guī)模翻了10倍,IP地址同樣也翻了10倍,所以一些公有云的同志們會非??只?,因為最早的虛擬協(xié)議支持不了這么多的節(jié)點,因此提出了容器網(wǎng)絡(luò),包括CNI、CNM的標準,賬戶要解決IP不夠用的問題,其實這個網(wǎng)絡(luò)還有另外一套問題:容器起來后IP也會變,會有一些別的技術(shù)保證IP也會變,那服務(wù)要怎么辦?如何去發(fā)現(xiàn),如果后臺比如有10個WEB應(yīng)用去訪問,此時如何去負載均衡,如果有個服務(wù)長時間有問題,如何提供整個服務(wù)集群,如何做熔斷,這些都是微服務(wù)常見的網(wǎng)絡(luò)概念。
Service Mesh主要就是解決者方面的問題,即使底層用最原始的完全不用它自身的網(wǎng)絡(luò)方案,照樣可以使用,如圖,最外層如Nginx,作為一個邊緣節(jié)點,會將流量通過Service Mesh打到集群內(nèi)部的服務(wù),它們之間也通過Service Mesh互相訪問,然后集群外面來說,換成淡藍色不能用外部服務(wù),就是通過Service Mesh向外去訪問。

這里總結(jié)了三點功能:
第一點是Service Discovery即服務(wù)發(fā)現(xiàn),和正常的如微服務(wù)的發(fā)現(xiàn)不太一樣,微服務(wù)發(fā)現(xiàn)用Cloud基本上也會存一些中間的存儲,ETCD比較多,包括DK,Consul這些,有人用Redis也存過,怎么也得把服務(wù)之間的調(diào)用關(guān)系存起來,這個Service Mesh大多是從第三方平臺獲得服務(wù)之間的IP地址和聯(lián)系,第三方平臺包括Kubernetes,包括這里寫的DCOS,DCOS是另外一個概念,即Mesos加Marathon再加一套新構(gòu)建的組件,合起來可能就是DCOS,從這里面把相關(guān)的服務(wù)信息采集出來就能做服務(wù)發(fā)現(xiàn),比如注冊個應(yīng)用,每次啟動時,這個應(yīng)用本身的IP地址,可能端口通過Mesos或Nginx分配的很明顯,因此如Linkerd、Istio就可以把IP地址獲取下來,當你訪問時組件是知道的,這是它大部分做服務(wù)發(fā)現(xiàn)的原理。
第二點是負載均衡和健康檢查,上面說過,一個服務(wù)可能是3個實例、10個實例去對外提供服務(wù),那本身應(yīng)用基本軒哪個服務(wù)就涉及到負載均衡,如果應(yīng)用上調(diào)不通,會踢出集群,這就是健康檢查。這部分可能分為兩大流派,第一大流派是做用戶層的,就是七層負載,比較傳統(tǒng),我們用的跟NG差不多,因為我們還會有其他別的信息;另外一種是使用本地IP Temple進行轉(zhuǎn)發(fā),此時更像原生的另外一個部署模式,包括像DCOS本身有一個Minuteman的組件,轉(zhuǎn)發(fā)的速度會很快,但這種有一個問題,服務(wù)失敗就是失敗了,通過這個端自己增加處置機制,還有HA的功能也不能做,所以它有一些限制。
最后比較重要的是Metrics和Tracing的對外暴露,像是這種新一代服務(wù)的組件,對外暴露各種Metrics的指標,如Linkerd,包括Istio都會暴露Prometheus的這些監(jiān)控,還會自帶一些Tracing的功能,是一種廣播級的追蹤,linkerd目前只能支持一種,因為它來自推特,推特的組件叫ZK,Tracing技術(shù)比較特別,需要修改服務(wù)的Hander,然后去加一些額外的信息,因此雖然Linkerd在官方主頁上公開了Metric,比如說Tracing是插件式的,但需要Tracing的服務(wù)去支持SPIN的協(xié)議才可以,這個比較坑。我目前正在給我們用的Tracing的截殺軟件,會截掉一部分Linkerd的Scalar代碼,將它的整個Hunter協(xié)議改掉,這樣才能支持別的協(xié)議模式,目前正在內(nèi)部試運行,后續(xù)用Linkerd較多的話,會向它提一些PR,讓它將整個Tracing開源。

這是在官網(wǎng)上截的一個圖,可以讓大家更深刻地理解,用過Kuber-Proxy的同學(xué)知道,這是和它一樣的,在機器上,服務(wù)過來先找它,通過代理模式再打到另外一臺服務(wù)的Linkerd,每次的服務(wù)訪問,被訪問其實都是通過本地的其他技術(shù)去發(fā)起的。
目前在跟進Skywalking,它是另外一個開源組織。不知道大家對Tracing有多少了解,要不是用手工的方式將監(jiān)控數(shù)據(jù)往外發(fā),如果不想修改代碼,目前只能用Java,要根據(jù)不同組件做埋點,需要看埋點插件的豐富度了,但埋點了以后會對性能稍微有一些影響,目前做的事是將整個Tracing的插件直接做到Linkerd上,服務(wù)之間調(diào)用,可能整個Tracing圖沒有了,但整個訪問統(tǒng)計還在,因此這個意義很大,如果完全不想動代碼的結(jié)構(gòu),直接上我們的整個組件,自身就帶了Tracing的過程。
離線與在線日志

離線和在線日志目前也是云原生比較重要的一環(huán),先解釋下Mesos Sandbox,Mesos會把待執(zhí)行的包下載到本地,生成一個臨時目錄,目錄很長,有很多CP數(shù),這里面就是Sandbox,原理和Docker一樣。日志要打到Sandbox里,否則就沒法看到日志,可能有些人原來不應(yīng)用,會打到某些固定的路徑,這時會要求打到相對應(yīng)的路徑里,此時會提供兩個文件:STD error、STD on,把標準輸入和標準輸出寫到這個文件里。當當目前只采集標準輸出或標準出錯,所以原來如果寫了一些特定格式的日志,會被要求改掉,其實開發(fā)還是很高興的,因為開發(fā)環(huán)境一般都是標準輸入和標準出錯的,開發(fā)那套關(guān)于日志配置不必修改,直接打到包里,上面說第一步要改應(yīng)用,首先把配置去文件化,日志的配置不用改,因為線上也只采集這兩個文件。

流程從右向左,F(xiàn)ilebeat目前是整個集群比較常用的組件,Logstsh是一個Transform,發(fā)到Elastic Search里,最后有Kibana提供服務(wù),中間緩沖用的是卡夫卡,此時運維和開發(fā)都可以通過兩種模式看日志,日譯中模式是直接訪問剛才的Sandbox,訪問的頁面通過整個運維平臺,直接點到頁面里面。

另外通過ERK平臺,在線看日志可能類似于上圖這樣一種格式,一行行打印出來,然后web頁面能自動滾動,可以看一些即時日志。

搜索統(tǒng)計還是走Kibana,上圖是測試環(huán)境的Kibana,會統(tǒng)計一些相關(guān)的日志指標。
高洪濤老師將多年的運維及開發(fā)相關(guān)想法融入到本次演講當中,如云原生應(yīng)用的12條軍規(guī),當當監(jiān)控指標制定規(guī)則,以及當當網(wǎng)的Service Mesh實踐進行了詳細地分享,小數(shù)希望大家在看完這篇長文后能夠有所收獲。