摘要:有贊容器化方案我們的容器化方案基于和,下面介紹一下我們在各個方面遇到的問題以及解決方案。不過對于上線來說,需要整個運維體系來適配容器化,比如監(jiān)控發(fā)布日志等等。
前言
容器化已經(jīng)成為一種趨勢,它可以解決很多運維中的痛點,比如效率、成本、穩(wěn)定性等問題,而接入容器的過程中往往也會碰到很多問題和不便。在有贊最開始做容器化是為了快速交付開發(fā)測試環(huán)境,在容器化的過程中,我們碰到過容器技術(shù)、運維體系適配、用戶使用習(xí)慣改變等各種問題,本文主要介紹有贊容器化過程中碰到的問題以及采取的方案。
有贊容器化的初衷在有贊同時會有很多個項目、日常在并行開發(fā),環(huán)境的搶占問題嚴重影響了開發(fā)、測試和上線的效率,我們需要給每個項目提供一套開發(fā)聯(lián)調(diào)(daily)、測試環(huán)境(qa),并且隨著項目、日常的生命周期項目環(huán)境也會隨著創(chuàng)建和銷毀,我們最早的容器化需求就是怎么解決環(huán)境快速交付的問題。
[有贊環(huán)境]
上面是有贊大致的研發(fā)流程,在標(biāo)準(zhǔn)流程中我們有四套穩(wěn)定環(huán)境,分別是 Daily 環(huán)境、Qa 環(huán)境、預(yù)發(fā)環(huán)境和測試環(huán)境。我們的開發(fā)、測試、聯(lián)調(diào)工作一般并不會直接在穩(wěn)定環(huán)境中進行,而是會拉一套獨立的項目環(huán)境出來,隨著代碼經(jīng)過開發(fā)、測試、預(yù)發(fā)驗收最終發(fā)布到生產(chǎn)環(huán)境后再同步回 Daily/Qa 的穩(wěn)定環(huán)境中。
[項目環(huán)境]
我們提供了一套以最小的資源投入滿足最大項目并行度的環(huán)境交付方案,在 Daily/Qa 穩(wěn)定環(huán)境的基礎(chǔ)上,隔離出N個項目環(huán)境,在項目環(huán)境里只需要創(chuàng)建該項目所涉及應(yīng)用的計算資源,其它缺失的服務(wù)調(diào)用由穩(wěn)定環(huán)境提供,在項目環(huán)境里,我們大量使用了容器技術(shù)。
[持續(xù)交付]
后面我們又在項目環(huán)境快速交付的解決方案的基礎(chǔ)上實現(xiàn)了持續(xù)交付流水線,目前已經(jīng)有超過 600 套項目/持續(xù)交付環(huán)境,加上 Daily/Qa 穩(wěn)定環(huán)境,涉及計算實例四五千個,這些計算實例無論是 cpu 還是內(nèi)存使用率都是非常低的,容器化可以非常好的解決環(huán)境交付的效率問題,以及提高資源使用率來節(jié)省成本的投入。
有贊容器化方案我們的容器化方案基于 kubernetes(1.7.10)和 docker(1.12.6)、docker(1.13.1),下面介紹一下我們在各個方面遇到的問題以及解決方案。
網(wǎng)絡(luò)有贊后端主要是 java 應(yīng)用,采用定制的 dubbo 服務(wù)化方案,過程中無法做到整個單元全量容器化,和原有集群在網(wǎng)絡(luò)路由上互通也就成了剛需,由于我們無法解決公有云上 overlay 網(wǎng)絡(luò)和公有云網(wǎng)絡(luò)的互通問題,所以一開始我們放棄了 overlay 網(wǎng)絡(luò)方案,采用了托管網(wǎng)絡(luò)下的 macvlan 方案,這樣既解決了網(wǎng)絡(luò)互通的問題也不存在網(wǎng)絡(luò)性能問題,但是也就享受不到公有云彈性資源的優(yōu)勢了。隨著有贊多云架構(gòu)的發(fā)展以及越來越多的云廠商支持容器 overlay 網(wǎng)絡(luò)和 vpc 網(wǎng)絡(luò)打通,彈性資源的問題才得到了緩解。
隔離性容器的隔離主要利用內(nèi)核的 namespace 和 cgroup 技術(shù),在進程、cpu、內(nèi)存、IO等資源隔離限制上有比較好的表現(xiàn),但其他方面和虛擬機相比存在著很多的不足,我們在使用過程中碰到最多的問題是容器里看到的 cpu 數(shù)和內(nèi)存大小不準(zhǔn)確,因為/proc文件系統(tǒng)無法隔離,導(dǎo)致容器里的進程"看到"的是物理機的 cpu 數(shù)以及內(nèi)存大小。
內(nèi)存問題我們的 java 應(yīng)用會根據(jù)服務(wù)器的內(nèi)存大小來決定 jvm 參數(shù)應(yīng)該怎么配置,我們是采用 lxcfs 方案來規(guī)避的。
因為我們有超賣的需求以及 kubernetes 默認也是采用 cpu share 來做 cpu 限制,雖然我們使用了 lxcfs,CPU 數(shù)還是不準(zhǔn)的。jvm 以及很多 Java sdk 都會根據(jù)系統(tǒng)的 CPU 數(shù)來決定創(chuàng)建多少線程,導(dǎo)致 java 應(yīng)用在線程數(shù)和內(nèi)存使用上都比虛擬機多的多,嚴重影響運行,其他類型的應(yīng)用也有類似的問題。
我們會根據(jù)容器的規(guī)格內(nèi)置一個環(huán)境變量 NUM_CPUS,然后比如 nodejs 應(yīng)用就會按照這個變量來創(chuàng)建它的 worker 進程數(shù)。在解決 java 類應(yīng)用的問題時,我們索性通過 LD_PRELOAD 將 JVM_ActiveProcessorCount 函數(shù)覆蓋掉,讓它直接返回 NUM_CPUS 的值[1]。
在容器化之前,有贊的應(yīng)用已經(jīng)全部接入到發(fā)布系統(tǒng),在發(fā)布系統(tǒng)里已經(jīng)標(biāo)準(zhǔn)化了應(yīng)用的打包、發(fā)布流程,所以在應(yīng)用接入方面成本還是比較小的,業(yè)務(wù)方無需提供 Dockerfile。
nodejs, python,php-soa 等用 supervisord 托管的應(yīng)用,只需要在 git 倉庫里提供 app.yaml 文件定義運行需要的 runtime 和啟動命令即可。
java 標(biāo)準(zhǔn)化啟動的應(yīng)用業(yè)務(wù)方無需改動
java 非標(biāo)準(zhǔn)化的應(yīng)用需要做標(biāo)準(zhǔn)化改造
鏡像集成
容器鏡像我們分了三層,依次為 stack 層(os),runtime 層(語言環(huán)境),應(yīng)用層(業(yè)務(wù)代碼和一些輔助agent),應(yīng)用以及輔助 agent 由 runit 來啟動。由于我們的配置還沒有完全分離,在應(yīng)用層目前還是每個環(huán)境獨立打包,鏡像里除了業(yè)務(wù)代碼之外,我們還會根據(jù)業(yè)務(wù)的語言類型放一些輔助的 agent。我們一開始也想將各種 agent 拆成多個鏡像,然后每個 pod 運行多個容器,后來因為解決不了 pod 里容器的啟動順序(服務(wù)啟動有依賴)問題,就把所有服務(wù)都扔到一個容器里去運行了。
我們的容器鏡像集成過程也是通過 kubernetes 來調(diào)度的(會調(diào)度到指定的打包節(jié)點上),在發(fā)布任務(wù)發(fā)起時,管控系統(tǒng)會在集群中創(chuàng)建一個打包的 pod,打包程序會根據(jù)應(yīng)用類型等參數(shù)編譯代碼、安裝依賴,并且生成 Dockerifile,然后在這個 pod 中使用 docker in docker 的方式來集成容器鏡像并推送到倉庫。
為了加速應(yīng)用的打包速度,我們用 pvc 緩存了 python 的 virtualenv,nodejs 的 node_modules,java 的 maven 包等文件。另外就是 docker 早的版本里,Dockerfile ADD 指令是不支持指定文件屬主和分組的,這樣會帶來一個問題就是需要指定文件屬主時(我們的應(yīng)用是以 app 賬號運行的)需要多運行一次 RUN chown,這樣鏡像也就多了一層數(shù)據(jù),所以我們打包節(jié)點的 docker 版本采用了官方比較新的 ce 版本,因為新版本支持 ADD --chown 特性。
有贊的應(yīng)用內(nèi)部調(diào)用有比較完善的服務(wù)化和 service mesh 方案,集群內(nèi)的訪問不用過多考慮,負載均衡只需要考慮用戶和系統(tǒng)訪問的 http 流量,在容器化之前我們已經(jīng)自研了一套統(tǒng)一接入系統(tǒng),所以在容器化負載均衡上我們并沒有完整按照 ingress 的機制來實現(xiàn) controller,ingress 的資源配置是配在統(tǒng)一接入里的,配置里面轉(zhuǎn)發(fā)的 upstream 會和 kubernetes 里的 service 關(guān)聯(lián),我們只是做了一個 sync 程序 watch kube-api,感知 service 的變化來實時更新統(tǒng)一接入系統(tǒng)中 upstream 的服務(wù)器列表信息。
在容器化接入過程中開發(fā)會反饋是控制臺比較難用,雖然我們優(yōu)化了多次,和 iterm2 等的體驗還是有所不足,最終我們還是放開了項目/持續(xù)交付環(huán)境這種需要頻繁登陸調(diào)試的 ssh 登陸權(quán)限。
另外一個比較嚴重的問題是,當(dāng)一個應(yīng)用啟動后健康檢查有問題會導(dǎo)致 pod 一直在重新調(diào)度,而在開發(fā)過程中開發(fā)肯定是希望看到失敗現(xiàn)場的,我們提供了調(diào)試發(fā)布模式,讓容器不做健康檢查。
有贊有專門的日志系統(tǒng),我們內(nèi)部叫天網(wǎng),大部分日志以及業(yè)務(wù)監(jiān)控數(shù)據(jù)都是通過 sdk 直接打到天網(wǎng)里去了,所以容器的標(biāo)準(zhǔn)輸出日志僅僅作為一種輔助排查問題的手段。我們?nèi)萜鞯娜罩臼占捎玫氖?fluentd,經(jīng)過 fluentd 處理后按照天網(wǎng)約定的日志格式打到 kafka,最終由天網(wǎng)處理進入 es 做存儲。
我們涉及到灰度發(fā)布的流量主要包含三部分:
用戶端的 http 訪問流量
應(yīng)用之間的 http 調(diào)用
應(yīng)用之間的 dubbo 調(diào)用
首先,我們在入口的統(tǒng)一接入上統(tǒng)一打上灰度需要用的各種維度的標(biāo)簽(比如用戶、店鋪等),然后需要對統(tǒng)一接入、http client 以及 dubbo client 做改造,目的是讓這些標(biāo)簽?zāi)軌蛟谡麄€調(diào)用鏈上透傳。我們在做容器灰度發(fā)布時,會發(fā)一個灰度的 deployment,然后在統(tǒng)一接入以及灰度配置中心配置灰度規(guī)則,整個鏈路上的調(diào)用方都會感知這些灰度規(guī)則來實現(xiàn)灰度發(fā)布。
標(biāo)準(zhǔn)環(huán)境容器化 標(biāo)準(zhǔn)環(huán)境的出發(fā)點和項目環(huán)境類似,標(biāo)準(zhǔn)穩(wěn)定環(huán)境中的 daily,qa,pre 以及 prod 中超過一半運行在低水位的服務(wù)器的資源非常浪費。
因為成本考慮 daily,qa,pre 里都是以單臺虛擬機運行的,這樣一旦需要發(fā)布穩(wěn)定環(huán)境將會造成標(biāo)準(zhǔn)穩(wěn)定環(huán)境和項目環(huán)境的短暫不可用。
虛擬機交付速度比較慢,使用虛擬機做灰度發(fā)布也比較復(fù)雜。
虛擬機往往會存在幾年甚至更長的時間,運行過程中操作系統(tǒng)以及基礎(chǔ)軟件版本的收斂非常麻煩。
標(biāo)準(zhǔn)環(huán)境容器化推進經(jīng)過之前項目/持續(xù)交付的上線和迭代,大部分應(yīng)用本身已經(jīng)具備了容器化的條件。不過對于上線來說,需要整個運維體系來適配容器化,比如監(jiān)控、發(fā)布、日志等等。目前我們生產(chǎn)環(huán)境容器化準(zhǔn)備基本完成,生產(chǎn)網(wǎng)已經(jīng)上了部分前端 nodejs 應(yīng)用,其他應(yīng)用也在陸續(xù)推動中,希望以后可以分享更多生產(chǎn)環(huán)境中的容器化經(jīng)驗。
結(jié)束語以上是有贊在容器化上的應(yīng)用,以及在容器化過程中碰到的一些問題和解決方案,我們生產(chǎn)環(huán)境的容器化還處于開始階段,后面還會碰到各種個樣的問題,希望能夠和大家互相學(xué)習(xí),后面能夠有更多的經(jīng)驗分享給大家。
參考文獻[1] https://github.com/fabianenar...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/11418.html
摘要:有贊容器化方案我們的容器化方案基于和,下面介紹一下我們在各個方面遇到的問題以及解決方案。不過對于上線來說,需要整個運維體系來適配容器化,比如監(jiān)控發(fā)布日志等等。 前言 容器化已經(jīng)成為一種趨勢,它可以解決很多運維中的痛點,比如效率、成本、穩(wěn)定性等問題,而接入容器的過程中往往也會碰到很多問題和不便。在有贊最開始做容器化是為了快速交付開發(fā)測試環(huán)境,在容器化的過程中,我們碰到過容器技術(shù)、運維體系...
摘要:第三個就是比較重點的內(nèi)容,在有贊的實踐。第四部分是將實時計算化,界面化的一些實踐。二有贊實時平臺架構(gòu)有贊的實時平臺架構(gòu)呢有幾個主要的組成部分。實時平臺提供了集群管理,項目管理,任務(wù)管理和報警監(jiān)控的功能。。 一、前言 這篇主要由五個部分來組成: 首先是有贊的實時平臺架構(gòu)。 其次是在調(diào)研階段我們?yōu)槭裁催x擇了 Flink。在這個部分,主要是 Flink 與 Spark 的 structure...
摘要:第三個就是比較重點的內(nèi)容,在有贊的實踐。第四部分是將實時計算化,界面化的一些實踐。二有贊實時平臺架構(gòu)有贊的實時平臺架構(gòu)呢有幾個主要的組成部分。實時平臺提供了集群管理,項目管理,任務(wù)管理和報警監(jiān)控的功能。。 一、前言 這篇主要由五個部分來組成: 首先是有贊的實時平臺架構(gòu)。 其次是在調(diào)研階段我們?yōu)槭裁催x擇了 Flink。在這個部分,主要是 Flink 與 Spark 的 structure...
摘要:業(yè)務(wù)對賬平臺的核心目的,就是及時發(fā)現(xiàn)類似問題,并及時修復(fù)。這對對賬平臺的吞吐量造成了挑戰(zhàn)。五健康度對賬中心可以拿到業(yè)務(wù)系統(tǒng)及其所在整個鏈路的數(shù)據(jù)一致性信息。在分布式環(huán)境下,沒有人能回避數(shù)據(jù)一致性問題,我們對此充滿著敬畏。 一、引子 根據(jù)CAP原理,分布式系統(tǒng)無法在保證了可用性(Availability)和分區(qū)容忍性(Partition)之后,繼續(xù)保證一致性(Consistency)。我...
閱讀 771·2021-09-28 09:35
閱讀 2600·2019-08-29 11:25
閱讀 2165·2019-08-23 18:36
閱讀 1864·2019-08-23 16:31
閱讀 2078·2019-08-23 14:50
閱讀 3131·2019-08-23 13:55
閱讀 3299·2019-08-23 12:49
閱讀 2091·2019-08-23 11:46