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