《攜程:我們是如何利用容器實現快速彈性伸縮的?》要點:
本文介紹了攜程:我們是如何利用容器實現快速彈性伸縮的?,希望對您有用。如果有疑問,可以聯系我們。
吳毅挺
攜程系統研發部高級總監
2012年加入攜程,從零組建攜程云平臺團隊,目前負責攜程私有云、虛擬桌面云、網站應用持續交付等研發.
近年來隨著大眾旅游消費的火熱,攜程的業務每年呈高速增長,2016年Q4財報顯示攜程2016年全年營業收入同比增長76%,交通票務營業收入同比增長98%,酒店預訂營業收入同比增長56%,其他BU也有大幅增長,預計2018年攜程的 GMV 將突破10000億,并在2021年突破2萬億.
我們開發的私有云和持續交付平臺為攜程超過 20 個 BU/SBU 服務,為了同步支撐業務的高速發展,我們也需要不斷的技術革新,持續提升攜程運營、研發的效率,縮短產品從 idea 到交付用戶的時間.
旅游出行的特點是季節性的,在平時流量都比較低,但節假日前一天流量會突然增高很多.因此每到節假日就會面臨成「倍」增長的擴容需求.圖 1?中可以明顯的看到流量的起伏情況.
圖 1
一般情況,臨時擴容的需求較多,縮容會比較少,因為流量一上去之后,在短時間內不會下來,另外一方面,哪怕是流量下來了,由于以往資源申請沒那么靈活,一般都會占用資源不釋放,只能通過一些運維手段來監測資源使用情況然后告知業務部門去主動縮容.
攜程目前大部分還是虛擬機,我們想縮短提前擴容的時間,以目前的虛擬機擴容方式,單個虛擬機擴容(從分配資源、調度、網絡、os基礎環境、應用部署等)至少是十分鐘級別的.
如果是每次擴容上千臺的話,確實需要一定的時間,而且還得看看有無足夠的資源,比如 1 月 1 日的流量提前一周就擴容好,但這不夠靈活,業務流量下來以后需要縮容,目前的速度還是不夠快.
針對這一場景,我們需要解決的問題是,能有更快的方案嗎?如何能夠做到更快速的彈性伸縮滿足業務的需求?答案是利用容器.
圖2
再舉個例子,攜程有個深度學習的小詩機項目,將訓練好的模型,對外提供服務,用戶只要上傳照片,后臺的?AI?機器人就會根據照片中的內容自動寫詩,這對于現行都市詞窮一族來說,瞬間提升了意境,蠻有意思的.
該項目希望在春節前上線,需要緊急擴容?1000?核,以滿足春節期間大流量的需求,春節過后立馬就可以縮容?90%?的資源.
目前我們通過容器可以做到?1000?核的資源,5?分鐘內完成?150?個容器實例的擴容,而且這還是?API?同步創建的速度,我們正在優化成異步的方式,相信后續提高并發能力后,速度還可以得到大大的提升.
其實攜程的容器化已經進行一年多了,容器給我們最大的感覺是看起來簡單,但要做好很難,原理不是很復雜,但是要利用這個技術做出一個產品或服務,中間有非常多的細節需要完善,比如如何做到用戶體驗更好的?UI?可視化、如何做到灰度發布、容器監控、容器基礎鏡像版本管理等等.
攜程容器云定位有以下?4?點:
秒級意味著所有的擴容、縮容、回滾全部是秒級的,做到秒級是很難的,有很多需要突破的地方.比如,高速的鏡像下發系統;高效的調度系統,穩定的容器服務,高度自動化的網絡服務.
2、提升資源利用率
為了提高服務器資源利用率,我們采取賬單的形式,督促業務線提高資源利用率,優化代碼架構.我們對采集到的實時監控數據進行統計分析,按照?CPU、內存、存儲、網絡等多個緯度,按月計費,每個月會將賬單發給業務線的?CTO.
3、組件服務化(mysql/kv/mq/…)or PaaS?化
應用所需要依賴的很多組件能夠變成服務化,AWS 或者阿里云也做了很多這種服務.攜程內部也在嘗試把一些公共組件服務化,例如,MySQL,Redis,RabbitMQ?等.
拿?MySQL?為例,我們讓用戶可以在測試環境快速部署?MySQL?實例,并且可以選擇性的將測試數據灌入.新建的?MySQL?實例也會自動在數據訪問中間件中完成注冊,方便開發人員、測試人員快速搭建測試環境和測試數據.
4、從自動化到一定程度智能化
從自動化到一定程度智能化指的是基礎設施變得更智能,比如能夠具備一定的自我修復能力,如果是從上游到下游的一整套服務都具備智能化修復能力的話,這是一個非常大的突破,對于提升運營效率和故障恢復速度至關重要;
以上是攜程容器部署基本原則,看起來很容易,卻是我們很長時間實踐經驗的總結.
比如單容器單應用這個原則,歷史原因我們有混合部署的情況,單個vm部署多個應用,運維的復雜度會上升很多,比如:應用之間如何做到更好的資源隔離?發布如何避免相互之間的沖突?等等.
使得我們的運維工具、發布工具變得格外復雜,開發、測試的持續交付效率也受到極大影響;
容器鏡像發布也是我們做的一個比較大的突破,過去是代碼編譯成可發布的包,直接部署到 vm 內部,而現在是編譯時直接生成容器的鏡像,不同環境其實部署的是同一個鏡像.
并且不允許部署之后單獨登陸進行配置修改,通過這種方式做到?immutable infrastructure ,保證開發、測試、生產環境的一致性,同時也保障了自動化擴容、縮容快速高效的進行.
是否在容器內部也運行各種運維 agent 也是我們經過實踐確定下來的;我們希望容器盡量簡單,盡可能只包含運行的應用本身,此外將所有的 agent 合并到 host 層面,也能在很大程度上提升服務器資源利用率,agent數量下降一到兩個數量級;但配套的管理工具(eg: salt) 需要做一次升級改造才能適配新的模式;
1、OpenStack
攜程除了容器之外的東西都是用 OpenStack 來管理的,OpenStack 可以用一個模塊(nova-docker)來管理容器,攜程在 OpenStack 方面有多年的二次開發技術積累、也大規模的部署運維經驗,但最終沒有選用 OpenStack,因為 OpenStack 整體過于復雜,調度效率也比較低,API 調度是 10 秒以上,可以進行優化,但我們覺得優化代價太大,OpenStack 整體的復雜度也很高;
我們早期的胖容器(把容器當 vm 來使用,做代碼包發布)的確是用 OpenStack 來做的,原因是我們希望把注意力放在容器本身,以最低的代價將容器先用起來,積累開發、運維經驗;
而到了瘦容器階段(基于容器鏡像做發布),我們發現 OpenStack 整體的設計理念從本質上講還是為虛擬機隔離粒度的虛擬化方案設計的,而容器本身與 vm 其實差別很大,玩法也相去甚遠, 于是我們對 Mesos/K8s 進行評估;
回顧我們的容器調度探索之旅,基本上可以用以下三個階段來總結:
圖3
OpenStack 用于管理 bm/vm 是很合適的,并且在網絡方面有很成熟的支持,無論是 vlan+OVS 還是最新的SDN 都能適配,尤其各大廠商的支持力度都很大;這也是為什么我們雖然不用 OpenStack 調度容器,但容器的網絡其實還是用 neutron 來管理的;
2、K8S
K8S?有很多很先進的設計理念,比如有 replication? controller/Pod/Yaml?配置管理等,但這些理念在攜程都很難落地,因為跟現有的運維模式、發布流程有較大的沖突.
而且當前還缺乏大規模部署案例,網絡尚無比較成熟的方案, 例如 L4/L7 負載均衡; 而在攜程 L4/L7 服務已經比較成熟穩定, 并且與我們現有的發布系統Tars集成得非常好;
3、Mesos
Mesos?和 K8S?解決問題的思路是不一樣的,基于?Mesos?我們可以非常容易的開發出適合我們場景的調度框架,并且非常容易和我們現有的運維基礎服務對接集成;包括 L4/L7 負載均衡、發布系統等;
圖4
-DPDK
-https硬件加速
-單容器單IP,可路由
-vxlan offload TOR 解封裝
Neutron+OVS+VLan,這個模式非常穩定,對于網絡管理也是非常的透明的.這也是攜程的選擇,現在的網絡無論是胖容器還是容器輕量發布都用這種模式.我們也在測試?DPDK 和 https 硬件加速的效果.
我們也評估過類似 flannel 的網絡,要求每個物理機獨立網段,通過這個特性來做路由;非常不靈活的一點是容器如果遷移到另外一臺物理機就需要換IP,無法滿足我們的需求;
接下來會走 vxlan+?基于BGP EVPN協議自研輕量級 SDN?controller 的路線,vxlan?offload?TOR 解封裝提高性能;對于 OpenStack 可見的還是大二層網絡(vlan), 而實際上是通過 underlay 的三層路由進行轉發;openstack與我們的控制器能實現元數據的一致性;關于這塊,后續我們也會有相應的分享單獨進行探討;
如何配置容器網絡
圖?5
如圖?5?用dwait 和 dresponse,基于?Go 開發,dwait 會通過?unix socket?請求外部服務dresponse?做容器的初始化.當這個容器起來的時候,它的網絡沒有那么獨立,在 Docker 里面是需要依賴外部提供信息的,所以需要知道哪個網段或者說創建的?neutronport?再配置到 Docker?容器內.這樣做后就不會有網絡丟失的情況.
接下來分享一下我們碰到的一些比較經典的Docker/Mesos相關的問題
1、Docker?Issue
圖?6
在我們嘗試使用?Chronos?跑?cronjob?時,由于我們的?Job?執行頻率非常高,導致物理機上出現非常頻繁地容器創建和銷毀,容器的創建和銷毀比單個進程的創建和銷毀代價大,會產生很多次內核的調用,磁盤的分配銷毀,這對內核是一個非常大的壓力考驗.
我們在實際操作過程中就遇到了一個?bug,如圖?6?這臺機器逐步失去響應,產生了?kernel soft lockup,慢慢的導致所有進程都死鎖了,最終物理機重啟了.為了避免頻繁創建銷毀容器,我們沒有在?Chronos 這種一個?task?一個容器的路上繼續走下去,我們自己研發了?mesos framework,改成了一個Job,一個容器的調度方式.
Mesos??性能很穩定,基本上不需要修改?Mesos?代碼,只需要在我們自己寫的 Framework 進行控制調度,控制如何啟動容器.
3、CExecutor
圖7
1)自定義?CExecutor,Go?語言實現
2)task:container
-1:1 -> N:1
3)容器持久化
如圖?7,可以觀察得到前段抖動非常厲害(如果過渡頻繁地創建刪除容器,會帶來非常大的負擔,抖動會非常高),在用?1:1?調度之后就變得平緩了.所以攜程自定義 CExecutorr(Go?語言實現),避免過于頻繁創建刪除容器,帶來的副作用(抖動非常強、load非常高),之后就基本上處于水平線了.
1、Mesos?監控
圖?8
圖?9
如圖?8-9?攜程用了很多開源技術,Telegraf、influxdb、Grafana?并做了一些擴展來實現 mesos 集群的監控,采集 mesos-master 狀態、task執行數量、executor 狀態等等,以便當 mesos 集群出現問題時能第一時間知道整個集群狀態,進而進行修復.
此外, 我們還從 mesos 調度入手,做了一些應用層的監控,比如: 針對 cron job 類型的應用,讓用戶可以看到 job 應該在什么時候執行,執行的過程,整個 job 的成功率,job 還有多個實例在跑等;
2、容器監控
圖?10
攜程監控團隊全新開發了一套監控系統?hickwall,也實現了對容器的監控支持;hickwall agent 部署在容器物理機上,通過 docker client 、cgroup等采集容器的運行情況,包括?CPU?、Memory、Disk?IO 等常規監控項;
由于容器鏡像發布會非常頻繁的創建、刪除容器,因此我們把容器的監控也做成自動發現,由 hickwall agent 發現到新的容器,分析容器的label信息(比如: appid、版本等)來實現自動注冊監控;在單個容器監控的基礎上,還可以按照應用集群來聚合顯示整個集群的監控信息;
除此之外,攜程還做了各個業務訂單量的監控,比如說今天有多少出票量、酒店間夜數,而我們可以非常精準地根據歷史的信息預測未來的數據,比如說明天的這個時間點訂單量應該在多少、準確性在?95%?以上,一旦比預估的偏差太大的話,就會告警有異常,它把一個綜合的業務運行健康度提供給業務研發團隊,而不僅僅是單個容器的運行情況.
我們在線也會做一些壓測,比如說這個集群下面有 10 臺機器,這 10 臺機器的負載均衡權重都是 0.1,我們會把其中一臺調高,看它的吞吐和響應的情況.測出它到了一定極限能提供的 QPS,就可以知道這個集群還剩多少性能高容量,這個容量就是這個集群還能承載多大的壓力.
比如說有?25%?的富余,根據訂單的變化就可以知道還多多少或者還缺多少,這樣就能做到更好的擴縮容調度
目前基于 vm 的應用已經能基于容量規劃和預測實現自動擴容,后續容器的擴縮容也會接入,并且做到更實時的擴容和縮容調度;
此外,容器監控對于攜程創新工場的團隊是很有意義的,這些新孵化的BU對成本控制更嚴格,隨著容器上線,我們能為其提供性價比更高的基礎設施.
圖 11
CDOS?全稱是?CtripData Center Operating System,?我們希望通過 CDOS 來調度多個數據中心的資源,就好比一個操作系統調度各種資源給各個進程一樣,CDOS 會調度多個數據中心的計算、網絡、存儲的資源給到不同的應用,滿足各個應用所需的冗余度,并且會動態的維持這個冗余度,一旦出現異常,可以自動嘗試修復,刪除出現問題的容器實例,并部署新的實例;這里面會涉及到非常多的模塊.
如圖 11?最上層是持續交付的發布系統,這一層是跟應用交付相關的東西,開發人員、測試人員都會用的發布系統.下面是針對不同運行模式的應用定制的兩套調度管理模塊,一個是 cron Job,另一個是 long running service;兩者在管理、部署、發布方面都有一些差異化;
底層資源分配是用 Mesos 來實現,歷史原因,我們還有大量的服務部署在 windows上, 因而需要同時支持 windows server container 和 docker.長期來看未必是繼續使用?Docker,因為 Docker 太激進了,目前已經有多種 container 實現方式可以選擇.
Windows 容器方面攜程也已經做了一些 POC,實現類似前面提到的 ovs + vlan 的網絡接入,遵循單容器單 ip 等原則,并且投入覆蓋了部分的測試環境.
圖中右邊有很多服務,比如 L4/L7 負載均衡、?SOA 的服務,CMS 應用元數據管理、監控、日志收集、鏡像管理和推送等模塊;
由于我們采用容器鏡像發布,要實現秒級交付,對于鏡像推送速度有很高的要求,當 base image 沒有變化時,只需要把應用新版本 build 出來的 app 層通過我們開發的 Ceph 同步模塊推送的多個數據中心;
當 base image 也變更時,情況會更復雜,除了同步到各個數據中心的 Ceph 對象存儲,還需要預先下發到可能用到的 Docker 服務器,才能以最快的方式啟動容器.
作者:吳毅挺
文章來源微信公眾號:高效運維
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/4273.html