摘要:說起,必須要介紹是什么東西,為什么中小企業私有云適合使用。看一下現在的架構圖開個玩笑。上面這四點導致我們必須要統一架構,最終把整個業務系統遷移到基于的類似于的私有云的平臺。
本文系 ArchSummit 大會 CODING 工程師王振威演講實錄。
大家好,非常高興在這里跟大家分享,我是王振威,來自 Coding 的一個程序員。今天給大家帶來的分享主要是我們團隊在使用 Docker 改進原有的業務系統的演進計劃和實施的經驗教訓。
說起 Docker,必須要介紹 Docker 是什么東西,為什么中小企業私有云適合使用 Docker。其次是我們做一套架構系統的變遷,總是事出有因的,我們必須介紹一下為什么變遷。第三是怎么變遷,作為中小型企業要想把業務假設到私有云上,如何一步一步來做。最后我們在使用Docker的過程中遇到了比較棘手和麻煩的問題。
第一,Docker,在座有相當一部分人已經了解了,它是容器技術,跟私有云有什么關系?那么首先要解釋一下什么叫私有云。
私有云用這樣一句話來形容是最為貼切的:就是企業內部的服務于企業自身的云服務平臺。企業內部有很多服務器,有不同的業務系統,但是想讓這些業務系統高效地運行起來,我們往往會采用類似于 IaaS 或者 PaaS 的技術來搭建這個平臺。那么 Docker 為什么適用于搭建一個私有云的企業平臺呢?因為容器技術比傳統的VM技術成本更低、效率更高。關鍵點在于這種技術是兼容性又好的,可以使我們傳統的架構變遷顯得更為平滑,這是最為重要的一點。另外,容器技術一大特點就是快速實現隔離,統一調配。有如下三快:
構建快
一個應用最終的形式往往是環境加上程序包,形成最終的鏡像,image 就是程序本身外加環境,Docker 讓我們可以用 Dockerfile 之類的技術定義鏡像,自動構建,免去在很多服務器上繁雜的安裝配置應用程序環境的過程
啟動快
容器相比虛擬機的啟動速度是非常快的,開一臺虛擬機的啟動速度慢一點的一分鐘,快一點的也要十幾秒,但是容器往往可以做到秒級啟動,這為我們后面所講的容器化交付奠定了基礎。
遷移快
應用以容器的方式標準化交付,這個主機跟另外一個主機只要安裝了 Docker 就沒有什么差別,image 不管扔到這里還是扔到那里都可以很快地正常運行。而傳統的 VM,只是省去了我們購置租用物理服務器的過程,本質上來講還是一個裸的操作系統,本來這個程序在 A 機運行,但 A 機掛了,現在來配置 B機,裝了 JDK,發現不行,這個 JDK 版本不對啦,JDK 缺少了本地的庫啦,之類一系列問題。但是如果用了 Docker,用了容器技術,它把這些依賴環境全打成 image,只要把 image 下載下來就行了,這是編程語言,框架無關的,因為應用的環境是跟著應用走的。
看一下現在的架構圖
開個玩笑。
如果我們的架構是這樣的話那就沒什么好講了,我的意思是說一個成熟的以容器來做基層建設的私有云環境,最終的效果應該像巨輪一樣,可以把所有的貨艙都碼放整齊,可以平穩地向前航行,這是基于容器的私有云的愿景。
有人會問了,如果說你之前的架構沒問題,為何要遷移到這個環境來呢?
事出有因,假如傳統的架構是很好的,我們沒必要遷移到 Docker 這種私有云環境來,我們為什么要遷移?
有幾個原因:
第一是我們之前的業務系統隨著時間的發展越來越多,不同的組件需要協同去做不同的工作,給運維帶來了巨大的挑戰,有 JAVA 寫的程序,還有些程序制定了必須用 JDK7,一些部門覺得 JDK8 有些特性比較好用所以用了 JDK8,還有些組件是用 Ruby 寫的,還有 Golang,NodeJS等等,目前我們系統中牽扯的系統語言已經達到了八九種,這對運維來講是一個巨大的挑戰,我們必須要給各種各樣的程序準備各種各樣的環境,維護,遷移都非常麻煩。
另外配置混亂,當你應用的服務器數量越來越多,有的系統可能是用 upstart 來管理程序,有的是用 Supervisor , 有些程序可能只是個 定時任務。我們的編程語言每一種都會有自己的構建工具,構建工具對依賴的管理也不太一樣。最終的結果是操作系統中的配置文件和各種黑科技補丁腳本散落在系統的各個角落,沒人能找得到,也沒人搞得懂。
最后致命的一點是監控和資源的混亂,?監控混亂,如果是一個很簡單的程序,往往只需要做到當發生錯誤,把這個錯誤日志打印出來,運維上看一下日志就行了。當涉及到幾百臺應用服務器,其中的各個組件每天打印上百萬條、上千萬條各種不同級別的日志的時候,運維是沒有精力去了解的,我們只能做錯誤報告,做消息的推送,但是因整體系統混亂,每個應用有各自的方式,最終導致日志,錯誤監控都沒能達到相應的預期。然后是混亂的資源,我們做 WEB 的應用往往出現白天是高峰期,晚上是低峰期,低峰期zi"yuanziyuan使用率很低,屬于資源的浪費。另外有些業務在申請計算資源的時候不能提前預估到使用量有多少,申請的過多或者過少,運維又要經常承擔著縮容擴容的問題。
有因必有果,環境不匹配導致測試跟生產環境不一樣,比如生產環境是 JDK8 跑的,某一個開發者本地用 JDK7 測試的程序,上去發現這個東西根本不對,雖然 JDK7 和 JDK8 的兼容性已經是99%以上,但是一個嚴謹的業務系統必須要做到測試環境跟生產環境是一致的。
配置混亂導致事故頻發,做過運維的肯定了解,這個配置被誰改掉了,這個服務宕掉了,當你的組件越來越多的時候根本無從管理。監控不一致,資源效率低。計算資源的成本很高,卻達不到相應的目標。所以之前那艘看起來航行很平穩的巨輪,在上面這四大原因的影響下,事實上是這樣的。
上面這四點導致我們必須要統一架構,最終把整個業務系統遷移到基于 Docker 的類似于 PaaS 的私有云的平臺。
架構變遷,作為一個架構團隊的 Leader,在做架構變遷遵循的時候要掌握如下原則:
DevOps 變遷原則即面向未來,又不過于激進
即追求穩定,又不過與保守
其實就是掌握平衡,追求一個度。我們用新技術,必然是為了解決舊技術的問題我們才用,但如果過于追求新技術,忽略了業務的重要性,你會發現你最終是得不償失的。所以我們遵循的原則是既面向未來,又不過于激進,既追求穩定,又不過于保守。
關于技術選型,這是我們團隊的做法。
OS | Container | Service Discovery | Config | Container Management | |
---|---|---|---|---|---|
Windows | Rocket | Consul | JSON | K8s | |
Ubuntu | RunC | Etcd | INI | Mesos | |
CentOS | Docker | YAML | Swarm | ||
Redhat | Compose | ||||
Ubuntu | None |
容器技術現在有幾種選擇,Docker 本身的底層就是 RunC。谷歌內部有自己的容器技術,VMware 也有容器技術,但是就目前來講,Docker 是最好的選擇。服務發現我們用了 ETCD,我不再講哪個軟件好哪個軟件壞,不同的軟件會適用不同的業務場景,只有適合與不適合。
接下來我會講具體的架構變遷三步走。
架構變遷三步走遵循的最重要的一點是平滑演進。我們都知道我們的業務系統是脆弱的,經不起風吹雨打,如果大動干戈搞一下,新的架構出問題了,業務系統是承受不住,技術部門也無法承受住其他部門帶來的壓力。所以我們必須有序平穩平滑的演進升級。微服務是這套升級的一個基礎點,如果你的這些應用不是微服務,不是無狀態化的,那你就沒辦法讓多個實例協同工作。最后是軟硬分離,分割計算資源和具體業務的強依賴,其實這個問題,在我們全部走完,只要在配置好的服務器環境裝一個 Docker 就搞定了。
三步走的具體第一步是 Dockerize,什么叫 Dockerize?先把應用無狀態化,你可以采用一些集中式緩存這種技術讓應用變得沒有自己的狀態,它隨時起停,起多少份都是無所謂的,只要有負載均衡器就可以讓這些組件對外提供一致的服務。當無狀態化應用實現之后,我們就可以給這個應用寫 Dockerfile 了,Dockerfile 構建的結果就是 Docker ?image ,其本身就是應用和環境,第一行是from java jdk7,第二行設置應用程序,第三行把這個程序運行起來。
# Base FROM java:jdk-7 COPY ./.src/target/app-1.0.jar /app/ # ENTRYPOINT WORKDIR /app CMD [ "java", "-Dfile.encoding=UTF-8", "-jar", "./app-1.0.jar" ]
這是很簡單的 Dockerfile,不要看他簡單,我推薦的是各位用 Docker 就應該這么用。不需要在 Dockerfile 里寫一堆 apt-get install ,一大堆 run 命令這些東西,記住 Dockerfile 就是聲明應用環境和應用本身。Docker 現在做的功能太多了,很多都是不怎么靠譜的,Docker 需要更專注于它本身作為容器的技術。完成無狀態化應用和寫完 Dockerfile 之后,這個程序就可以被打報成 Docker image 了,放到一個 Docker Host 上運行起來就得到了無狀態的應用容器,也就完成了把應用裝容器的過程。
架構變遷的第二步是管理你的容器。不能說應用扔進去就不管了,如何管,管的辦法有很多,容器技術這個圈里爭論最多的就是編排技術。
容器的管理方式對 Docker 來講,目前就三種:
第一是直接管,我們都知道Docker 官方有一個 CLI 工具,只要裝了 Docker 就可以使用這個 CLI 工具把指定的程序運行在容器里,這是更直接的方式。但明顯我們有幾十臺上百臺服務器的時候,不能每個都上去搞一下,雖然它更直接,但它比較麻煩。
另外一個是 Docker remote API,更為靈活,提供了相關的編程接口來管理容器。
最后是編排系統,它們更為復雜,定義的條條框框更多。我這里不推薦做架構漸變演化的團隊采用。主要原因是,我們遷移到這些編排系統往往都是跳躍式的升級,不是平滑演進,業務系統不能容許直接把整個業務系統跳躍式升級,無法承擔風險,出問題的回退預案也很難定制。當然如果是一個本身從零開始的系統,那你可以嘗試一下,但也不保證這種編排系統就適應于你的業務系統。我們推薦一步一步走,先把這種應用變成容器,再來想辦法管理這些容器。
很顯然我們采用的是第二種選擇。
配置文件配合 Docker remote API。根據實際情況,選擇Docker的少量的一些特性,例如文件系統、網絡、資源限定等這些成熟的,我們最為需要的功能,我們編寫了一個便捷的操作工具 cli/web。
在配置文件中定義一個任務,名字寫下來,這個任務用什么 image 跑,什么版本,運行在哪臺機器上,注意這里,機器名并不跟具體的業務綁定,而是一個資源池,不管什么應用都是無差別的,只要是無狀態的應用,所有的存儲、依賴都通過網絡的形式來解決,我們整個資源池就可以實現自由調度。
如果把這個應用綁定到某一些具體的特有的機器上的話,局限性比較大,萬一這些機器出問題,將無法快速遷移。有一些選項是沒填的,比如 port, port 其實是 Docker 支持把容器內的某個端口映射到容器外,我們沒填這個東西是因為,我們默認在全系統級都只使用Docker的 host 網絡模式。 host 模式下,Docker 內部容器的網絡跟宿主機的網絡是一樣的,這是 Docker 所有網絡模式中性能最高的,缺點是不能做隔離。
這里有人可能會問,為什么要放棄隔離呢?這里解釋下沒用 Docker 的高級的網絡模式,以及 SDN、端口映射等的原因。就是沒必要。注意我們講的是私有云平臺,私有云平臺內部都是企業自身的業務,大部分業務都基于業務層面做隔離和權限就可以了, 所以 Docker 用 host 的模式運行就跟傳統應用沒有差別,不需要做 NAT,SDN,也不需要做端口影射,另外一個好處就是,對于應用來講他們的依賴用容器和不用容器都是一樣的,這完全符合我們要求的平滑演進。
下面還有其他的配置,我們會通過環境變量控制一些應用內部的參數,因為我們的配置文件往往是打包到 image 里面,但是 Docker 這點挺煩的,改一個配置文件都要重新打一個 image,我們最終把配置項做成環境變量或者 CMD 參數,這樣可以在組件間共享一些 image。
這是我們用CLI在更新某個實例的時候打印出的內容,這是我們自己的定制的,它會告訴我們當前運行的實例的名字是什么,運行時間是什么等等一系列內容,只要選擇指定版本代碼的 Docker image,我們就可以完成全自動化的更新。
另外我們還部署了一套 DockerUI,這個軟件總體用下來不是特別好用,這是它大概的界面,跟我們 CLI 的功能比較類似,我們之后會自己定制一個運維的系統級 DashBoard。
架構變遷第三步就是如何真正地把我們上面實現的內容替換到現有的系統中。釜底抽薪,這個形容是比較貼切的。我們的服務都是無狀態化的,這個服務運行在哪里是無關緊要的,運行多少份也是無關緊要的,只要把這些新的容器化的交付應用替換掉之前的以各種雜亂的形式運行的應用,由于演進是平滑的,直接替換即可,整個系統就有機結合起來了。
完成架構變遷前兩部之后,假如現在系統有50個組件,只完成了5個組件的 Docker 化、無狀態化、編排。沒問題,我們的原則就是平滑,漸進,你不需要全部搞定,就可以開始應用到生產環境了。目前 Coding 的 95% 的組件都運行在 Docker里面,為什么留5%,是因為有一些極其邊緣的組件,因歷史遺留原因還沒有遷移過去。事實上我們發現只要前兩步做的好,第三步是很容易的,簡單來說就是停掉舊服務,啟動新服務。
這里值得一提的是,不光我們的主業務系統需要這么做,我們的一些附屬業務系統包括監控系統、負載均衡系統、服務發現等等,都應該按照這個架構一步一步替換過來。最后實現計算和存儲分離,軟件和硬件分離。因之前不是在容器中運行,應用對某個服務器可能都是一種強依賴的狀態,而現在把這些組件替換掉之后,你所有應用的環境都封裝在 Docker image 里面,這些服務器上本身沒有任何各個語言的執行環境,他們都是 Docker 宿主機,自動就變成無差別化的了。Docker Image只要放到任何一臺裝有 Docker 的環境上,就可以很快運行起來。
這是線上的 Docker 容器的列表截圖,這是某一臺服務器運行的實例。最終形成的架構是這樣的:
當你們看到這個架構的時候覺得它并不高端也并不奇怪,因為很多傳統架構就是這樣。而我想說的是我們完成這些東西其實也并不違背傳統的高可用分布式架構,只是釜底抽薪,把底層的進程組件換成了容器,把原來管理應用的方式換成了管理容器的方式。
我們現在運維的流程是這樣,運維有兩種方式來操作這些容器,分別是 CLI 和 UI 界面,運維操作都是發往這個工具,這個工具是可以管理現有所有的容器,所有的容器的定義都會存放在相應的配置文件里,這些配置文件還會在 ETCD 里做一個副本,LB 系統監控系統等等需要知道這些組件的狀態。
LB系統是內部服務的總入口,比如內部有一個很小的服務,這個服務做的事情很簡單,所以它屬于微服務的特點,微服務就是某一個組件每一個服務只做好一件事情,把這個事情做到極致。而 LB 就是把對這些服務的請求轉發給相應的無狀態組件。
我們有一個微服務的組件 md2html 就做一件事情,就是編譯 Markdown ,所有其他組件但凡有需要編譯 Markdown 的都通過 LB 系統調它。這個組件使用 Ruby 寫的,其運行環境比較難配置,牽扯到一些原生的 C 的庫,會對一些本地庫有些版本需求,新增服務器很容易配置錯誤。現在就沒問題了,這個應用的環境已經被我們打包成 image 存入了 Docker registry ,即便我們裝有運行環境的那臺機器宕了,我們只要用 Docker pull 下來,立馬就能遷移到另外一臺服務器。
我們的監控系統跟 LB 是什么關系?監控系統會對每一個容器的關鍵指標做數據收集,比如 LB,比如剛提到的 md2html ,都會維護一個 Http 接口,這個接口里提供它的關鍵指標的數據信息。計算資源服務器的關鍵指標有內存使用量,CPU 使用率等等。應用程序的關鍵指標都由各個業務應用自己定義。
例如我們這個 md2html 他的一個關鍵指標就是每秒鐘處理的MD數量。
我們的監控系統會定時抓取這些關鍵指標,要求較高的是 5 秒一次,要求低的可能是1分鐘,抓取之后存入數據庫,再配上一些監控的報警規則。比如一個 md2html 實例,正常業務量可能是每秒鐘處理10個編譯的任務,但是監控系統查到連續五分鐘處理量都低于3,我們就認為這個實例有問題了。
監控系統在遇到問題時,一方面會發一條消息到 ETCD 里面,告知現在這個實例異常,LB 系統訂閱ETCD,LB 系統 watch 到相應的改變之后就會把自己的配置改一下然后做一次 reload,這個實例就自動下線了。另外,監控系統監測到問題的時候會發一條消息到通知中心,通知中心會把錯誤的信息直接通過手機 APP 推送給運維人員。另外我們還支持包括發郵件,發短信,打電話等等形式。通知中心是我們這個系統中組件共用的,還有些普通的業務應用也會用到通知中心這個組件。
這些組件都是運行的多個實例,不要覺得業務量不大何必運行這么多實例,對一個服務來講,它沒什么負載,它運行著也不會占你太多的計算資源,據我的了解我接觸大多數人的系統架構里計算資源都屬于過剩的狀態,他們卻不愿意去多運行幾個實例來提升可靠度。
這里是我們這個架構圖的一些細節:
LB 系統: Nginx / HAProxy / confd / Etcd
監控系統: Prometheus / cAdvisor / Http Metrics
Docker Registry V1
Docker 網絡:Host
Docker 日志:Mount 宿主機
HAProxy/ nginx這些很普通的負載均衡軟件。confd 是一個很簡單的程序,就做一件事情,confd 一直 watch ?Etcd 中服務的容器應用狀態,一旦有改動,就生成新的LB 配置文件,并 reload LB 程序。這也印證了我們堅持的一點,系統中所有的組件只做一件事情,而且把這件事情做到極致。
假如說我們現在有三個 md2html 實例,當某一個實例掛了,監控系統檢查到了相關問題,知道它掛了,這時監控系統會兩件事情,把它掛的消息通知到 ETCD,推送到ETCD 后,confd 會自動 reload LB,實現 LB 系統的自動切換。另外就是發送通知給運維人員,好讓運維查出系統的問題,從而做出響應。
我們搭建一個 Docker RegistryV1 版本,現在已經發布了V2 版本,Docker 官方 V1 和 V2 版本不兼容,V2 也改了名字,叫做 Distribution。我們用到現在沒出特別大的問題,完全沒有激發我們升級新版本的動力,因為V1用得挺好的。
Docker 網絡,Host 模式,優點在于性能高,平滑。如果不用Host的模式,用 NAT 模式會非常痛苦,NAT 模式雖然安全,但是對于私有云內部來講沒有危險的應用,所有程序都是自己寫的,沒有不安全的,就算它不安全,你之前沒有用 Docker 的時候它也是這樣,所以用這個 Host 模式并沒有增加不安全度。最后是 Docker 日志,我們之前踩了一些坑,現在的做法是讓它直接寫到宿主機的日志文件里。
我們的架構接下來的改進方向是如下幾個點:
Job-Tool 進化成 Job DashBoard ,集成監控(cAdivsor),日志(ELK)等功能
利用監控系統的硬件指標,根據業務用量實現自動擴容,縮容
分析各個業務對硬件資源的使用量和高低峰,設計混布實現提升硬件使用率
Docker image 的構建和管理
動態調整 container 的資源限制
吐槽一下Docker的問題。Dockerfile 有點用,但沒什么大用,就是幾句話的問題非要編譯那么大的鏡像,改一行配置都需要重新編譯一個 image。Docker Daemon,很不穩定,我們出的很多問題都是它導致的,它功能太多,很多問題也就是他這些無用的功能導致,我們認為 Docker daemon 只需要做幾件簡單的事情,幫你管理容器,起、停、刪除就完了。Docker 官方最近剛推出了一個 ContainerD,就是一個簡化版的 Docker Daemon,基于 RunC 的,就非常符合我們對于 Container 管理的看法。
我們之前踩了兩個比較大的坑,一個是容器標準輸出輸出大量數據,會導致內存泄露,從而導致 Docker Daemon crash。另外一個是Docker Daemon 在頻繁創建刪除容器(每天幾十萬個)會出現性能嚴重下降等問題,只能重啟 Docker Daemon。標準輸出問題,必須要滿足的兩個條件是輸出數據量大、輸出速度快。
這里列出了我們關于標準輸出問題的簡易重現方式和最終 Docker 的修復方案。
重現方式一: docker run ubuntu yes “something long”
重現方式二:docker run -i ubuntu dd if=/dev/zero of=/proc/self/fd/1 bs=1M count=1000
Issue: https://github.com/docker/docker/issues/14460
Fix By: https://github.com/docker/docker/pull/17877
最后,關于并發性能問題,測試環境比較復雜,還在進一步研究中,歡迎各位來 Coding.net 冒泡 共同探討。
謝謝大家。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/26495.html
摘要:大會是由國內容器社區組織的專為一線開發者和運維工程師設計的頂級容器技術會議,會議強調實踐和交流,話題設置圍繞容器運維云計算等技術領域,力求全方位多角度為參會者解讀容器技術。 @Container大會是由國內容器社區 DockOne 組織的專為一線開發者和運維工程師設計的頂級容器技術會議,會議強調實踐和交流,話題設置圍繞容器、運維、云計算等技術領域,力求全方位、多角度為參會者解讀容器技術...
摘要:英特爾創新的總結了數字化變革的個要素,混合云虛擬化網絡面向未來的存儲分析和數據戰略及多層安全性。各地的企業紛紛采用混合云加快業務創新和數據中心轉型。2018年6月28日,在北京金隅喜來登,英特爾、聯想以及企業用戶圍繞’變數字勢能為企業動能這一主題展開演講和討論。與會嘉賓一起探討了如何通過基于至強可擴展平臺的豐富產品技術組合為各行業用戶提供一個完善的混合云解決方案,來解決企業用戶傳統業務和互聯...
摘要:浪潮云計算產品部副總經理劉曉欣近日,版本正式發布,其在可管理性彈性可擴展性等方面的持續提升,充分證明了正在日趨成熟與完善,已然成為業界公認的成功開源項目之一,在業內更是成了無可厚非的私有云實施標準。浪潮云計算產品部副總經理劉曉欣近日,OpenStack ?Queens版本正式發布,其在可管理性、彈性、可擴展性等方面的持續提升,充分證明了OpenStack正在日趨成熟與完善,OpenStack...
摘要:不過,云來了,以阿里云為代表的云服務商攜云原生數據庫發起了新一輪挑戰。實際上,阿里云數據庫技術也得到國際咨詢機構的認可,在數據庫魔力象限中,阿里云成為國內首個入選的科技公司。第三個是數據的安全隱私保護,這是阿里云數據庫一直不敢放松的。數據庫市場形成今天的格局已經很久了,商業數據庫為王,這幾乎沒有變過。不過,云來了,以AWS、阿里云為代表的云服務商攜云原生數據庫發起了新一輪挑戰。與以往歷次的挑...
摘要:發現云計算領導者的秘密借助云改變商業策略圖為大中華區全球信息科技服務部戰略及市場總經理石峰同時陶弢也很客觀地指出,從整體上來看云計算助力企業業務增長還處于比較早期的階段。本文原標題發現云計算領導者的秘密借助云改變商業策略本文轉載自 目前對云計算的態度和發展上,國家政策是一面地傾斜、IT廠商是全業務滲透,而企業用戶呢?在云計算剛起來時,我們就做過暢想,諸如云計算會徹底變 革企業的IT架構、云計...
閱讀 2570·2021-11-22 09:34
閱讀 931·2021-11-19 11:34
閱讀 2800·2021-10-14 09:42
閱讀 1471·2021-09-22 15:27
閱讀 2385·2021-09-07 09:59
閱讀 1731·2021-08-27 13:13
閱讀 3431·2019-08-30 11:21
閱讀 770·2019-08-29 18:35