美團點評Docker容器管理平臺

ClaudeGalar 7年前發布 | 13K 次閱讀 Docker

美團點評容器平臺簡介

本文介紹美團點評的Docker容器集群管理平臺(以下簡稱“容器平臺”)。該平臺始于2015年,是基于美團云的基礎架構和組件而開發的Docker容器集群管理平臺。目前該平臺為美團點評的外賣、酒店、到店、貓眼等十幾個事業部提供容器計算服務,承載線上業務數百個,日均線上請求超過45億次,業務類型涵蓋Web、數據庫、緩存、消息隊列等。

為什么要開發容器管理平臺

作為國內大型的O2O互聯網公司,美團點評業務發展極為迅速,每天線上發生海量的搜索、推廣和在線交易。在容器平臺實施之前,美團點評的所有業務都是運行在美團私有云提供的虛擬機之上。隨著業務的擴張,除了對線上業務提供極高的穩定性之外,私有云還需要有很高的彈性能力,能夠在某個業務高峰時快速創建大量的虛擬機,在業務低峰期將資源回收,分配給其他的業務使用。美團點評大部分的線上業務都是面向消費者和商家的,業務類型多樣,彈性的時間、頻度也不盡相同,這些都對彈性服務提出了很高的要求。在這一點上,虛擬機已經難以滿足需求,主要體現以下兩點。

第一,虛擬機彈性能力較弱。使用虛擬機部署業務,在彈性擴容時,需要經過申請虛擬機、創建和部署虛擬機、配置業務環境、啟動業務實例這幾個步驟。前面的幾個步驟屬于私有云平臺,后面的步驟屬于業務工程師。一次擴容需要多部門配合完成,擴容時間以小時計,過程難以實現自動化。如果可以實現自動化“一鍵快速擴容”,將極大地提高業務彈性效率,釋放更多的人力,同時也消除了人工操作導致事故的隱患。

第二,IT成本高。由于虛擬機彈性能力較弱,業務部門為了應對流量高峰和突發流量,普遍采用預留大量機器和服務實例的做法。即先部署好大量的虛擬機或物理機,按照業務高峰時所需資源做預留,一般是非高峰時段資源需求的兩倍。資源預留的辦法帶來非常高的IT成本,在非高峰時段,這些機器資源處于空閑狀態,也是巨大的浪費。

由于上述原因,美團點評從2015年開始引入Docker,構建容器集群管理平臺,為業務提供高性能的彈性伸縮能力。業界很多公司的做法是采用Docker生態圈的開源組件,例如Kubernetes、Docker Swarm等。我們結合自身的業務需求,基于美團云現有架構和組件,實踐出一條自研Docker容器管理平臺之路。我們之所以選擇自研容器平臺,主要出于以下考慮。

快速滿足美團點評的多種業務需求

美團點評的業務類型非常廣泛,幾乎涵蓋了互聯網公司所有業務類型。每種業務的需求和痛點也不盡相同。例如一些無狀態業務(例如Web),對彈性擴容的延遲要求很高;數據庫,業務的master節點,需要極高的可用性,而且還有在線調整CPU,內存和磁盤等配置的需求。很多業務需要SSH登陸訪問容器以便調優或者快速定位故障原因,這需要容器管理平臺提供便捷的調試功能。為了滿足不同業務部門的多種需求,容器平臺需要大量的迭代開發工作。基于我們所熟悉的現有平臺和工具,可以做到“多快好省”地實現開發目標,滿足業務的多種需求。

從容器平臺穩定性出發,需要對平臺和Docker底層技術有更高的把控能力

容器平臺承載美團點評大量的線上業務,線上業務對SLA可用性要求非常高,一般要達到99.99%,因此容器平臺的穩定性和可靠性是最重要的指標。如果直接引入外界開源組件,我們將面臨3個難題:1. 我們需要摸熟開源組件,掌握其接口、評估其性能,至少要達到源碼級的理解;2. 構建容器平臺,需要對這些開源組件做拼接,從系統層面不斷地調優性能瓶頸,消除單點隱患等;3. 在監控、服務治理等方面要和美團點評現有的基礎設施整合。這些工作都需要極大的工作量,更重要的是,這樣搭建的平臺,在短時間內其穩定性和可用性都難以保障。

避免重復建設私有云

美團私有云承載著美團點評所有的在線業務,是國內規模最大的私有云平臺之一。經過幾年的經營,可靠性經過了公司海量業務的考驗。我們不能因為要支持容器,就將成熟穩定的私有云擱置一旁,另起爐灶再重新開發一個新的容器平臺。因此從穩定性、成本考慮,基于現有的私有云來建設容器管理平臺,對我們來說是最經濟的方案。

美團點評容器管理平臺架構設計

我們將容器管理平臺視作一種云計算模式,云計算的架構同樣適用于容器。如前所述,容器平臺的架構依托于美團私有云現有架構,其中私有云的大部分組件可以直接復用或者經過少量擴展開發。容器平臺架構如下圖所示。

美團點評容器管理平臺架構

可以看出,容器平臺整體架構自上而下分為業務層、PaaS層、IaaS控制層及宿主機資源層,這與美團云架構基本一致。

業務層:代表美團點評使用容器的業務線,他們是容器平臺的最終用戶。

PaaS層:使用容器平臺的HTTP API,完成容器的編排、部署、彈性伸縮,監控、服務治理等功能,對上面的業務層通過HTTP API或者Web的方式提供服務。

IaaS控制層:提供容器平臺的API處理、調度、網絡、用戶鑒權、鏡像倉庫等管理功能,對PaaS提供HTTP API接口。

宿主機資源層:Docker宿主機集群,由多個機房,數百個節點組成。每個節點部署HostServer、Docker、監控數據采集模塊,Volume管理模塊,OVS網絡管理模塊,Cgroup管理模塊等。

容器平臺中的絕大部分組件是基于美團私有云已有組件擴展開發的,例如API,鏡像倉庫、平臺控制器、HostServer、網絡管理模塊,下面將分別介紹。

API

API是容器平臺對外提供服務的接口,PaaS層通過API來創建、部署云主機。我們將容器和虛擬機看作兩種不同的虛擬化計算模型,可以用統一的API來管理。即虛擬機等同于set(后面將詳細介紹),磁盤等同于容器。這個思路有兩點好處:1. 業務用戶不需要改變云主機的使用邏輯,原來基于虛擬機的業務管理流程同樣適用于容器,因此可以無縫地將業務從虛擬機遷移到容器之上;2. 容器平臺API不必重新開發,可以復用美團私有云的API處理流程

創建虛擬機流程較多,一般需要經歷調度、準備磁盤、部署配置、啟動等多個階段,平臺控制器和Host-SRV之間需要很多的交互過程,帶來了一定量的延遲。容器相對簡單許多,只需要調度、部署啟動兩個階段。因此我們對容器的API做了簡化,將準備磁盤、部署配置和啟動整合成一步完成,經簡化后容器的創建和啟動延遲不到3秒鐘,基本達到了Docker的啟動性能。

Host-SRV

Host-SRV是宿主機上的容器進程管理器,負責容器鏡像拉取、容器磁盤空間管理、以及容器創建、銷毀等運行時的管理工作。

鏡像拉取:Host-SRV接到控制器下發的創建請求后,從鏡像倉庫下載鏡像、緩存,然后通過Docker Load接口加載到Docker里。

容器運行時管理:Host-SRV通過本地Unix Socker接口與Docker Daemon通信,對容器生命周期的控制,并支持容器Logs、exec等功能。

容器磁盤空間管理:同時管理容器Rootfs和Volume的磁盤空間,并向控制器上報磁盤使用量,調度器可依據使用量決定容器的調度策略。

Host-SRV和Docker Daemon通過Unix Socket通信,容器進程由Docker-Containerd托管,所以Host-SRV的升級發布不會影響本地容器的運行。

鏡像倉庫

容器平臺有兩個鏡像倉庫:

  • Docker Registry: 提供Docker Hub的Mirror功能,加速鏡像下載,便于業務團隊快速構建業務鏡像;
  • Glance: 基于Openstack組件Glance擴展開發的Docker鏡像倉庫,用以托管業務部門制作的Docker鏡像。

鏡像倉庫不僅是容器平臺的必要組件,也是私有云的必要組件。美團私有云使用Glance作為鏡像倉庫,在建設容器平臺之前,Glance只用來托管虛擬機鏡像。每個鏡像有一個UUID,使用Glance API和鏡像UUID,可以上傳、下載虛擬機鏡像。Docker鏡像實際上是由一組子鏡像組成,每個子鏡像有獨立的ID,并帶有一個Parent ID屬性,指向其父鏡像。我們稍加改造了一下Glance,對每個Glance鏡像增加Parent ID的屬性,修改了鏡像上傳和下載的邏輯。經過簡單擴展,使Glance具有托管Docker鏡像的能力。通過Glance擴展來支持Docker鏡像有以下優點:

  • 可以使用同一個鏡像倉庫來托管Docker和虛擬機的鏡像,降低運維管理成本;
  • Glance已經十分成熟穩定,使用Glance可以減少在鏡像管理上踩坑;
  • 使用Glance可以使Docker鏡像倉庫和美團私有云“無縫”對接,使用同一套鏡像API,可以同時支持虛擬機和Docker鏡像上傳、下載,支持分布式的存儲后端和多租戶隔離等特性;
  • Glance UUID和Docker Image ID是一一對應的關系,利用這個特性我們實現了Docker鏡像在倉庫中的唯一性,避免冗余存儲。

可能有人疑問,用Glance做鏡像倉庫是“重新造輪子”。事實上我們對Glance的改造只有200行左右的代碼。Glance簡單可靠,我們在很短的時間就完成了鏡像倉庫的開發上線,目前美團點評已經托管超過16,000多個業務方的Docker鏡像,平均上傳和下載鏡像的延遲都是秒級的。

高性能、高彈性的容器網絡

網絡是十分重要的,又有技術挑戰性的領域。一個好的網絡架構,需要有高網絡傳輸性能、高彈性、多租戶隔離、支持軟件定義網絡配置等多方面的能力。早期Docker提供的網絡方案比較簡單,只有None、Bridge、Container和Host這四種網絡模式,也沒有用戶開發接口。2015年Docker在1.9版本集成了Libnetwork作為其網絡的解決方案,支持用戶根據自身需求,開發相應的網絡驅動,實現網絡功能自定義的功能,極大地增強了Docker的網絡擴展能力。

從容器集群系統來看,只有單宿主機的網絡接入是遠遠不夠的,網絡還需要提供跨宿主機、機架和機房的能力。從這個需求來看,Docker和虛擬機來說是共通的,沒有明顯的差異,從理論上也可以用同一套網絡架構來滿足Docker和虛擬機的網絡需求。基于這種理念,容器平臺在網絡方面復用了美團云網絡基礎架構和組件。

美團點評容器平臺網絡架構

數據平面:我們采用萬兆網卡,結合OVS-DPDK方案,并進一步優化單流的轉發性能,將幾個CPU核綁定給OVS-DPDK轉發使用,只需要少量的計算資源即可提供萬兆的數據轉發能力。OVS-DPDK和容器所使用的CPU完全隔離,因此也不影響用戶的計算資源。

控制平面:我們使用OVS方案。該方案是在每個宿主機上部署一個自研的軟件Controller,動態接收網絡服務下發的網絡規則,并將規則進一步下發至OVS流表,決定是否對某網絡流放行。

MosBridge

在MosBridge之前,我們配置容器網絡使用的是None模式。所謂None模式也就是自定義網絡的模式,配置網絡需要如下幾步:

  1. 在創建容器時指定—net=None,容器創建啟動后沒有網絡;
  2. 容器啟動后,創建eth-pair;
  3. 將eth-pair一端連接到OVS Bridge上;
  4. 使用nsenter這種Namespace工具將eth-pair另一端放到容器的網絡Namespace中,然后改名、配置IP地址和路由。

然而,在實踐中,我們發現None模式存在一些不足:

  • 容器剛啟動時是無網絡的,一些業務在啟動前會檢查網絡,導致業務啟動失敗;
  • 網絡配置與Docker脫離,容器重啟后網絡配置丟失;
  • 網絡配置由Host-SRV控制,每個網卡的配置流程都是在Host-SRV中實現的。以后網絡功能的升級和擴展,例如對容器添加網卡,或者支持VPC,會使Host-SRV越來越難以維護。

為了解決這些問題,我們將眼光投向Docker Libnetwork。Libnetwork為用戶提供了可以開發Docker網絡的能力,允許用戶基于Libnetwork實現網絡驅動來自定義其網絡配置的行為。就是說,用戶可以編寫驅動,讓Docker按照指定的參數為容器配置IP、網關和路由。基于Libnetwork,我們開發了MosBridge – 適配美團云網絡架構的Docker網絡驅動。在創建容器時,需要指定容器創建參數—net=mosbridge,并將IP地址、網關、OVS Bridge等參數傳給Docker,由MosBridge完成網絡的配置過程。有了MosBridge,容器創建啟動后便有了網絡可以使用。容器的網絡配置也持久化在MosBridge中,容器重啟后網絡配置也不會丟失。更重要的是,MosBridge使Host-SRV和Docker充分解耦,以后網絡功能的升級也會更加方便。

解決Docker存儲隔離性的問題

業界許多公司使用Docker都會面臨存儲隔離性的問題。就是說Docker提供的數據存儲的方案是Volume,通過mount bind的方式將本地磁盤的某個目錄掛載到容器中,作為容器的“數據盤”使用。這種本地磁盤Volume的方式無法做到容量限制,任何一個容器都可以不加限制地向Volume寫數據,直到占滿整個磁盤空間。

LVM-Volume方案

針對這一問題,我們開發了LVM Volume方案。該方案是在宿主機上創建一個LVM VG作為Volume的存儲后端。創建容器時,從VG中創建一個LV當作一塊磁盤,掛載到容器里,這樣Volume的容量便由LVM加以強限制。得益于LVM機強大的管理能力,我們可以做到對Volume更精細、更高效的管理。例如,我們可以很方便地調用LVM命令查看Volume使用量,通過打標簽的方式實現Volume偽刪除和回收站功能,還可以使用LVM命令對Volume做在線擴容。值得一提地是,LVM是基于Linux內核Devicemapper開發的,而Devicemapper在Linux內核的歷史悠久,早在內核2.6版本時就已合入,其可靠性和IO性能完全可以信賴。

適配多種監控服務的容器狀態采集模塊

容器監控是容器管理平臺極其重要的一環,監控不僅僅要實時得到容器的運行狀態,還需要獲取容器所占用的資源動態變化。在設計實現容器監控之前,美團點評內部已經有了許多監控服務,例如Zabbix、Falcon和CAT。因此我們不需要重新設計實現一套完整的監控服務,更多地是考慮如何高效地采集容器運行信息,根據運行環境的配置上報到相應的監控服務上。簡單來說,我們只需要考慮實現一個高效的Agent,在宿主機上可以采集容器的各種監控數據。這里需要考慮兩點:

  1. 監控指標多,數據量大,數據采集模塊必須高效率;
  2. 監控的低開銷,同一個宿主機可以跑幾十個,甚至上百個容器,大量的數據采集、整理和上報過程必須低開銷。

    監控數據采集方案

針對業務和運維的監控需求,我們基于Libcontainer開發了 Mos-Docker-Agent 監控模塊。該模塊從宿主機proc、CGroup等接口采集容器數據,經過加工換算,再通過不同的監控系統driver上報數據。該模塊使用GO語言編寫,既可以高效率,又可以直接使用Libcontainer。而且監控的數據采集和上報過程不經過Docker Daemon,因此不會加重Daemon的負擔。

在監控配置這塊,由于監控上報模塊是插件式的,可以高度自定義上報的監控服務類型,監控項配置,因此可以很靈活地適應不同的監控場景的需求。

支持微服務架構的設計

近幾年,微服務架構在互聯網技術領域興起。微服務利用輕量級組件,將一個大型的服務拆解為多個可以獨立封裝、獨立部署的微服務實例,大型服務內在的復雜邏輯由服務之間的交互來實現。

美團點評的很多在線業務是微服務架構的。例如美團點評的服務治理框架,會為每一個在線服務配置一個服務監控Agent,該Agent負責收集上報在線服務的狀態信息。類似的微服務還有許多。對于這種微服務架構,使用Docker可以有以下兩種封裝模式。

  1. 將所有微服務進程封裝到一個容器中。但這樣使服務的更新、部署很不靈活,任何一個微服務的更新都要重新構建容器鏡像,這相當于將Docker容器當作虛擬機使用,沒有發揮出Docker的優勢。
  2. 將每個微服務封裝到單獨的容器中。Docker具有輕量、環境隔離的優點,很適合用來封裝微服務。不過這樣可能產生額外的性能問題。一個是大型服務的容器化會產生數倍的計算實例,這對分布式系統的調度和部署帶來很大的壓力;另一個是性能惡化問題,例如有兩個關系緊密的服務,相互通信流量很大,但被部署到不同的機房,會產生相當大的網絡開銷。

對于支持微服務的問題,Kubernetes的解決方案是Pod。每個Pod由多個容器組成,是服務部署、編排、管理的最小單位,也是調度的最小單位。Pod內的容器相互共享資源,包括網絡、Volume、IPC等。因此同一個Pod內的多個容器相互之間可以高效率地通信。

我們借鑒了Pod的思想,在容器平臺上開發了面向微服務的容器組,我們內部稱之為 set 。一個set邏輯示意如下圖所示。

Set邏輯示意圖

set是容器平臺的調度、彈性擴容/縮容的基本單位。每個set由一個BusyBox容器和若干個業務容器組成, BusyBox容器不負責具體業務,只負責管理set的網絡、Volume和IPC配置。

set的配置json

set內的所有容器共享網絡,Volume和IPC。set配置使用一個JSON描述(如圖6所示),每一個set實例包含一個Container List,Container的字段描述了該容器運行時的配置,重要的字段有:

  • Index ,容器編號,代表容器的啟動順序;
  • Image ,Docker鏡像在Glance上的name或者ID;
  • Options ,描述了容器啟動時的參數配置。其中CPU和MEM都是百分比,表示這個容器相對于整個set在CPU和內存的分配情況(例如,對于一個4核的set而言,容器CPU:80,表示該容器將最多使用3.2個物理核)。

通過set,我們將美團點評的所有容器業務都做了標準化,即所有的線上業務都是用set描述,容器平臺內只有set,調度、部署、啟停的單位都是set。

對于set的實現上我們還做了一些特殊處理:

  • Busybox具有Privileged權限,可以自定義一些sysctl內核參數,提升容器性能。
  • 為了穩定性考慮,用戶不允許SSH登陸Busybox,只允許登陸其他業務容器。
  • 為了簡化Volume管理,每一個set只有一個Volume,并掛載到Busybox下,每個容器相互共享這個Volume。

很多時候一個set內的容器來自不同的團隊,鏡像更新頻度不一,我們在set基礎上設計了一個灰度更新的功能。該功能允許業務只更新set中的部分容器鏡像,通過一個灰度更新的API,即可將線上的set升級。灰度更新最大的好處是可以在線更新部分容器,并保持線上服務不間斷。

Docker穩定性和特性的解決方案:MosDocker

眾所周知,Docker社區非常火熱,版本更新十分頻繁,大概2~4個月左右會有一個大版本更新,而且每次版本更新都會伴隨大量的代碼重構。Docker沒有一個長期維護的LTS版本,每次更新不可避免地會引入新的Bug。由于時效原因,一般情況下,某個Bug的修復要等到下一個版本。例如1.11引入的Bug,一般要到1.12版才能解決,而如果使用了1.12版,又會引入新的Bug,還要等1.13版。如此一來,Docker的穩定性很難滿足生產場景的要求。因此十分有必要維護一個相對穩定的版本,如果發現Bug,可以在此版本基礎上,通過自研修復,或者采用社區的BugFix來修復。

除了穩定性的需求之外,我們還需要開發一些功能來滿足美團點評的需求。美團點評業務的一些需求來自于我們自己的生產環境,而不屬于業界通用的需求。對于這類需求,開源社區通常不會考慮。業界許多公司都存在類似的情況,作為公司基礎服務團隊就必須通過技術開發來滿足這種需求。

基于以上考慮,我們從Docker 1.11版本開始,自研維護一個分支,我們稱之為MosDocker。之所以選擇從版本1.11開始,是因為從該版本開始,Docker做了幾項重大改進:

Docker Daemon重構為Daemon、Containerd和runC這3個Binary,并解決Daemon的單點失效問題;

  • 支持OCI標準,容器由統一的rootfs和spec來定義;
  • 引入了Libnetwork框架,允許用戶通過開發接口自定義容器網絡;
  • 重構了Docker鏡像存儲后端,鏡像ID由原來的隨即字符串轉變為基于鏡像內容的Hash,使Docker鏡像安全性更高。

到目前為止,MosDocker自研的特性主要有:

  1. MosBridge,支持美團云網絡架構的網絡驅動, 基于此特性實現容器多IP,VPC等網絡功能;
  2. Cgroup持久化,擴展Docker Update接口,可以使更多的CGroup配置持久化在容器中,保證容器重啟后CGroup配置不丟失。
  3. 支持子鏡像的Docker Save,可以大幅度提高Docker鏡像的上傳、下載速度。

總之,維護MosDocker使我們可以將Docker穩定性逐漸控制在自己手里,并且可以按照公司業務的需求做定制開發。

在實際業務中的推廣應用

在容器平臺運行的一年多時間里,已經接入了美團點評多個大型業務部門的業務,業務類型也是多種多樣。通過引入Docker技術,為業務部門帶來諸多好處,典型的好處包括以下兩點。

  • 快速部署,快速應對業務突發流量。由于使用Docker,業務的機器申請、部署、業務發布一步完成,業務擴容從原來的小時級縮減為秒級,極大地提高了業務的彈性能力。
  • 節省IT硬件和運維成本。Docker在計算上效率更高,加之高彈性使得業務部門不必預留大量的資源,節省大量的硬件投資。以某業務為例,之前為了應對流量波動和突發流量,預留了32臺8核8G的虛擬機。使用容器彈性方案,即3臺容器+彈性擴容的方案取代固定32臺虛擬機,平均單機QPS提升85%, 平均資源占用率降低44-56%(如圖7,8所示)。
  • Docker在線擴容能力,保障服務不中斷。一些有狀態的業務,例如數據庫和緩存,運行時調整CPU、內存和磁盤是常見的需求。之前部署在虛擬機中,調整配置需要重啟虛擬機,業務的可用性不可避免地被中斷了,成為業務的痛點。Docker對CPU、內存等資源管理是通過Linux的CGroup實現的,調整配置只需要修改容器的CGroup參數,不必重啟容器。

某業務虛擬機和容器平均單機QPS

某業務虛擬機和容器資源使用量

結束語

本文介紹了美團點評Docker的實踐情況。經過一年的推廣實踐,從部門內部自己使用,到覆蓋公司大部分業務部門和產品線;從單一業務類型到公司線上幾十種業務類型,證明了Docker這種容器虛擬化技術在提高運維效率,精簡發布流程,降低IT成本等方面的價值。

目前Docker平臺還在美團點評深入推廣中。在這個過程中,我們發現Docker(或容器技術)本身存在許多問題和不足,例如,Docker存在IO隔離性不強的問題,無法對Buffered IO做限制;偶爾Docker Daemon會卡死,無反應的問題;容器內存OOM導致容器被刪除,開啟OOM_kill_disabled后可能導致宿主機內核崩潰等問題。因此Docker技術,在我們看來和虛擬機應該是互補的關系,不能指望在所有場景中Docker都可以替代虛擬機,因此只有將Docker和虛擬機并重,才能滿足用戶的各種場景對云計算的需求。

 

來自:http://tech.meituan.com/mt-docker-practice.html

 

 本文由用戶 ClaudeGalar 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!