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