付琳琳 鄒素雯



摘? ?要:隨著分布式系統和云計算的飛速發展,微服務和容器的應用越來越廣泛,通過將微服務容器化實現自動化部署和持續集成,從而簡化部署和加快開發也是企業應用的研究重點。通過對微服務特性和容器核心技術的研究,給出了微服務容器化部署的理論支持,并對幾種常見的微服務部署模式進行了比較,最后著重介紹了微服務容器化部署模式的一般流程和總體設計方案,包括微服務應用的開發、容器鏡像的構建、管理和容器部署編排,并給出了微服務容器鏡像構建的優化方案,對企業的應用開發部署具有一定的理論參考價值。
關鍵詞:微服務;容器;鏡像;微服務部署;鏡像優化
中圖分類號:TP399? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 文獻標識碼:A
Research on Container Deployment of Microservices
FU Lin-lin1?覮,ZOU Su-wen2
(1. Wuhan Research Institude of Posts and Telecommunications,Wuhan ,Hubei 430074,China;
2. Wuhan Fiberhome Information Integration Technology Company Limited,Wuhan,Hubei 430074,China)
Abstract:With the development of distributed systems and cloud computing,the application of micro-services and containers is becoming more and more extensive.The automated deployment and continuous integration through microservices containerization to simplify deployment and accelerate development is also the focus of enterprise researches. Based on the research of the characteristics of microservices and the core technology of docker,this paper gives the theoretical support for the container deployment of microservices,than compares several common microservices deployment patterns. Finally,the general process and overall design scheme of microservices container deployment mode are introduced,including the development of microservices application,the construction of container image,the management and the arrangement of container deployment. And put forward some optimization scheme for microservices container image construction,which has certain theoretical reference value for enterprise application development deployment.
Key words:microservices;docker;image;deployment of microservices;image optimization
隨著計算機技術的發展,軟件架構從單體到微服務,從垂直到分布式,不斷的更新發展以適應不斷龐大的業務需求。其中微服務架構從提出到現在一直備受企業和開發人員的關注,相關開源項目的社區也極為活躍,如何更好的進行微服務應用的業務拆分,穩定而快捷的服務通信,使整個項目開發迭代快,穩定高可用,部署維護成本低,一直都是開發人員的研究重點,而容器等新的新技術產生,更是為微服務開發、部署、維護等過程提供了新的思路。
1? ?微服務和容器
1.1? ?微服務概述
不同于單體應用,微服務是一種將大型應用系統進行由大到小拆分的架構風格,根據業務功能將其拆分成多個相互獨立的小型服務模塊,各自擁有自己的數據存儲系統、開發模式并獨自運行,然后通過某些通信協議,如基于HTTP的RESTful API進行服務間的通訊[1]。
微服務的理念至提出到現在發展迅速,Martin Fowler還總結出了微服務架構的九大特性即服務組件化、按業務組織團隊、做產品的態度、智能端點與啞管道、去中心化治理、去中心化管理數據、基礎設施自動化、容錯設計以及演進式設計[2]。通過對微服務特性的分析,可以得到微服務具有開發效率高,迭代周期短,擴展能力強,維護成本低的優點,但也帶來了分布式系統的通信和保持數據庫一致性的復雜度,增加了測試部署運維的開銷。
1.2? ?容器概述
容器是一種集裝箱技術,通過將應用“裝”起來實現應用之間的相互隔離。Docker 是一個開源的容器引擎,在 Linux 容器(Linux Containers,LXC)技術的基礎上,進一步封裝了容器的一些操作接口提供給開發者管理和使用容器[4]。從本質上來說,
Docker其實是運行在宿主機上的進程,其核心技術主要是控制組(Cgroups)和命名空間(Namespace)。
Cgroups技術用來制造約束,主要提供限制資源使用,優先級控制,審計功能,掛起、恢復進程等功能[5]。Namespace技術是使得每個容器在不同硬件資源的使用方面都有自己不同的命名空間,例如如下的一些資源:內核、內存、CPU、網絡、文件系統、進程等[6],使得進程之間運行互不干擾。這種技術解決了如何確保容器使用者資源的隔離問題。
而這兩個技術提供的資源分配和監控功能正好可以滿足微服務的獨立部署原則。綜上所述,容器技術,支持微服務的快速部署。
2? ?微服務部署模式
微服務的部署模式通常可分為單主機多服務實例模式和每個主機一個實例模式[7]。
2.1? ?單主機多服務實例模式
單主機多服務實例模式是應用程序部署的傳統方式,是指在一個或者多個物理主機或虛擬主機上運行多個服務實例,每個服務實例運行在主機的不同標準端口。其結構圖如圖1所示,每個主機上有多個服務實例。
單主機多服務模式因為共享服務器及其操作系統,資源使用率較高且部署啟動較快,但服務實例之間的隔離性較差,且會導致因資源搶奪而服務崩潰的情況,同時對于不同技術語言開發的微服務,環境信息的錯綜復雜也會增加部署的錯誤風險[8]。
2.2? ?一個主機一個服務實例模式
微服務部署的另一種方式是使用一個主機一個服務實例(Service Instance per Host)模式。這種模式又可以分為兩種不同形式:每個虛擬機一個服務實例模式和每個容器一個服務實例模式。
前者是將每個服務打包成一個虛擬機鏡像,通過啟動鏡像創建一個VM虛擬機,作為一個服務實例,如Amazon EC2 AMI,這種模式也是Netflix部署視頻流服務的主要方式[9]。因為每個虛擬機擁有各自的CPU和內存,所以這種模式很好的實現了服務間的資源隔離,并且其封裝技術,使部署變得更加簡單,甚至可以上云實現負載均衡和自動擴縮的功能,從而使應用的部署更加可靠。但這種方案資源的利用率較低。
后者則是將每個服務實例運行在一個容器中,而容器作為輕量級應用,鏡像構建和運行速度極快,甚至可以在一個物理或者虛擬機上運行多個容器,在資源隔離和利用上優于前兩種方式,并且可以使用容器集群管理工具類進行容器的管理,極大的簡化了部署流程。
因此基于容器的部署模式是三種部署方式中相對最好的方式,下面則提出容器部署微服務的一般流程。
3? ?微服務容器化部署
3.1? ?微服務容器化部署整體流程
首先給出微服務容器化部署的一般方案設計,其流程圖如圖2所示。
主要分為微服務開發、微服務容器鏡像構建、微服務容器鏡像管理、微服務容器編排管理四個步驟。首先利用微服務框架,例如SpringCloud,進行微服務應用的開發,通過框架自帶的組件機制進行服務管理,保證應用的高可用性。其次將每個微服務打包,構建容器鏡像,鏡像可以推送到創建的私有鏡像倉庫進行鏡像的存儲管理,每次部署時只需從倉庫拉取相關的鏡像,最后通過選擇合適的容器編排工具,將容器運行到不同虛擬機或者物理機集群上,并對容器間的通信和容器的啟停進行配置,使不同微服務的實例在容器中運行并通信良好,并實時監控容器集群的運行狀態,從而保證整個應用的正常運行。
3.2? ?微服務容器化部署流程步驟
3.1給出了容器化部署微服務的整體流程設計,可大致分為微服務開發、微服務容器鏡像構建、微服務容器鏡像管理、微服務容器編排管理四個步驟。下面對此四個步驟進行具體的研究分析,并給出相應的技術方案。
3.2.1? ?微服務應用開發
隨著企業和開發者對微服務的不斷研究,微服務開發框架層出不窮,如SpringCloud,Dubbo等,其豐富的配置管理、服務治理、斷路器、智能路由、微代理、控制總線、全局鎖、決策競選、分布式回話和集群狀態管理等操作為構建微服務系統提供了簡單的開發模式[3]。
企業或者個人進行應用開發時,可以通過對待開發應用的分析研究,拆分業務服務,選擇合適的微服務框架進行應用開發,充分利用其自帶的豐富組件,如服務注冊和發現、網關API、負載均衡、容錯監控或其他第三方管理插件,通過簡單的配置實現微服務應用的快速開發和系統管理。
3.2.2? ?微服務容器鏡像構建
鏡像構建是將開發的微服務生成可以運行的容器鏡像。Docker中通常有兩種方法來構建新鏡像。第一種是通過commit命令將一個正在運行的容器提交為一個新鏡像,第二種為編寫Dockerfile文件,接著使用build命令構建一個容器鏡像。
容器鏡像實際上是類似于文件系統的分層機構,而從鏡像運行容器,會在該鏡像頂部加載一個可讀寫、初始值為空的文件系統,稱為容器層[10]。當容器內發生變化時,這些變化都會標記應用到這一層,不影響下面已經存在的層,比如在容器中刪除一個文件,也只是頂層標記文件刪除,但文件其實依然存在并占用鏡像空間,而從容器構建鏡像,即方法一,本質上是把容器頂層固化,生成一個新的鏡像,因此每修改一次,鏡像就會多一層,鏡像體積就會增大。長此以往,鏡像將變得越來越臃腫。而且當此鏡像變化時,依賴此鏡像的子容器鏡像也要隨之重新構建。若沒有編寫自動化構建腳本,而是手工構建的,那么不可避免存在許多重復的構建工作。因此使用過程中,并不推薦使用第一種方法來構建鏡像。
第二種通過Dockerfile來快速構建自定義鏡像則用途廣泛,其中,Dockerfile是一個文本格式的配置文件,一般分為基礎鏡像信息、維護者信息、鏡像操作指令、容器啟動時執行指令這四個部分[11]。各部分常用指令如表1所示.
通過對上述四個部分進行編寫后,即完成了Dockerfile的編寫,然后通過docker build命令創建鏡像。該命令的執行過程是通過讀取指定路徑下的Dockerfile,然后將該路徑下的全部內容發送給Docker服務端,由服務端來創建鏡像[12]。
3.2.3? ?微服務容器鏡像優化
由于微服務鏡像不僅包含微服務自身的開發代碼,還包括代碼運行和依賴的眾多環境信息,因此構建的鏡像往往體積都很龐大,而過大的鏡像不僅占用資源空間且每次部署拉取鏡像時間都較長,而精簡的Docker鏡像可以減少構建時間、減少磁盤使用量、減少下載時間、提高安全性以及提升部署效率等。因此下面提出幾種優化方案來減小鏡像體積:
一、使用alpine版本的基礎鏡像
Alpine是包含了基本工具的輕量級Linux發行版,鏡像大小大概只有4~5M,很多語言和框架都有基于alpine制作的基礎鏡像。如Java的SpringBoot應用,則有openjdk:8-jdk-alpine,openjdk:8-jre-alpine等。其中openjdk:8-jre是309MB,而openjdk:8-jre-alpine是107.8MB。可見鏡像大小幾乎縮減了一半多。
二、串聯Dockerfile中的操作指令
Dockerfile的每條指令都會產生一個文件層,因此我們可以通過運算符&&和\來實現指令的合并,最大化利用緩存減小鏡像體積。通過實驗發現鏡像體積得到了有效的縮減。
3.2.4? ?微服務容器鏡像管理
至此,微服務容器鏡像已經構建成功,但往往一個完整的應用系統包括不止一個微服務,即對應著多個鏡像,因此還需要對構建的容器鏡像進行相應的存儲管理。DockerHub是Docker官方認證的DockerRegistry,上面不僅存放著許多常用的優秀鏡像,還提供認證、工作組結構、工作流工具、構建觸發器等工具來簡化工作[13]。
因此,對于每一個為服務應用,首先在Docker Hub 上創建相應的私有倉庫,然后將應用下所有微服務構建好的容器鏡像推送到倉庫內,進行存儲和管理。同時可以隨時隨地拉取相應的鏡像,搭建新的開發、測試環境。
3.2.5? ?微服務容器編排
通常拉取鏡像進行容器啟動后,該微服務就會運行到新創建的容器進程中。由于應用包括多個微服務容器,容器的啟動順序、運行容器間的通信,容器實例的運行狀態都需要配置和管理,若都人工配置和操作,不免增加了許多部署人員和維護人員的工作量和復雜度,因此需要選用容器編排工具進行容器的管理和調度。
隨著容器的應用越來越多,容器編排和集群管理工具也層出不窮,如Docker Compose,DockerSwarm和Kubernetes。其中DockerCompose操作最容易,只需要編寫一個文件,即docker-compose.yml,在此文件中定義應用程序的服務、聲明好要啟動的容器,配置一些參數,然后運行docker-composeup指令便可,但是需要注意到,Docker-Compose只能管理當前主機上的Docker,并不能跨主機去啟動其他主機上的Docker容器[14]。
然而現在很多應用服務,比如云應用產品,往往都是多主機集群,這種情況Compose就不再適用,DockerSwarm和Kubernetes作為容器集群管理工具,就能發揮各自的特長。其中Kubernetes是Google的一個開源項目,基于其多年大規模容器管理技術,具有完備的集群管理能力,包括透明的服務注冊和發現機制、可擴展的資源自動調度機制、強大的故障發現和自我修復能力、多粒度的資源管理能力、負載均衡,涵蓋了包括開發部署測試運維監控在內的多個環節[15]。可實現大規模、分布式、高可用的 Docker 集群。
因此,要依據項目的大小和適用場景,選擇合適的容器管理工具,通過配置文件的編寫,進行微服務容器的部署和管理,使微服務實例正常運行于各自的容器中并保持良好的交互,從而使整個系統應用正常運行,完成微服務的容器化部署。
4? ?結? ?論
容器化部署作為微服務的理想選擇,單個容器不需要托管一個完整的應用,只需要托管應用程序中的一部分--一個微服務。通過使用容器技術,部署多個微服務的工作將變得更為簡便,簡單的微服務部署可直接通過 docker 命令即可實現,省掉了繁瑣的環境搭建、依賴管理等。對于大型應用,也可利用各種編排工具實現一鍵部署。在服務隔離、升/降級等方面具有相當的優勢。在開發階段,容器化也是 DevOps 的最佳搭檔,通過自動化部署、持續集成等手段,可以有效降低集成成本,降低 bug 率。同時,也可保證始終有可用的版本,且各個版本都可測試,可追溯,可回滾。容器化部署微服務已經在企業開發部署應用中扮演了重要的角色。
參考文獻
[1]? ? FOWLER M.Microservice[EB/OL]. http://martinfowler.com/articles/microservices.html,2014.
[2]? ? YU Y. A microservice based reference architecture model in the context of enterprise architecture[A]. Proceedings of 2016 IEEE Advanced Information Management,Communicates,Electronic and Automation Control Conference(IMCEC 2016)[C]. IEEE Beijing Section、Global Union Academy of Science and Technology、Chongqing Global Union Academy of Science and Technology,2016:5.
[3]? ? 王方旭.基于Spring Cloud和Docker的微服務架構設計[J].中國信息化,2018(03):53—55.
[4]? ? 楊保華,戴玉劍,曹亞侖.Docker技術入門與實踐[M].北京:機械工業出版社,2014.
[5]? ?Redhat. Introduction to control groups[EB/OL].https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/ Resource_Management_Guide/ch01.html,2016.
[6]? ?Linux.Namespace[EB/OL]. http://man7.org/linux/man—pages/man7/namespaces.7.html,2016.
[7]? ? 譚一鳴. 基于微服務架構的平臺化服務框架的設計與實現[D]. 北京:北京交通大學,2017.
[8]? ? 劉輝軍,劉培鋒,邱鈺鋒,等. 基于開源框架及容器技術的微服務架構研究[J].電力信息與通信技術,2018,16(06):90—94.
[9]? ? 劉鵬. 云計算[M]. 北京:電子工業出版社,2011.
[10]? 馬雄. 基于微服務架構的系統設計與開發[D]. 南京:南京郵電大學,2017.
[11]? 李紅健.微服務架構和容器技術應用分析[J]. 無線互聯科技,2018,15(08):134—135.
[12]? 李蘇璇.基于微服務架構的SaaS應用構建方法研究[D]. 廣州:華南理工大學 2016.
[13]? 周立. SpringCloud與Docker微服務架構實戰[M].北京:電子工業出版社,2017.
[14]? MARKUS L. Docker compose for the simple deployment of an integrated drug target screening platform[J]. Journal of Integrative Bioinformatics,2017,14(2):98—102.