歷時3年,美圖全面容器化踩過的坑
本文圍繞美圖業(yè)務(wù)和大家分享美圖容器基礎(chǔ)平臺建設(shè)中的探索經(jīng)驗以及在業(yè)務(wù)落地過程中的具體問題和相應(yīng)的方案。
美圖從 2016 年開始了容器相關(guān)的探索到 2018 年業(yè)務(wù)基本實現(xiàn)容器化,今天主要會圍繞美圖的業(yè)務(wù)情況,聊一聊在容器基礎(chǔ)平臺建設(shè)探索過程中遇見的一些問題,以及具體如何落地的方案,希望可以給大家一些參考。
美圖公司成立于 2008 年 10 月,懷揣著“成為全球懂美的科技公司”的愿景,創(chuàng)造了一系列軟硬件產(chǎn)品,如美圖秀秀、美顏相機(jī)、短視頻社區(qū)美拍以及美圖拍照手機(jī)。
美圖產(chǎn)品的多樣化也催生了復(fù)雜多樣的服務(wù)端技術(shù),億級 MAU 對服務(wù)端的技術(shù)要求也越加嚴(yán)苛。
2016 年我們開始調(diào)研容器化相關(guān)技術(shù),2017 年我們開始擁抱 Kubernetes,2018 年容器平臺基本落成并推進(jìn)業(yè)務(wù)的整體容器化。
我們期望通過容器化可以提升公司研發(fā)人員的線上支撐能力,提升持續(xù)開發(fā)和集成的能力,提升整體資源利用率和服務(wù)的可用性。
美圖容器化建設(shè)實踐
容器化之前
在業(yè)務(wù)容器化之前,我們業(yè)務(wù)是以物理機(jī)的方式部署到北京、寧波等多個 IDC,部分服務(wù)部署到公有云。
其中大部分業(yè)務(wù)是單 IDC 部署,部分業(yè)務(wù)存在跨 IDC 間的調(diào)用,然后 IDC 之間通過專線打通。
當(dāng)時存在的幾個重要的問題:
- 服務(wù)部署沒有進(jìn)行隔離,業(yè)務(wù)混部需要控制得非常小心,資源的利用率非常低。
- 業(yè)務(wù)類型較多,缺乏完全統(tǒng)一和完善的自動化運(yùn)維手段,業(yè)務(wù)的增長會伴隨著維護(hù)人力的增加。
- 測試環(huán)境與生產(chǎn)環(huán)境存在較大差異,這也導(dǎo)致一些生產(chǎn)環(huán)境問題不能在測試期間發(fā)現(xiàn)。
- 開發(fā)人員線上意識較薄弱,線上故障率持續(xù)較高。
- 面對機(jī)房級故障時業(yè)務(wù)遷移非常困難,出問題時只能尷尬地等機(jī)房恢復(fù)。
對此,我們希望通過積極的調(diào)整來解決掉存在的種種問題,而容器化是一個非常好的機(jī)會,可行性也比較高。
同時我們希望借著這個機(jī)會對我們的技術(shù)架構(gòu)以及相關(guān)人員做一次從意識到技能的全面提升,為未來的技術(shù)演進(jìn)鋪平部分道路。
選擇 Kubernetes
2017 年容器編排的“戰(zhàn)爭”打完,Kubernetes 取得領(lǐng)先并趨于成熟。我們也徹底投入到 Kubernetes 當(dāng)中,容器系統(tǒng)的大規(guī)模落地離不開成熟的容器編排系統(tǒng)。
Kubernetes 對容器的編排、資源的調(diào)度以及強(qiáng)大的擴(kuò)展能力極大地方便了我們平臺的構(gòu)建。
單體容器如集裝箱,它統(tǒng)一的標(biāo)準(zhǔn)方便了調(diào)度運(yùn)輸。Kubernetes 提供了對集裝進(jìn)行集中調(diào)度的碼頭和輪渡,讓一切井然有序并且易于實施。
容器基礎(chǔ)平臺則好比基于容器和 Kubernetes 之上的完整的運(yùn)輸系統(tǒng),它需要集裝箱,碼頭輪渡,高速公路等整套體系,實際服務(wù)容器化的過程不是一個簡單的打包裝箱和調(diào)度規(guī)劃過程。
大部分的服務(wù)與外界是有割不開聯(lián)系的,需要保持與外界的聯(lián)通,服務(wù)進(jìn)駐容器更像是用戶住進(jìn)集裝箱房子,她需要相應(yīng)的基礎(chǔ)配套設(shè)施,像水,電,燃?xì)獾鹊取?/p>
所以我們首先是提供各種基礎(chǔ)設(shè)施,讓服務(wù)能進(jìn)駐容器而不會水土不服。比如需要做好資源隔離,打通底層網(wǎng)絡(luò),做好負(fù)載均衡,處理好應(yīng)用日志等等。
容器平臺建設(shè)
首先我們對多地機(jī)房及云端資源進(jìn)行梳理,成為我們計算及存儲的資源池。
同時我們構(gòu)建起基礎(chǔ)的容器網(wǎng)絡(luò),日志系統(tǒng),存儲服務(wù)等底層基礎(chǔ),然后依托 Kubernetes 完成了基于多租戶的容器管理平臺建設(shè),提供完善的項目管理,服務(wù)編排,資源調(diào)度,負(fù)載均衡等能力。
我們提供同集群多租戶的模式,所以對集群內(nèi)的業(yè)務(wù)隔離,資源調(diào)度,彈性伸縮等都會有很高的要求。
同時我們也存在多集群混合云的應(yīng)用場景,因此存在著對跨集群跨機(jī)房的容器網(wǎng)絡(luò)互通,多集群的負(fù)載均衡等的特定需求。
①基礎(chǔ)建設(shè)之網(wǎng)絡(luò)
先來看基礎(chǔ)建設(shè)中網(wǎng)絡(luò)這一層。網(wǎng)絡(luò)屬于底層建設(shè),解決的問題非常關(guān)鍵。
容器網(wǎng)絡(luò)解決的問題主要包括:
- Pod 內(nèi)部容器間的通信
- Pod 與 Pod 的通信
- Pod 與 Service 的通信
- Service 與集群外部的通信
- 跨集群跨網(wǎng)段通信
容器網(wǎng)絡(luò)除了要解決上述的 5 個問題的同時也需要考慮如何將網(wǎng)絡(luò)層的性能損失最小化。接下來先來看看在網(wǎng)絡(luò)方案選擇上我們的一些考慮。
Kubernetes 通過 CNI 提供了非常強(qiáng)的擴(kuò)展能力,同時社區(qū)的活躍也讓網(wǎng)絡(luò)插件有了更多選擇的空間。
CNI 是 CNCF 旗下的一個項目,作為容器網(wǎng)絡(luò)標(biāo)準(zhǔn),由一組用于配置網(wǎng)絡(luò)接口的規(guī)范和庫組成,同時還包含了一些插件。
CNI 僅關(guān)心容器創(chuàng)建時的網(wǎng)絡(luò)分配和當(dāng)容器被刪除時釋放網(wǎng)絡(luò)資源。CNI 具有廣泛的支持,而且規(guī)范易于實現(xiàn),社區(qū)支持非常豐富,網(wǎng)絡(luò)可選方案也比較多。
網(wǎng)絡(luò)方案的選型方面,我們會比較看重性能、穩(wěn)定性、可維護(hù)性相關(guān)。在對 Flannel、Opencontrail、Contiv、Weave、Calico、Romana 等開源方案進(jìn)行詳細(xì)的對比和分析之后,最終選擇了 Calico 方案。
經(jīng)過我們實際的壓測驗證,Calico 的性能比較接近 Host 的性能。從社區(qū)活躍度、方案成熟程度和穩(wěn)定性方面考慮 Calico 也是較為良好,同時其基于 BGP 的方案也為我們后繼的網(wǎng)絡(luò)擴(kuò)展提供了可能性。
那么在 Calico 方案里面,Kubernetes 創(chuàng)建 Pod 時的過程是怎樣的呢?Kubernetes 在創(chuàng)建 Pod 時,會先創(chuàng)建 Sandbox 的虛擬網(wǎng)絡(luò),然后 Pod 中的容器直接繼承 Sandbox 網(wǎng)絡(luò)。
在創(chuàng)建網(wǎng)絡(luò)時,Kubelet 服務(wù)會通過標(biāo)準(zhǔn)的 CNI 接口調(diào)用 Calico CNI 插件,為容器創(chuàng)建一個 veth-pair 類型的網(wǎng)卡,并寫入路由表信息。
節(jié)點上的路由表通過 Calico Bird 組件以 BGP 的形式廣播到其他鄰居上,其他節(jié)點在收到路由條目后再進(jìn)一步聚合路由寫入到自身節(jié)點上。
Calico 在同子網(wǎng)內(nèi)直接使用 BGP、跨子網(wǎng)時使用 IPIP。 而 IPIP 因為其單隊列的設(shè)計存在著性能瓶頸,這嚴(yán)重限制了節(jié)點的吞吐能力,特別是作為 LB 時影響更為嚴(yán)重,所以我們需要規(guī)避 IPIP 的問題。
另外因為我們多機(jī)房建設(shè)需要打通不同機(jī)房、不同集群、不同網(wǎng)段的網(wǎng)絡(luò),所以我們需要進(jìn)一步推進(jìn)網(wǎng)絡(luò)的優(yōu)化。
圖一
進(jìn)一步的網(wǎng)絡(luò)建設(shè)主要是三方面內(nèi)容:
- 多集群的容器網(wǎng)絡(luò)與物理網(wǎng)絡(luò)打通
- 去掉 IPIP,關(guān)閉 NAT 優(yōu)化性能
- 增加限速,對節(jié)點網(wǎng)絡(luò)進(jìn)行保護(hù)
圖一中是簡化后的一個網(wǎng)絡(luò)拓?fù)鋱D,集群的 Calico-RR(反射器) 與物理網(wǎng)關(guān)通過 BGP 進(jìn)行打通,實現(xiàn)機(jī)房物理網(wǎng)絡(luò)與容器網(wǎng)絡(luò)拉平,解決了多集群網(wǎng)絡(luò)互通的問題,同時因為網(wǎng)絡(luò)已拉到同一平面,也直接規(guī)避 IPIP 的性能問題。
從上圖可以看出,每個機(jī)房作為一個 AS 部署一個 Kubernetes 集群,機(jī)房內(nèi)部冗余有多個 RR(反射器),RR 分別與機(jī)房內(nèi)的網(wǎng)關(guān)建立 iBGP 連接,機(jī)房間的路由器通過 OSPF 同步彼此之間的路由。
除了私有云我們也需要解決混合云的場景,實現(xiàn)集群網(wǎng)絡(luò)跨云打通。受限于協(xié)議的支持,我們并沒有采用與私有云一樣的打通方式。
因為云端網(wǎng)段相對固定,在規(guī)劃完成后變動較少,因此我們采用靜態(tài)路由的方式,機(jī)房網(wǎng)關(guān)上配置相應(yīng)網(wǎng)段的靜態(tài)路由規(guī)則,同時在云端路由上也配置上相應(yīng)路由規(guī)則,最終打通路由路徑。
我們在實施的過程中遇到了不少細(xì)節(jié)上的問題,比如舊集群單個集群跨了三機(jī)房,在打通網(wǎng)絡(luò)時存在環(huán)路的情況需要通過靜態(tài)路由來規(guī)避問題。
在做網(wǎng)絡(luò)限速時,插件存在 Bug 并且社區(qū)沒有解決(目前新版本已解決了)需要手動修復(fù)。不過問題一一解決后,網(wǎng)絡(luò)基礎(chǔ)也完成了生產(chǎn)落地和打通。
②基礎(chǔ)建設(shè)之 LB
Kubernetes 在設(shè)計上其實是充分考慮了負(fù)載均衡和服務(wù)發(fā)現(xiàn)的,它提供了 Service 資源,并通過 kube-proxy 配合 Cloud Provider 來適應(yīng)不同的應(yīng)用場景。
此外還有一些其他負(fù)載均衡機(jī)制,包括 Service,Ingress Controller,Service Load Balancer,Custom Load Balancer。
不過 Kuernetes 的設(shè)計有它實際適用的場景和局限性,并不能完全滿足我們復(fù)雜場景落地,同時也考慮到社區(qū)方案成熟度問題,最終我們使用了自定義開發(fā)的 Custom Load Balancer。
七層負(fù)載的選型上,我們是使用了較為成熟的 Nginx Custom Controller 的方案。
我們也對 Envoy 等方案進(jìn)行了仔細(xì)對比,但是考慮到我們公司對于 Nginx 有非常成熟的運(yùn)維經(jīng)驗,以及我們很多業(yè)務(wù)依賴于 Nginx 的一些第三方擴(kuò)展的功能。
所以從推動業(yè)務(wù)容器快速落地角度、維護(hù)穩(wěn)定性角度,我們最終選擇了Nginx 作為早期的落地方案。
不過在與 Kubernetes 結(jié)合方面,Nginx 還是存在著不少的細(xì)節(jié)問題,我們也一直在推動解決,同時我們也在考慮 Envoy 等后續(xù)的優(yōu)化方案。
Custom Load Balancer 由 Nginx、 Kubenernet Controller 以及管理組件組成。
Kubenernet Controller 負(fù)責(zé)監(jiān)聽 Kubernetes 資源,并根據(jù)資源情況動態(tài)更新 Nginx 配置。
Nginx Upstream 直接配置對應(yīng)的 Service Endpoints,并增加相應(yīng)的存活檢測機(jī)制。
因為在網(wǎng)絡(luò)層面上物理網(wǎng)與容器網(wǎng)絡(luò)已拉平,所以 Nginx 與各集群的 Service 的 Endpoint 是完全鏈路可達(dá)的,因此也可直接支撐多集群的負(fù)載均衡。
LB 提供了友好的 UI 界面,提高了發(fā)布的效率、減少人為故障。 同時,LB 也具備灰度升級,流量控制,故障降級等相關(guān)基礎(chǔ)功能,并且提供了豐富的指標(biāo),讓運(yùn)維監(jiān)控可視化。
③基礎(chǔ)建設(shè)之日志
我們再來看一下另外一個比較重要的基礎(chǔ)設(shè)施——日志。日志其實是較為關(guān)鍵的基礎(chǔ)設(shè)施,它是審計,排障,監(jiān)控報警等所必需的。
日志標(biāo)準(zhǔn)化一直是比較難推進(jìn)的一件事情,特別是存在大量舊系統(tǒng)的情況下。
一方面面臨業(yè)務(wù)代碼的改造,另一方面面臨著開發(fā)及運(yùn)維習(xí)慣的改造。 而容器化恰好是推進(jìn)日志標(biāo)準(zhǔn)化很好的一個機(jī)會。
圖二
日志架構(gòu)上我們選用的是 Cluster-Level 的方式,使用 Fluentd 作為節(jié)點采集 Agent。
Docker 日志驅(qū)動使用 Json log-driver,業(yè)務(wù)容器日志輸出到標(biāo)準(zhǔn)輸出,最終落盤到容器所屬的目錄中。
Fluentd 采集 Docker 輸出日志,并寫入 Kafka 隊列。Logstash 負(fù)責(zé)消費(fèi)隊列數(shù)據(jù)并入 Elasticsearch,同時由 Kibana 提供統(tǒng)一的日志查詢界面。
在業(yè)務(wù)容器化落地的過程中,日志也暴露了很多的問題。如:兼容問題,標(biāo)準(zhǔn)輸出的日志可能經(jīng)過多層封裝導(dǎo)致日志被截斷或者添加了額外內(nèi)容,如 PHP-FPM ,Nginx 等。
又比如日志格式不統(tǒng)一,不同類型業(yè)務(wù)日志格式各不相同,比較難完全統(tǒng)一。再比如業(yè)務(wù)日志可靠性要求,有些允許極端情況下丟失,有些不允許丟失。
為了讓業(yè)務(wù)能更快速將舊業(yè)務(wù)遷移至容器平臺,我們?yōu)槊糠N特性的業(yè)務(wù)類型做了定制化方案,輔助業(yè)務(wù)快速接入。
比如對 PHP,業(yè)務(wù)將日志輸出至 pipe 再由 tail 容器讀取 pipe 數(shù)據(jù)輸至標(biāo)準(zhǔn)輸出。
再如大數(shù)據(jù)業(yè)務(wù),因為統(tǒng)計日志與事件日志是分割開的,一起輸?shù)綐?biāo)準(zhǔn)輸出會需要較大改造量,改造時間較長,所以對采集方式進(jìn)行適配調(diào)整,業(yè)務(wù)直接輸出日志到 rootfs,并由宿主機(jī) agent 直接采集 rootfs 約定目錄的日志數(shù)據(jù)。
總之日志因為與其他系統(tǒng)以及人員習(xí)慣耦合度太高,所以要完成標(biāo)準(zhǔn)化,完成系統(tǒng)解耦和人員依賴改變是比較消耗時間精力的一件事情。
④基礎(chǔ)建設(shè)之彈性調(diào)度
再來看關(guān)于調(diào)度的一些建設(shè)。容器調(diào)度,其實是為了解決資源利用率的問題,本質(zhì)上是一個整數(shù)規(guī)劃問題。
Kubernetes 的調(diào)度策略源自 Borg, 但是為了更好的適應(yīng)新一代的容器應(yīng)用,以及各種規(guī)模的部署,Kubernetes 的調(diào)度策略相應(yīng)做的更加靈活,也更加容易理解和使用。
Kubernetes 對 Pod 的調(diào)度通過兩個階段來實現(xiàn)。Predicates 階段用于過濾出符合基本要求的節(jié)點,Priorities 階段用于得到更優(yōu)節(jié)點。
不過由于調(diào)度是根據(jù)分配量來進(jìn)行而不是實際使用率,所以業(yè)務(wù)需要準(zhǔn)確評估出自己的資源使用量,如果評估不準(zhǔn)有可能會造成資源的浪費(fèi)或者影響業(yè)務(wù)質(zhì)量。
圖三
比如我們看圖三的實例,左邊為空閑服務(wù)器,中間每個 Pod 都申請了內(nèi)存的 Request 及 Limit,調(diào)度器根據(jù) Request 計算,服務(wù)器能放得下這幾個 Pod,于是調(diào)度到了服務(wù)器上面。
可以看到實際 Limit 是機(jī)器可用資源的兩倍。那么假如這時 Pod1 內(nèi)存使用超過了 Request,但是遠(yuǎn)沒有達(dá)到 Limit,這時服務(wù)器有可能會出現(xiàn) Swap。
而更進(jìn)一步,機(jī)器資源不足后,有可能會出現(xiàn) OOM,內(nèi)存最多且 Request/Limit 比值最小的那個 Pod 中的進(jìn)程將會被 OOM Kill。
而這種 Kill 將會造成業(yè)務(wù)的抖動。同時如果出現(xiàn)大量 Swap 也會使硬盤出現(xiàn) IO 瓶頸,影響同機(jī)器上的其他業(yè)務(wù)。
在這樣的場景下,當(dāng)前 Kubernetes 的調(diào)度器實現(xiàn)會面臨一些問題,因為它是根據(jù)配額來調(diào)度的,而業(yè)務(wù)用戶不合理的配額需求導(dǎo)致了很多預(yù)期之外的場景,所以它無法簡單解決。
針對這種場景,我們總結(jié)出了以下幾個優(yōu)化點:
- 優(yōu)化業(yè)務(wù) Request 值,根據(jù)業(yè)務(wù)歷史數(shù)據(jù)調(diào)節(jié) Request。
- 增加運(yùn)行時指標(biāo),將節(jié)點當(dāng)前利用率考慮進(jìn)去。
- 對于特殊質(zhì)量保障的業(yè)務(wù)設(shè)置 Guaranteed 級別。
- 規(guī)避 Pod 內(nèi)存進(jìn)行 Swap。
- 完善 IO 及網(wǎng)絡(luò)等資源的隔離機(jī)制。
實際上我們在業(yè)務(wù)的開發(fā)測試集群中就遇到了資源緊張同時調(diào)度不均衡導(dǎo)致大量 OOM 的場景,并且一度影響到了業(yè)務(wù)的接入。
本質(zhì)這還是資源利用率過高時調(diào)度的不合理造成。后面經(jīng)過優(yōu)化改進(jìn)才從這種困境中逃離。
再看另外一個場景,我們在將集群分配率擠壓到高于 50% 以上時,很容易出現(xiàn)資源碎片。這時一些資源需求較大的 Pod 會出現(xiàn)無法調(diào)度的情況。
在這種場景下則需要通過一些人工干預(yù)來進(jìn)行調(diào)度調(diào)整。針對這種場景,我們其實是需要通過一些策略調(diào)優(yōu)來優(yōu)化我們的調(diào)度,包括:Reschedule、 MostRequestedPriority、以及優(yōu)先級來優(yōu)化集群的調(diào)度。
圖四
圖四是簡化后一個單資源的示例。實際應(yīng)用中我們更希望集群有足夠的冗余度來做資源調(diào)度。
同時在混合云場景,我們更希望是盡量使用完部分節(jié)點再擴(kuò)容新的節(jié)點。比如圖四所示,希望存在一些大塊的空白節(jié)點,盡量減少碎片空間。
不過提高容器利用率,則會遇到上一場景提到的利用率過高時 Pod 資源不足的問題。所以必需首先解決好資源使用的預(yù)估及調(diào)度優(yōu)化。
而且也需要在利用率及冗余度上做平衡,設(shè)定對相應(yīng)的策略權(quán)重,通過一定水位限制確保節(jié)點仍有一定冗余度,如 MostRequestedPriority 的水位限制。水位控制與我們希望的集群利用率直接相關(guān)。
圖五
前面考慮很多時候是先從單個維度出發(fā)來考慮問題,實際場景中我們是多維度的。
多維度下會復(fù)雜得多,并且碎片的情況更容易出現(xiàn),在這種情況下很多時候得到的只是一個局部更優(yōu)調(diào)度而不是全局更優(yōu)。
有時候為了更接近全局更優(yōu)分配需要進(jìn)行一定重調(diào)度。這需要我們自定義控制器做特定的調(diào)度策略,同時考慮到大量調(diào)動 Pod 可能會帶來的業(yè)務(wù)抖動,特別是對于部分優(yōu)雅關(guān)閉沒有做很好的業(yè)務(wù),所以需要較嚴(yán)謹(jǐn)?shù)谋Wo(hù)規(guī)則和時機(jī)控制。如只在機(jī)器資源較為緊張時對優(yōu)先級較低的服務(wù)進(jìn)行調(diào)整。
在實際業(yè)務(wù)容器化過程中,業(yè)務(wù)對于資源的依賴復(fù)雜多樣,根據(jù)業(yè)務(wù)的實際需求,我們進(jìn)一步引入了 IO,網(wǎng)絡(luò),內(nèi)存帶寬等一些資源需求的調(diào)度,我們在調(diào)度策略中也新增了對應(yīng)的擴(kuò)展資源。
⑤基礎(chǔ)建設(shè)之彈性伸縮
調(diào)度解決了業(yè)務(wù)資源合理分配,彈性伸縮組(HPA)則是在提升資源利用率的同時對業(yè)務(wù)進(jìn)行資源保障的重要手段。
它保證在業(yè)務(wù)量級上來時能及時的進(jìn)行擴(kuò)容,在業(yè)務(wù)量級下降后又能及時回收資源,HPA 是根據(jù)特定的指標(biāo)以及業(yè)務(wù)設(shè)定的目標(biāo)值來增加或減少 Pod 的數(shù)量。
這部分需要考慮三方面:
- 伸縮指標(biāo)的擴(kuò)展
- 錯峰調(diào)度的實現(xiàn)
- 伸縮時的業(yè)務(wù)抖動的優(yōu)化
圖六
圖六左側(cè)是我們擴(kuò)展指標(biāo)的架構(gòu)圖,從圖中我們可以看到,通過擴(kuò)展采集模塊及 CME 構(gòu)建了擴(kuò)展指標(biāo)的采集面,通過預(yù)測器輸出預(yù)測指標(biāo),通過 custom-metrics 提供 HPA 所需要的擴(kuò)展指標(biāo)。
伸縮指標(biāo)我們主要是擴(kuò)展出了 4 個指標(biāo),包括 QPS,網(wǎng)絡(luò)入帶寬,網(wǎng)絡(luò)出帶寬,消息隊列積壓長度。錯峰調(diào)度則是通過定時策略實現(xiàn)。
我們這邊有一個云處理的業(yè)務(wù),會對于視頻做 H.265 轉(zhuǎn)碼、編碼優(yōu)化等 CPU 密集型操作,經(jīng)常會有突峰的轉(zhuǎn)碼需求導(dǎo)致該業(yè)務(wù)需要大量的 CPU 資源。
在這種情況下,HPA 的擴(kuò)縮容有時會跟不上節(jié)奏造成業(yè)務(wù)處理延時變長,主要是伸縮組算法在計算伸縮值時算法較為簡單,容易在業(yè)務(wù)量變小后馬上過量縮量。
這就會導(dǎo)致業(yè)務(wù)量波動時反復(fù)進(jìn)行伸縮影響業(yè)務(wù)穩(wěn)定,所以我們引入了慢縮容機(jī)制同時增加收縮滑動窗口以達(dá)到消峰的作用。
圖七
圖七是一個錯峰調(diào)度的案例。我們某個處理服務(wù),白天需要大量資源占用,高峰時需要 2500 核心,而低峰期間所需求的資源則非常少,最小時僅需要 60 核。
而另外一個服務(wù)的一些離線計算任務(wù)沒有太強(qiáng)時間急迫性要求,可以放在夜間處理,還有一些統(tǒng)計類定時任務(wù)也是可以放置在夜間,這樣整體集群資源可以被充分利用。
⑥基礎(chǔ)建設(shè)之監(jiān)控
監(jiān)控是我們生產(chǎn)穩(wěn)定的一個重要的保障手段。在容器化之前,我們運(yùn)維體系已經(jīng)有一套成熟的監(jiān)控機(jī)制,容器化之后相應(yīng)的監(jiān)控并不需要完全推倒重做,部分體系可以復(fù)用比如物理機(jī)監(jiān)控,在這之上引入新的容器監(jiān)控系統(tǒng)。
容器平臺主要監(jiān)控是幾方面的內(nèi)容:
- 物理機(jī)基礎(chǔ)監(jiān)控,主要是像硬盤,IO,內(nèi)存,網(wǎng)絡(luò)等
- 業(yè)務(wù)指標(biāo)監(jiān)控,包括異常監(jiān)控以及性能監(jiān)控
- 容器行為的監(jiān)控,監(jiān)控 Pod 資源,容器事情等
- 容器組件的監(jiān)控
實際上監(jiān)控指標(biāo)是持續(xù)在豐富及優(yōu)化的過程,我們最初只監(jiān)控了主要的四方面的指標(biāo),而最終進(jìn)行匯總分析時則是從集群,服務(wù),Pod,業(yè)務(wù)等等視角進(jìn)行多維度的匯總分析輸出。
圖八
監(jiān)控報表對于我們問題分析及排障會提供巨大的便利。圖八是一個 CPU 監(jiān)控圖,圖中可以看出有兩個高峰期 Pod 的 CPU 是跑滿了。
實際對應(yīng)到的正是線上的某一次業(yè)務(wù)異常,當(dāng)時業(yè)務(wù)的 SLA 在流量高峰時部分處理延時較高并導(dǎo)致報警。
基礎(chǔ)平臺的建設(shè)涉及到的還有很多內(nèi)容,比如多集群的管理、多租戶管理、DNS 的優(yōu)化,鏡像服務(wù)的優(yōu)化,混合云落地等等,限于篇幅不一一展開。
業(yè)務(wù)落地
前面講了比較多是基礎(chǔ)平臺構(gòu)建的一些內(nèi)容,下面我們聊一下業(yè)務(wù)接入的一些事情。
我們知道容器化給業(yè)務(wù)帶來的收益是非常多的,但是我們也是需要考慮可能會給業(yè)務(wù)帶來的困難。
考慮各種遷移和改造的問題,我們需要將平臺更進(jìn)一步優(yōu)化,讓業(yè)務(wù)接入成本盡量低。
提供更簡單方便的 CI/CD 流程,我們需要提供友好的統(tǒng)一的操作界面,提供完整的接入指導(dǎo),快速排障工具,定期的培訓(xùn)等。
圖九
比如我們優(yōu)化 CI/CD 流程,整個構(gòu)建和發(fā)布過程對開發(fā)盡量透明,圖九右邊是新的流程,開發(fā)提交完代碼之后,Gitlab-CI 會自動促發(fā)測試及構(gòu)建過程,并將鏡像推送到倉庫。
開發(fā)同學(xué)僅需要在統(tǒng)一門戶網(wǎng)上面操作對應(yīng)的版本進(jìn)行發(fā)布,平臺會自動生成 Deployment 并發(fā)布至相應(yīng)的集群。
再比如,我們提供一個友好的管理平臺,它可以減少業(yè)務(wù)學(xué)習(xí)成本以及出錯的概率。
同時也提供了靈活的軟件階段定制支持??梢允褂煤唵蔚姆绞蕉ㄖ贫鄠€階段,包括:Dev、Test、Pre、 Beta、Canary、Realse … …
綜上,其實我們僅基礎(chǔ)平臺建設(shè)是遠(yuǎn)不夠,實際業(yè)務(wù)接入過程中需要考慮很多其他因素。同時業(yè)務(wù)的需求也不斷地優(yōu)化我們的平臺架構(gòu),最終實現(xiàn)整體的落地。
實際上我們做的也確實還遠(yuǎn)遠(yuǎn)不夠,業(yè)務(wù)在接入過程還是需要面臨著眾多的問題。
所以我們需要在各方面都進(jìn)一步完善,業(yè)務(wù)其實一直在教導(dǎo)我們?nèi)绾巫龊靡粋€平臺,我們也在不斷地學(xué)習(xí)吸收。這也是我們不斷提升的源動力之一。
展望未來
未來我們將長期運(yùn)行多集群混合云的架構(gòu),會逐步引入多家公有云,優(yōu)化調(diào)度系統(tǒng),更進(jìn)一步提高我們的資源利用率,同時也會保持著對 ServiceMesh、Serverless、邊緣計算等方向的關(guān)注,會結(jié)合著業(yè)務(wù)的需求,更進(jìn)一步優(yōu)化容器基礎(chǔ)平臺。
目前就職于美圖技術(shù)保障部架構(gòu)平臺,主要從事容器基礎(chǔ)平臺建設(shè),流媒體體系相關(guān)建設(shè)。負(fù)責(zé)容器平臺基礎(chǔ)組件建設(shè)、調(diào)度系統(tǒng)研發(fā)、多機(jī)房及混合云建設(shè)、流媒體基礎(chǔ)服務(wù)建設(shè)及用戶體驗優(yōu)化等。在容器化技術(shù)及流媒體方向有著多年的積累及豐富的實戰(zhàn)經(jīng)驗。