微博基于 Docker 的混合云架構與應用實踐
干貨還在繼續!今天是數人云容器三國演義Meetup嘉賓演講實錄第三彈。 新浪微博無疑是服務器體量巨大的典型代表 ,讓我們看看大型互聯網公司 基于Docker的最新架構與實踐——
大家好!先做一個自我介紹,我來自新浪微博,付穩,屬于微博平臺研發中心,本次分享的主題是新浪微博DCP基于Docker的混合云架構與應用實踐。今天的主題是Swarm、Mesos、Kubernetes的三國演義,但是我可能更多講的是大型互聯網公司在調度框架選型或者它依賴的中間設施,如何把它應用到上千臺服務器的一個規模,新浪微博遇到了哪些問題,并且如何來解決它們。
背景,挑戰與實現
介紹一下本次項目微博混合云的背景,大家知道微博的體量是比較大的,線上規模大概幾千臺服務器,所以每一次架構改造對我們來說都是非常大的挑戰,要考慮的因素會更多。
微博的峰值流量特點類似前一段時間的王寶強事件、奧運事件、喬任梁事件,在10分鐘之內,微博的流量會漲到兩到三倍。線上有三千臺服務器,如果十分鐘內流量來了三倍,以前是沒辦法的,申請機器、上架、初始化、服務部署,這一個流程大概需要一兩個月,所以就要求平臺研發中心具備在十分鐘之內完成一千個節點的擴張能力。考慮幾個方面:極端峰值、擴展性、成本和業務迭代。業界基本就是依靠混合云這種趨勢,包括阿里云、AWS等公有云平臺的成熟是一方面,國內的12306利用阿里云來解決它的余票查詢業務,包括Docker、Mesos等容器新技術使大規模動態調度成為可能性,京東等也在這上面有一些實踐,所以我們也提出了自己混合云的解決方案。
說一個大家能比較切身感受的例子,12306。這是12306的一個本地機房。它70%的業務來自于余票查詢,即壓力70%在余票查詢上,它把這一部分放在公有云上,內部的IDC每五分鐘之內緩存同步,同步到阿里云機房。用戶來訪問12306的時候,如果是其它業務、結算類業務就走本地IDC,如果余票查詢就走阿里云的IDC。這給我們很好的一個啟發,可以利用公有云節省成本,快速擴容,但是它的數據是分鐘級同步的、流量可預期,而新浪微博整個峰值就是十分鐘,比如王寶強發酵事件,要十分鐘之內要擴容完成,完成服務發現流量引入;大家刷一條微博也不可能要求別人五分鐘之后才能看到,所以對技術的要求很高。
混合云去年DCP的實戰,具備了十分鐘混合云擴容一千節點的技術能力,春晚兩天之內完成了1000+臺阿里云ECS,基本上就是16核16G或者16核64G高配的這種配置,當然容器數量肯定是成倍的增加。實現了無降級的平滑過渡,同時支持了微博50%的主體流量,利用Docker技術動態調度技術、基礎設施跨云,包括微博Feed流、紅包飛、手機微博不同業務方都使用。現在每天晚上也是利用這種動態調度標準體系的晚高峰擴容300+節點,熱點事件也會進行彈性擴容。
基于混合云的微博項目總結兩點,第一是基于Docker的彈性調度,第二是基礎設施的跨云。當然服務編排是不可分割的一個部分,但是如果想讓混合云體系運轉起來可能還需要基礎設施的跨云。接下來,我會對這幾個問題分別講解。
整個微博的容器技術發展體系, 2014年我們做了Docker化、容器化,2015年到現在我們做了私有云+混合云,還有動態調度。技術也是在不斷積累中的,這是目前成型的一個技術體系。大家可以看主機層,主機層其實是內部和私有云打通,外部和公有云打通,它進行主機的創建。主機的創建之后,進行成本的結算。它還要承擔一個最重要的任務就是初試化,比如Docker環境,Mesos、Swarm的環境,還有運維基礎環境的初始化。服務編排下發編排任務,編排向調度層進行下發,下發根據調度策略選擇進行資源調度。當你有資源的時候,它可以進行資源調度。如果沒有物理資源,它向主機層進行申請。主機層申請之后,這里面創建機器,其實初始化做了很重要部分就是把它創建機器成為一個可運行的Docker編排環境。在調度層去年我們主體跑的Swarm大概有兩千+節點,然后部分的業務線在Mesos上跑,今年主要在自研的容器調度平臺。DCP的編排+調度+主機體系,和Docker三駕馬車有類似,之后也會重點介紹。當集群是一、兩千節點,并發量百億級時候,服務發現、鏡像中心、監控中心包括容量評估等周邊體系建設等都是要考慮的。
新浪微博的技術棧基本上是內網私有云的裸主機,公有云上VM,CentOs全是7.0的,Docker1.6.2。為什么1.6.2?因為這是目前跑的最穩定的一個版本,近期也在考慮升級,去年調研的時候,因為我們用Swarm比較早,所以從0.1快到0.4,后來出了1.0,穩定版本一直在用。其實Docker1.6.2目前來說是最能和Swarm兼容的版本,因為Swarm是基于DockerAPI的,低版本的API是不支持的,這就要求我們Docker版本至少為Docker1.6.2。網絡模式是Host的模式,因為我們的并發量比較大,我們調整過其它網絡模式,但是網絡性能損耗是非常大的,這方面不能忍受,所以是Host的模式。DockerRegistry是自建的鏡像倉庫V1、V2。
整個混合云的DCP流程,首先是內網主機申請,內網向私有云申請,公網向云端進行申請,申請之后進行初始化,初始化有兩步,系統環境、運維環境(DNSmasq、Cron等)初始化。還有一些Docker環境, Docker Swarm、 Mesos進行安裝和啟動,安裝和啟動之后就代表一個可調度的Docker環境,然后根據你的調度策略和算法進行動態調度。之后容器鏡像啟動、服務發現全自動流程。關于服務發現是微博自己開源的平滑reload的服務發現版本nginx-upsync-module。
基礎設施
新浪微博的基礎設施很多功能現在都要用阿里云去改進或者是去定制,所以在公有云上做了很多經驗。整個DCP的思路就是內網私有云,因為微博有著這樣的特點,就是大家刷微博的時候,刷PC端一般是中午,刷手機端微博是晚上,它屬于兩個不同的業務方,當然從屬于一個大的技術平臺。當中午流量刷的時候,手機端微博的用戶其實少了,可以把機器共享出來放入我們的私有云或者放到共享池。不管是私有云還是公有云的機器,通過資源調度的方式,當機器閑置的時候,把它放入一個共享池整合來利用,提高資源的利用率。
公有云方面,我們做了一些改造是封裝阿里云的接口。大家封裝阿里云可能是一臺或者是幾臺的,但我們如果在幾分鐘之內要創建一百臺或者一千臺,肯定要對它的接口進行封裝,包括它的一些BUG也提出要求,一些VPC或者是一些控制臺的性能我們也做了封裝和改進。假如有了上面的API,就可以創建機器了。創建機器的時候,首先建議大家定制一個自己的VM,這個VM鏡像不是Docker鏡像,是操作系統的鏡像。我們的Docker基礎鏡像版本是這樣每個層級來分的,比如說CentOS,然后所有的Mesos,Java,PHP,整個鏡像大概是700M。如果一個鏡像700M,當整個一千臺集群開始拉這個鏡像的時候,它是相當大的帶寬,多機房鏡像倉庫是扛不住的。主要Docker鏡像放置操作系統VM鏡像,使只有代碼部分或者你的配置變更部分,在拉取鏡像時變更。利用的就是Docker鏡像分層機制。
回到上面,我們創建一臺VM的時候,配置所需要的環境和軟件,構建快照,這些快照基本上把所需要的鏡像先預放到操作系統里面,然后設置你的磁盤分區、機器權限及自定義的啟動腳本,進行預設。下邊一步是初始化,一般是在內網Puppet,阿里云上用的Ansible。然后用這些內網工具做初始化,我希望通過初始化把這個版本、把Swarm、Mesos這些組件進行啟動。初始化完成以后,代表你是一個可運行的調度資源調度環境。關于Ansible大家知道有很多坑,包括性能非常差。一臺Ansible配完能達到30、40臺的規模,我們把它源碼做了一些改造,包括一些初始化的穩定性和速度優化。
綜上說,我們通過了一個VM的鏡像加初始化,利用Docker鏡像體系打造了一個標準化的運行平臺,不同語言或者不同的跨云、跨業務都可以在這個Docker環境中進行動態調度。
我們的內網有自己的鏡像倉庫,版本是V1到V2,存儲是Ceph。在內網所有的業務端上傳鏡像之后會自動同步到公有云或者同步到不同的機房,這樣避免跨IDC之間的帶寬傳送太大。阿里云上為鏡像Mirror的緩存,隨時進行同步,節省了拉鏡像的時間。其實整個容器啟動是非常快的,但是遇到大鏡像存在一兩分鐘無法拉去現象。鏡像倉庫最大的瓶頸其實是帶寬,千兆網卡如果沒達到瓶頸,你會看到它很正常;如果達到瓶頸,它會達到一個峰值惡化,性能急劇下滑。同時我們做了一些優化,包括鏡像倉庫根據擴容臺數,比如擴一千臺可能按比例自動擴容鏡像倉庫,支持動態擴展。
最后簡單說一下公有云上有一個網絡,就是微博內網聯通電信兩大機房之后,通過兩根端線,比如阿里云的A區和C區進行打通、專線互聯打通,同時構建了一個V*N網絡,這個V*N網絡是走公網的,性能要求不高可以走V*N網絡,當然兩個專線之間是互備的,比如這根斷了之后,它會自動進行路由切換,走這條線路,保證網絡的高可用。
彈性調度
接下來介紹拿到一個物理主機之后怎么樣建成一個可動態調度的Docker環境,首先說一下彈性調度。其實彈性調度基本上離不開今天提的三個主題,Swarm、Mesos和K8S。我們在用的時候也做了很多調研,也糾結于選型,最后選擇了Swarm,我們又自研了一些容器編排的工具。我們的需求其實很復雜,包括跨池調度、指定歸還、單機業務的灰度、多實例的部署、故障的自動恢復、還有一些定制的調度算法、容器的監控、評估,跨IP調度等等。其實我們要實現的需求就是快速迭代,實現內網計算資源的統一管理,公有云上獲取計算資源,快速進行部署。結果發現上面任何一個調度框架拿來直接用的都是不好用的,所以我們在上面做了改造,就是對調度框架進行了一個封裝。它接受編排層的一個任務調度體系,告訴你不同的IDC、不同的服務,然后你的調度策略是怎么樣的,根據你所要的資源、你所要的數量來下發。分幾種模式,現在主要線上跑的有直接DockerDaemon的管理,以及Swarm、Mesos。Mesos將來預期管理離線存儲業務,其實就是把它整個生態體系進行封裝。我們做了自定義調度框架,還有資源的管理,特別是資源的編排和管理、容量的評估、監控報警基本上都在這一層來完成。
因為功能多,所以生產池的環境中有很多坑的問題。Swarm的架構基本上是業界很通用的CS的模式,Client節點向Master進行匯報,這里面有一個資源注冊中心,我們用的是Consul,向Consul進行注冊,Master通過Consul拿到節點信息后通過Http請求與client通信管理。之前早期的版本,Swarm性能非常差,因為它下發命令之后,任何命令會有一個全局鎖,現在已改為分步式鎖,性能比較高。整體來說,它的性能還是比較好的。單個集群節點,單個IDC,其實管最大的一千+節點是沒有問題的。現在Swarm應該有了一個高可用的版本,當時我們做了基于Consul的一個多IDC的高可用、可擴展的機制。
為什么微博當時選擇Swarm?因為它簡單,是Docker原生,滿足微博跨服務池一些編排或者一些抽象多租戶的需求。因為當時K8S只能管理容器化,微博后期還有一些離線的業務想去做,所以就沒有選K8S。Mesos,現在也是簡單管理一些非容器。
Swarm的調度策略基本上分為兩個部分,第一個部分是主機、容器的過濾加上策略的選擇。拿到一定資源之后,過濾基本上就是健康性的過濾,容器這個節點是死還是活,還有約束條件,就是DockerDeamon打標簽。給這些容器打這個標簽,它就只能這個范圍之內進行容器管理,比如不同的服務池,手機微博的服務池、PC端的服務池啊、不同業務的服務池進行隔離,隔離之后,比如只要找手機微博的服務池進行容器管理。同時還有一些親和性的管理、依賴性的管理,還有端口的管理。通過這些約束性條件之后,會根據各個節點的CPU或內存運行狀況包括它的過濾策略選出來、剔除掉資源不足的主機,然后進行打分,比如對一千個節點進行打分。打分之后,然后進行策略選擇。其實就是在同等條件下,是選擇資源使用最多的節點,還是選擇容器用得多的節點,還是容器用得少的節點,還是隨機進行選擇,其實整個Swarm調度策略就這么簡單。然后調度的粒度基本上就是內存和CPU。
其實調度代碼最核心的不像Mesos那種選舉策略或者其他,它的策略比較簡單,你可以看使用的資源,占的比例,進行打分。當所有有CPU資源和內存資源都同時滿足的時候,那就證明資源是可以用的。它的策略很簡單,就是把兩個分加起來,這就是它的調度算法。如果大家有更復雜的一些資源調度框架,我不建議用Swarm,它支持得不太好,當然對內存和CPU這種限制,是可以滿足我們需求的。還有一個坑就是它的資源創建只與容器create時的配置有關,與運行時實際使用的資源情況無關。比如第一次啟動的時候用Swarm配置了8G,但其實只使用了2G,最后的算法是永遠認為它用了8G,它在Cgroup文件里面進行了限制,與實際使用時無關,只有容器啟動的時候與它分到的資源數有關系。
動態調度那一塊,微博整合了Mesos、Swarm包括DockerDeamon直接下發,,現在服務器單機或者是按批次來上線的時候,我們會有Docker deamon下發的策略。對分布式調度框架進行封裝,包括SwarmMaster高可用、多機房的自動適配、容器資源評估、容器資源監控,這都是我們的動態調度需要做的東西。
編排與實現
簡單說一下服務編排,剛才三駕馬車底層和主機層講完之后,然后進入資源調度,上面就是服務的編排。服務之間的依賴、容器之間的依賴很多都在服務編排層去做,當然我們沒用Compose或者其它一些組件來用,因為場景更復雜無法滿足。我們在編排層自己定義進行解決,用編排層的工具進行解決。內網的共享池加上公有云組成一個共享池,大家從共享池來拿資源。當然,也會按照不同的服務池進行切分。整個流程的發起是在編排層,它會向調度層發起,調度層如果有資源就進行資源調度,如果沒有資源的進行資源申請,然后初始化,服務上線。
拿一個現實的例子來說,如何申請阿里云機器。這是阿里云的機房,三個機房,選擇哪個交換機,16核16G要一百臺,這是剛才定義的VM鏡像,就是操作系統鏡像。選擇16核16G內存,創建100臺的機器,這樣就有了100臺物理機。當然,你可以向內網私有云進行創建。如果沒有資源其實要資源申請,向共享池發起申請,申請之后會入到Buffer池,Buffer池進行初始化。這個初始化要實時生成報告來告訴你失敗,然后實時重試。一切就是自動的,有一個初始化報告。初始化完成之后,還有一個實用的經驗就是大家不要把自己的容器類型或者容器的資源類型切割的力度太散,微博基本上是定一個通用的標準,運維的復雜度一下子降低了,比如dP01、dP02、dP03、dP04,基本上按照業務來分四到五種類型就可以了。容器的類型越復雜,資源管理就越復雜。我們也很簡單,這是微博的RPC服務,這是Web服務,后面還有一個類型是緩存服務,按照不同的業務進行容器的劃分。你的業務通過調度下發給我,我就知道要的是這種容器類型,我給你編排,盡量減少用戶自定義的數量,減少用戶使用復雜度。對每個任務來說,我們會有一個整體的任務監控,然后實施成功、失敗都可以提示,包括剛才說的整個初始化、包括服務發現,都會有任務框管理。任務的耗時,也會進行監控。
這個圖是整個流程,一鍵擴容,管理員向混合云平臺發起,第一步進行資源的評估,然后根據你的配額,向公有云和內網的私有云進行拉資源。如果資源獲取到進行初始化,初始化完畢發起容器調度,通過Swarm或者通過我們自己的調度框架進行調度。調度完之后進行容器的啟動、服務的部署,服務的部署之后進行服務發現。我們在每個容器里面還有一個運維,業務上分為兩個容器,一個是業務容器,一個是運維容器,運維容器的組件就是把監控的組件進行推送,推送到日志中心,生成一些監控數據。同時要機器進行創建,你的業務監控隨時可以馬上監控到。
現在說一下比較重要的服務發現,容器啟動的流量怎么過的,就是容器編排。容器編排其實是一個大的概念,因為怎么樣跨IDC、跨機房,不同的服務池你怎么樣更快更便捷的進行服務發現。這是微博的,當然微博是有內網機房和阿里云的機房,有不同的服務,如何快速的服務發現。簡單說一點業界比較通用的就是NginxReload,當然你在大機房情況下可以驗證一下,它會有10%的性能損耗。大家可以看這個開源地址https://github.com/weibocom/nginx-upsync-module,是基于Consul的自動服務發現。因為使用容器,你的變更肯定會非常頻繁,降低它的性能損耗上,服務發現也是很重要的一個方面。還有一個特點是公有云上它會有20%的性能差,同樣內網是16核16G或者你的容器資源是16核16G,但是如果你用阿里云或者你用公有云資源的話,它會有20%的性能差,盡量讓你在服務化進行配置的時候把你的權重調低。比如公有云上整體權重為20,權重調為16,這樣才能達到你的性能和內網是一致的,和你自己的宿主機是一致的權重。
RPC服務大家也知道了,這是Motan的RPC框架,它是支持跨IDC的服務發現,也支持按權重、按機房來自動調配。
春晚要保證整個體系沒有問題,還得從整體的運維架構上包括監控體系、容量評估、干預 手段,微博都有一個完整手段進行解決。監控基本上分為四類,一個是作戰類監控,就是云上的服務器數,包括你的容器數量、專線帶寬、實時容量。實時報警類的是接口監控,超過閾值就會報警。監控類,我們會有QPS監控、平均耗時、4XX和5XX。問題節點監控有單機的slow、資源slow、分布耗時,這些基本上都是可以認為單機和單容器的一個slow,是對容器進行單機和整體的監控。整體的一個監控體系,微博是把一些業務日志進行掛載到硬盤,然后通過logtailer推到一個日志中心,日志中心進行收斂計算之后通過Graphite的展示,沒有特別針對容器監控組件,是把業務日志進行落地,推動監控中心進行監控,生成監控頁面。
很重要的幾點,大家一定要對單機容器或者是總體監控,因為在公有云的時候,它會有一些超買問題,你不確定哪個容器會發生問題的,所以你可能開一百臺有二十臺容器莫名會有問題,單機性能的惡化也會很嚴重的,大家一定要把監控做到這種力度,這樣方便問題排查。錯誤響應是多少,超過一個閾值,我們會把這個容器進行自動摘掉。容量評估系統,就是根據你單容器的平均系統指標包括你的QPS業務指標,這都可以自動進行設置進行,看你的線上,比如說你可縮容多少臺、可擴容多少臺。我剛才提到的這些縮容和擴容,如果縮容就進入共享池,擴容就從共享池里面進行容器的彈性調度,會有一個容量評估的決策。整體的干預手段基本上也有重啟、回滾、緊急上線、服務降級、封殺,包括流量切換,流量切換有跨IDC、跨服務池的,還有限流的一些數據修復,等等這些干預手段。這些干預手段其實有一些是帶容器級別的操作。
春晚實戰&總結
這些做完之后,再看一下春晚的整個實戰,基本流程是三分鐘機器創建,然后Ansible進行初始化,Registry進行拉鏡像,然后是預熱鏡像,進行容器調度,包括服務發現。整個完成之后,大概是十分鐘。
這是一個微博內部阿里云多機房的架構,可能大家可以了解一點,這是微博內網標準的一個前端機、隊列機,然后消息隊列、緩存、數據庫,然后在阿里云上同步有一個類似的架構。
微博常規部署會在阿里云上部署、緩存。在正常情況下阿里云上=只有十到二十臺機器,但是在峰值流量的情況下我們立馬擴到一千到兩千+的容器。容器進行擴容,主要是web服務器或者是RPC服務,然后我通過服務發現把流量引入。
大家可以看一下這個作戰圖,剛才我提到一個監控數量,包括服務池水位,包括服務池容量承載倍數、專項帶寬、各業務方占用帶寬、各服務池用的容器數量都會有一個實時的監控進行監控。
最后說一下微博遇到的一些問題,比如阿里云部署,在公有云上部署緩存服務器的時候,會發現它的PPS經常被打滿。阿里云的北京A區7W,C區10W+,當你的PPS打滿之后,你的緩存或者服務會急劇下降。我們通過擴容緩存來解決。還有一些莫名的機器性能差,這就依賴大流量高并發服務的時候你的單機監控,要隨時發現,自動把性能差服務平滑摘掉。還有一個剛才提到的在公有云上使用阿里云SLB負載均衡的時候,當大流量大概4、5G的時候,大流量下肯定會把SLB打垮。此外,就是專線帶寬的時候,跨機房的時候要注意這些專線帶寬。
剛才講了整個DCP擴容的一個流程,自動擴容、云平臺服務管理,DCP平臺優勢可能是高并發、大流量的場景實際場景應用,微博也會把我剛才所有講到的東西進行開源,就是DCP開源項目,12月份也會開源,到時候大家也可以一塊把它建得更好。
來自:http://mp.weixin.qq.com/s?__biz=MzA3MDg4Nzc2NQ==&mid=2652134435&idx=1&sn=485886511aa4d077e42aaa489b8c09f9&chksm=84d50c19b3a2850f5ecfc404ee72ee978715ddf60e722b5387b462f13b3d08ca765efaeb7c1e&scene=0