2018年數(shù)人云Meetup第一站础锐,聯(lián)合vivo在深圳舉辦 Building Microservice 系列活動第一期嗓节。本次技術(shù)沙龍vivo、中興通訊皆警、華為拦宣、數(shù)人云共同派出技術(shù)大咖,為開發(fā)者們帶來有關(guān)微服務(wù)耀怜、容器化恢着、配置中心、服務(wù)網(wǎng)格等領(lǐng)域的實戰(zhàn)與干貨分享财破。
數(shù)人云Meetup每月一期掰派,歡迎大家來面基、學(xué)習(xí)左痢。本文為vivo云計算架構(gòu)師袁樂林分享的“vivo云服務(wù)容器化實踐”現(xiàn)場演講實錄靡羡。
今天講的內(nèi)容主要是介紹技術(shù)背景,產(chǎn)品的技術(shù)架構(gòu)俊性,我們關(guān)鍵技術(shù)的實踐略步,前車之鑒,以及對下一代云服務(wù)架構(gòu)的設(shè)想定页。
技術(shù)背景
vivo這些年的業(yè)務(wù)增長非程吮。快,用戶數(shù)已經(jīng)上億典徊,服務(wù)器到了萬級杭煎,業(yè)務(wù)域好幾百恩够,后端系統(tǒng)的復(fù)雜度在迅速攀升,不光是運維方面羡铲、架構(gòu)體系復(fù)雜度也非常高蜂桶,vivo技術(shù)架構(gòu)也是到了破繭化蝶的時候。
我們做過容器也切、虛擬機(jī)與物理機(jī)性能對比測試扑媚。上面這張圖是當(dāng)時做的性能測試架構(gòu)圖。得出了一些測試結(jié)論:
1.容器化app(4c8g)在性能上略優(yōu)于非容器化app測試指標(biāo)
2.容器化app(32c64g)性能相較于裸跑同物理機(jī)有近4%左右性能損耗雷恃,其中TPS有3.85%損耗疆股,平均響應(yīng)時間3.95%(1毫秒)的增加,對業(yè)務(wù)請求無影響褂萧。
3.容器化app在12h的穩(wěn)定性測試中表現(xiàn)正常
4.容器化app在cpu相對配額押桃,cpu綁定以及絕對配額場景下,業(yè)務(wù)性能CPU相對配額 > CPU綁定 > 絕對配額导犹。
5.容器化app在組部件異常,單計算節(jié)點羡忘,控制異常場景下谎痢,容器運行正常。
綜上所述卷雕,容器化app性能上接近物理機(jī)节猿,在多測試場景下,表現(xiàn)相對穩(wěn)定可靠漫雕。同時滨嘱,對計算密集型app,相對權(quán)重配額能實現(xiàn)CPU資源利用率最大化浸间。
vivo容器化云服務(wù)框架
正是因為這個性能測試數(shù)據(jù)的支撐太雨,就有了vivo容器化云服務(wù)框架,我們給它取名 Kiver魁蒜,提供輕量級囊扳、高可靠的容器化生產(chǎn)方案。
在這個框架之上vivo一共有八個云服務(wù)兜看,按照后來統(tǒng)計數(shù)據(jù)來看锥咸,MySQL加上其他兩個服務(wù)占到80%的比例,這也非常符合“二八”原則细移。
vivo整個云服務(wù)容器化產(chǎn)品的架構(gòu)搏予,左邊是運維自動化的工具集,比如日志弧轧、監(jiān)控等雪侥,日志在業(yè)界應(yīng)用非常廣泛球涛,我們用采集容器的數(shù)據(jù)、容器的監(jiān)控指標(biāo)校镐。
這里有兩個日志亿扁,上面是中間件的業(yè)務(wù)日志平臺,所有業(yè)務(wù)基于中間件日志規(guī)范鸟廓,輸出日志后都會送到這里面收集起來从祝,但是這個業(yè)務(wù)日志平臺功能目前比較薄弱,對新增加的一些組件引谜,比如ECTD等不支持牍陌。vivo又引入了現(xiàn)在容器領(lǐng)域比較常見的日志方案EFK,今后會規(guī)劃把兩個日志整合到一起员咽。
vivo在運維方面做了一些工具毒涧,如 vivo MachineCtl和 KiverCtl,兩個工具主要實現(xiàn)宿主機(jī)的自動化贝室,簡單來說可以把宿主機(jī)操作系統(tǒng)自動化地裝起來契讲,裝完之后變成Kiver的計算節(jié)點或者控制節(jié)點。還有KiverPerfermance滑频,是我們內(nèi)嵌的一個小的性能測試插件捡偏。
再來看右邊,是vivo的基礎(chǔ)設(shè)施峡迷,物理機(jī)和交換機(jī)银伟,網(wǎng)絡(luò)設(shè)備和防火墻等,上面是Docker绘搞,Docker容器虛擬化技術(shù)把物理機(jī)上面的相關(guān)資源虛擬化用起來彤避。
右邊有 Ceph 塊存儲,實現(xiàn)數(shù)據(jù)備份夯辖,上面是vivo自研的DevOps平臺琉预,做了調(diào)度框架,右邊是用harbor做的鏡像倉庫楼雹,再往上就是云服務(wù)Portal模孩,前面所說的那些云服務(wù),同時也可以跑長生命周期應(yīng)用贮缅。
宿主機(jī)自動化實踐
下面我們講一下vivo的實踐≌ジ溃現(xiàn)在物理機(jī)一旦上了規(guī)模之后率碾,裝操作系統(tǒng)就成為一件大事蛇耀,我們提供了 vivoMachineCtl,這個工具是一個命令行給運維人員使用辫狼,可以實現(xiàn)宿主機(jī)集中化的參數(shù)配置和自動化。
利用 vivoMachineCtl数焊,首先和物理機(jī)管理卡做一個交互永淌,交互之后拿到物理機(jī)的MAC地址,這里有個BMC佩耳,也有廠商叫iDrac卡遂蛀,它可以取得這臺服務(wù)器網(wǎng)卡的MAC地址,創(chuàng)建以MAC地址命名的Bootfile干厚,指明現(xiàn)在需要裝什么操作系統(tǒng)李滴,和其他一些參數(shù)。再進(jìn)一步給它一個ipmi消息對服務(wù)器復(fù)位蛮瞄,然后服務(wù)器開始重啟所坯。
重啟之后,服務(wù)器第一次會發(fā)dhcp請求挂捅,拿到IP地址芹助,之后會走一個pxe的協(xié)議,拿到bootfile闲先,下載Bootfile所指明的小系統(tǒng)和內(nèi)存文件系統(tǒng)文件下來状土,加載到物理機(jī)中,然后開始進(jìn)行操作系統(tǒng)安裝饵蒂。這就是操作系統(tǒng)安裝的過程声诸。操作系統(tǒng)安裝完成之后,把安裝類和文件系統(tǒng)切換成正在啟動的文件系統(tǒng)退盯,在post階段到集中化的配置中心,把相關(guān)的配置拉下來泻肯,包括IP地址渊迁,主機(jī)名和網(wǎng)關(guān)等信息,這是宿主機(jī)的自動化部署灶挟。
KiverCtl實際上就是把操作系統(tǒng)的宿主機(jī)變成計算節(jié)點或者控制節(jié)點琉朽。計算節(jié)點有如下幾個功能:第一,基本的包安裝稚铣,第二箱叁,Docker、Netplugin初始化惕医,啟動kiver-guard/flume/cadvisor容器耕漱,完成日志和監(jiān)控指標(biāo)的采集。
控制節(jié)點上面有Etcd和Netmaster抬伺,也會可選地Prometheus/alertmanager/grafana/啟動起來螟够。vivoMachineCtl和KiverCtl實現(xiàn)了云服務(wù)器節(jié)點從物理機(jī)到宿主機(jī)的轉(zhuǎn)變。
業(yè)務(wù)日志集成到日志平臺實踐
這是vivo日志采集的實踐,在宿主機(jī)上做日志分區(qū)妓笙,容器運行起來之后掛這個目錄若河,每個容器起來之后會創(chuàng)建一個自己的文件目錄。外面有kiver-guard寞宫,用來偵聽內(nèi)核文件系統(tǒng)的新日志文件創(chuàng)建的通知萧福。
根據(jù)通知會創(chuàng)建軟件鏈接,鏈接到上一級Flume監(jiān)控的日志目錄辈赋,由Flume推到kafka鲫忍。大數(shù)據(jù)平臺會來消費這里的數(shù)據(jù),業(yè)務(wù)日志平臺也會消費這個數(shù)據(jù)炭庙,然后持久化到ES里饲窿,最后由中間件日志平臺來實現(xiàn)對日志的檢索和展示。
為什么要這么做焕蹄?當(dāng)時用的flume版本不支持自動收集遞歸子目錄下日志新增內(nèi)容的收集逾雄,完整的文件可以收集進(jìn)去,但是日志文件在遞歸子目錄下有不停地追加是輸不進(jìn)去的腻脏。
kiver-guard本身也是一個容器鸦泳,它起來之后把宿主機(jī)日志目錄掛上去,在容器里面?zhèn)陕犎罩灸夸浵碌腸reate事件永品。
不管這些日志路徑有多深或者在哪里做鹰,都可以鏈接出來。做鏈接的時候有一點需要注意鼎姐,要確保鏈接過來之后文件名稱是唯一的钾麸。有些容器被刪除了,或者日志被輪轉(zhuǎn)刪除了炕桨,同樣也會針對Delete事件饭尝,偵測到delete是件之后刪除上層flume監(jiān)控日志路徑的對應(yīng)鏈接。
基礎(chǔ)組件日志收集實踐
基礎(chǔ)組件日志采用Etcd献宫、Ceph钥平、CentOS、Netmaster等一些網(wǎng)上比較熱門的EFK組件姊途,開箱即用涉瘾。
監(jiān)控與告警實踐
這是監(jiān)控和告警實踐,在容器領(lǐng)域比較常見捷兰,vivo采用的是Promethus和Alertmanager立叛。Promethus采用雙節(jié)點,雙拉(拉兩遍)寂殉,兩個Promethus之間沒有做主從囚巴,為了解決高可用問題,掛了一個另外一個還在。
之后接短信郵件中心彤叉,后面接Grafana作為監(jiān)控面板庶柿,前面用了telegraf。我們做的東西不僅僅有容器秽浇,還有其他的組件像Ceph浮庐。我們用Cadvisor收集容器監(jiān)控指標(biāo)。
我們對集群健康做監(jiān)控柬焕,也對集群資源使用情況進(jìn)行監(jiān)控审残,集群的健康性采用telegraf可以調(diào)用外部shell腳本的特性。我們在控制節(jié)點寫了腳本斑举,用來檢查Etcd的健康情況搅轿,也和各個節(jié)點進(jìn)行通訊,檢查各個節(jié)點是不是健康富玷。之后會返回數(shù)值璧坟,給出集群健康狀態(tài)碼。
這個就是前面講的自定義的一些監(jiān)控指標(biāo)赎懦,這是集群的健康檢查雀鹃,這是集群的資源利用率,大致兩條數(shù)據(jù)鏈進(jìn)來励两。一個腳本由telegraf去拉黎茎,推到Prometheus里面,最后展現(xiàn)在Grafana上面当悔。另一個傅瞻,由DevOps框架把數(shù)據(jù)寫到Mysql里面,再由Grafana定義Mysql的軟件源盲憎。
這邊拉出來的自定義的健康指標(biāo)支持返回碼俭正,這個返回碼需要翻譯成文字,實際上Grafana已經(jīng)具備這個特性焙畔,我們可以去做一個映射,比如1代表監(jiān)控串远,2代表網(wǎng)絡(luò)問題等等宏多,它可以自動翻譯來。
數(shù)據(jù)持久化實踐
說到云服務(wù)大家都會關(guān)注這個問題澡罚,數(shù)據(jù)怎么做到持久化伸但,做到不丟。容器啟動的時候會掛在宿主機(jī)上面的一個數(shù)據(jù)目錄留搔,和日志類似更胖,有容器的啟動進(jìn)程,直接寫腳本也可以,創(chuàng)造二級目錄却妨。
用主機(jī)名饵逐,是在容器默認(rèn)的主機(jī)名,就是它的默認(rèn)ID號彪标。如果這個ID已經(jīng)存在就不用創(chuàng)建倍权,說明容器是起用一個舊的容器,最后建立軟鏈接到數(shù)據(jù)目錄捞烟。這樣確保每個容器日志數(shù)據(jù)都持久化到宿主機(jī)薄声,還可以確保容器重啟后數(shù)據(jù)不丟。
第二题画,數(shù)據(jù)本身有一個單獨的備份系統(tǒng)默辨,它會每天晚上凌晨2點跑一遍,把Mysql數(shù)據(jù)推到Ceph塊存儲當(dāng)中苍息,實現(xiàn)數(shù)據(jù)的可靠性缩幸。
集群可靠性實踐
這是容器集群可靠性實踐,最典型的是三個副本档叔,副本能夠?qū)崿F(xiàn)數(shù)據(jù)和服務(wù)的可靠性桌粉。
失效重試,在集群各節(jié)點提供一個crontab定時任務(wù)衙四,每隔一段時間探測一次docker服務(wù)進(jìn)程健康狀況铃肯,若不健康,則拉起Docker服務(wù)進(jìn)程传蹈。同時我們開啟了docker的Restartalways選項押逼,確保容器服務(wù)異常退出后,能被重新拉起來惦界。
關(guān)于隔離挑格,首先是分區(qū)隔離,宿主機(jī)業(yè)務(wù)日志目錄/app/log獨立分區(qū)沾歪,避免日志量過大時侵占宿主機(jī)系統(tǒng)分區(qū)或者業(yè)務(wù)分區(qū)磁盤漂彤。
第二,資源隔離灾搏,flume當(dāng)時是跑進(jìn)程的挫望,我們做的第一件事情是進(jìn)行容器化,之后做配額狂窑,限制能使用的資源使用量媳板,避免大日志傳輸時侵占宿主機(jī)過多資源。
第三泉哈,故障隔離蛉幸,開啟dockerlive-restore選項破讨,保障docker服務(wù)進(jìn)程不影響容器服務(wù)。
前車之轍
我們犯過一些錯誤奕纫,不負(fù)責(zé)物理機(jī)運營的童鞋可能感受不明顯提陶。如果磁盤引導(dǎo)分區(qū)被破壞,就可能導(dǎo)致操作系統(tǒng)被重裝若锁,這個問題是很嚴(yán)重的搁骑。原因也很簡單,服務(wù)器一般有多引導(dǎo)的選項又固,比如磁盤仲器、網(wǎng)絡(luò)、CD仰冠,一般在順序上磁盤第一乏冀,網(wǎng)絡(luò)第二。
但如果磁盤引導(dǎo)分區(qū)壞了洋只,服務(wù)器會認(rèn)為沒有操作系統(tǒng)辆沦,然后就從第二個上引導(dǎo)。這時候不幸的事情是识虚,在你的網(wǎng)絡(luò)環(huán)境里如果之前剛好裝過操作系統(tǒng)肢扯,采用了第三方開源的部署服務(wù)器,而沒有把之前的文件刪掉担锤,那么它就會把那些操作重新裝上蔚晨。
解決辦法很簡單,我們提供了定時任務(wù)肛循,對兩個小時前創(chuàng)建的引導(dǎo)文件铭腕,能看見它的創(chuàng)建時間、訪問時間多糠,并進(jìn)行強(qiáng)制性刪除累舷。
第二個前車之轍,在收集Ceph日志時碰到困難夹孔,當(dāng)時是用fluent-plugin-ceph插件來做被盈。具體的情況是,第一搭伤,官方配置文檔不正確害捕,因為提交者沒按官方文檔格式編碼,導(dǎo)致看到的配置是一行闷畸,拿回來根本不知道怎么辦。第二吞滞,它和td-agent1.0 版本不兼容佑菩。摸索出的解決方法就是圖片上顯示的辦法盾沫。
** 下一代云服務(wù)架構(gòu)**
這是我們下一代云服務(wù)架構(gòu),與上一代的主要區(qū)別在于殿漠,把編排框架換成了Kubernetes赴精。目前AI這塊已經(jīng)用起來了,AI部分在線上大概有一百臺物理機(jī)绞幌,跑Job任務(wù)蕾哟,短任務(wù)每天可以跑到三萬個,一次性可以調(diào)動3000個容器莲蜘,未來會把這個些換成Kubnernetes谭确,包括我們的AI、云服務(wù)都會跑在Kubernetes上票渠。
XaaS on Kubernetes
如果把云服務(wù)跑到Kubernetes上逐哈,第一個要做的事情,可能會采用ceph塊存儲做后面的數(shù)據(jù)和數(shù)據(jù)持久化问顷。目前vivo已經(jīng)有了數(shù)據(jù)ceph塊存儲昂秃,但功能還不強(qiáng)大。第二杜窄,要解決pod漂移調(diào)度問題肠骆,如果不用ceph塊存儲,pod失效調(diào)度到其他節(jié)點上有問題塞耕,調(diào)過去沒用的蚀腿,沒有數(shù)據(jù)。 第三荷科,也是最常見的一個唯咬,固定POD IP,看到網(wǎng)上有人討論這個事情畏浆,覺得容器壞了胆胰,沒必要把容器固定起來,因為有違微服務(wù)的原則刻获。這種觀點不太對蜀涨,有一些場景,比如在vivo的企業(yè)IT架構(gòu)里面蝎毡,很多東西都跟IP掛鉤厚柳,比如安全策略,它不是跟域名掛鉤沐兵,而是PODIP掛鉤别垮,交換機(jī)、防火墻等很多的配置都跟這個相關(guān)扎谎。所以vivo要干的很重要的事情碳想,就是把POD IP固定烧董。 目前業(yè)界對這塊也有一些實踐,比如京東最近有這方面的分享胧奔,把PODIP放在一個APP的IP 小池子里面逊移,小池子里面還有IP的話,就從小池子里拿龙填,沒有的話就從大池子里去申請胳泉。
在數(shù)人云微信公眾號后臺回復(fù)“127”,即可獲取本次演講PPT《vivo云服務(wù)容器化實踐》岩遗。