《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 嵌入式技術(shù) > 業(yè)界動(dòng)態(tài) > 云計(jì)算核心技術(shù)docker的探索

云計(jì)算核心技術(shù)docker的探索

2016-07-08

  首先通過(guò)一個(gè)簡(jiǎn)單的場(chǎng)景來(lái)看一下為什么docker這么火?

  開(kāi)發(fā)人員在開(kāi)發(fā)的時(shí)候是有一套開(kāi)發(fā)環(huán)境,包括運(yùn)行的操作系統(tǒng),依賴的服務(wù)比如weblogic,java,一些特定的配置,比如jvm大小 ,字符集,操作系統(tǒng)內(nèi)核參數(shù)等,然后就是應(yīng)用代碼了。當(dāng)開(kāi)發(fā)完成后,開(kāi)發(fā)人員就把代碼打包發(fā)送運(yùn)維人員到生產(chǎn)上部署。運(yùn)維人員就需要搭建一個(gè)和開(kāi)發(fā)環(huán)境一樣的生產(chǎn)環(huán)境,安裝操作系統(tǒng) ,weblogic,java,根據(jù)基線配置一些參數(shù),過(guò)程非常的繁瑣。搭建完成后還是可能因?yàn)閮蓚€(gè)環(huán)境細(xì)微的不同都有可能導(dǎo)致應(yīng)用程序的部署失敗。做為運(yùn)維人員常常聽(tīng)到開(kāi)發(fā)的抱怨,在我的環(huán)境里是正常的啊,怎么到你的環(huán)境就不行了呢!

  在傳統(tǒng)的部署模式下,如果有非常多的服務(wù)器,運(yùn)維工程師需要在每一臺(tái)服務(wù)器上進(jìn)行相當(dāng)復(fù)雜的操作才能夠完成部署。安裝->配置->部署。但是docker的出現(xiàn)顛覆了這種傳統(tǒng)的模式。我們看一下,docker只需要把整個(gè)開(kāi)發(fā)環(huán)境做打包成一個(gè)docker image,也就是docker鏡像給運(yùn)維團(tuán)隊(duì),而運(yùn)維團(tuán)隊(duì)直接運(yùn)行就可以了,整個(gè)過(guò)程就變成打包,傳送,運(yùn)行即可,非常的簡(jiǎn)單。因?yàn)閐ocker鏡像包含了所有的環(huán)境依賴關(guān)系,可以保證開(kāi)發(fā)與生產(chǎn)環(huán)境一致,對(duì)于開(kāi)發(fā)和運(yùn)維工作,docker技術(shù)可以讓開(kāi)發(fā)和運(yùn)維豁免很多預(yù)想之外的工作和相互推脫。此外,容器可以重復(fù)運(yùn)行在任何地方,簡(jiǎn)單化了運(yùn)維人員的工作 。 Docker的這種在安全、可重復(fù)的環(huán)境中可移植,跨平臺(tái)的快速部署軟件的方式也方便做持續(xù)集成,所以說(shuō)docker出現(xiàn)拉開(kāi)了基于云計(jì)算平臺(tái)發(fā)布產(chǎn)品方式的變革序幕,是運(yùn)維人員的解放,廣受開(kāi)發(fā)者和運(yùn)維人員的歡迎。

  Docker ,除了是云時(shí)代的應(yīng)用交付方式的變革,運(yùn)維人員的解放,和微服務(wù)的結(jié)合使用還將顛覆傳統(tǒng)的軟件架構(gòu)。我們先看一下單塊架構(gòu)和微服務(wù)架構(gòu)的區(qū)別。單塊架構(gòu)就是一個(gè)實(shí)例里包含了多個(gè)業(yè)務(wù)模塊,如果說(shuō)電信行業(yè)的登陸,開(kāi)戶,繳費(fèi),話費(fèi)查詢等功能都運(yùn)行在一個(gè)實(shí)例里,這樣做有什么缺點(diǎn)呢?第一,隨著業(yè)務(wù)的增長(zhǎng),這個(gè)單塊會(huì)越來(lái)越大,變得很復(fù)雜,啟動(dòng)的時(shí)間也會(huì)越來(lái)越長(zhǎng),如果有bug要排查起來(lái)也會(huì)非常的復(fù)雜。第二,如果其中某一個(gè)業(yè)務(wù)模塊異常將會(huì)影響所有其他的業(yè)務(wù)模塊,造成整個(gè)業(yè)務(wù)系統(tǒng)癱瘓。第三,有些功能業(yè)務(wù)壓力大,有些功能業(yè)務(wù)壓力小,因?yàn)槔壴谝黄穑贾荒芤黄鹪黾踊驕p少,這樣就會(huì)造成資源的浪費(fèi)。如果某個(gè)功能業(yè)務(wù)4個(gè)實(shí)例已經(jīng)不能支撐了,而其他業(yè)務(wù)模塊其實(shí)并沒(méi)有什么壓力,但是為了業(yè)務(wù)大的功能模塊的業(yè)務(wù)壓力,就需要增加一個(gè)實(shí)例。而微服務(wù)架構(gòu)就可以解決這三個(gè)問(wèn)題,把功能按模塊運(yùn)行在不同的容器里,相互不影響,各用各的資源,可以根據(jù)實(shí)現(xiàn)的業(yè)務(wù)壓力而來(lái)啟動(dòng)相應(yīng)的實(shí)例數(shù)。

  Docker的細(xì)粒度松耦合能夠讓我們用一個(gè)Docker容器裝載一個(gè)場(chǎng)景功能,讓每個(gè)Docker中運(yùn)行一個(gè)微服務(wù),為微服務(wù)應(yīng)用程序創(chuàng)建出高效的分布式模型,從而順利實(shí)現(xiàn)微服務(wù)概念的現(xiàn)實(shí)轉(zhuǎn)化。

  那么docker究竟是什么呢?

  首先我們來(lái)看一下docker的標(biāo)識(shí),是一個(gè)大鯊魚(yú)馱著一堆集裝箱在海上航行。無(wú)邊無(wú)盡的海就是云了,大鯊魚(yú)貨輪就是云計(jì)算平臺(tái)了,docker是集裝箱。集裝箱將貨運(yùn)目標(biāo)標(biāo)準(zhǔn)化,Docker 將應(yīng)用程序標(biāo)準(zhǔn)化,集裝箱里面裝的以是任意類型的App,各自在自己的集裝箱里運(yùn)行,相互隔離,共用大鯊魚(yú)貨輪的資源,這種封裝的集裝箱可以放到任何的平臺(tái)上去運(yùn)行。非常形像的展示了docker的特性: Build, Ship and Run Any App, Anywhere!在任何平臺(tái)運(yùn)行任何應(yīng)用!

  Docker的英文本意是碼頭工人,也就是搬運(yùn)工,這種搬運(yùn)工搬運(yùn)的是集裝箱。

  Docker是PasS提供商DoctCloud開(kāi)源的一個(gè)基于LXC的高級(jí)容器引擎。

  Docker是一個(gè)由GO語(yǔ)言寫(xiě)的程序運(yùn)行的“容器” 。

  Docker把App裝在Container內(nèi),通過(guò)Linux Container技術(shù)的包裝將App變成一種標(biāo)準(zhǔn)化的、可移植的、自管理的組件(集裝箱)。這種組件可以在你的電腦上開(kāi)發(fā)、調(diào)試、運(yùn)行,最終非常方便和一致地運(yùn)行在測(cè)試環(huán)境和生產(chǎn)環(huán)境下。

  Docker誕生的時(shí)間并不長(zhǎng),2013年3月發(fā)布0.1版本,到現(xiàn)在也才三年多,現(xiàn)在最新的版本是1.12,還在不斷的完善中。但docker并不是一種新技術(shù),而是基于Linux內(nèi)核容器技術(shù)LXC的為適應(yīng)時(shí)代需要、標(biāo)準(zhǔn)化IT結(jié)構(gòu)的新方式,一種沖擊虛擬化的新玩法。

  Docker解決LXC的兩個(gè)問(wèn)題集成度低,需要手工準(zhǔn)備容器內(nèi)文件系統(tǒng)的兩個(gè)問(wèn)題。

  Docker的整體結(jié)構(gòu)包括兩個(gè)部分,Docker Hub 和 Docker 引擎組成。Docker Hub提供API和云服務(wù)來(lái)發(fā)布基于Docker的應(yīng)用程序。Docker Hub 是Docker 官方提供的容器鏡像倉(cāng)庫(kù),有大量的軟件公司在其中維護(hù)自己的官方軟件。目前已經(jīng)有1萬(wàn)4千多個(gè)基于Docker的應(yīng)用程序package,從操作系統(tǒng)的廠商,,云計(jì)算IaaS服務(wù)商,大數(shù)據(jù),像各種各樣的編程語(yǔ)言等等各種各樣的軟件,包含最流行的13個(gè)應(yīng)用-CentOS, MongoDB, MySQL, Nginx, Redis, Ubuntu, and WordPress 等等,在云計(jì)算產(chǎn)業(yè)迅速發(fā)展的環(huán)境下?lián)碛性絹?lái)越豐富的生態(tài)系統(tǒng)。后者運(yùn)行在宿主機(jī)上,是一個(gè)可以移植的,輕量的應(yīng)用運(yùn)行環(huán)境和打包工具,負(fù)責(zé)構(gòu)建、運(yùn)行和分發(fā) Docker 容器。簡(jiǎn)單來(lái)說(shuō),Docker Hub 是資源存放的云平臺(tái),Docker 引擎是使用云上資源資源的終端,任何人都能到云上下載需要的資源,這就是容器云+端開(kāi)放平臺(tái)的模式。

  下面講一下在docker的容器云+端開(kāi)放平臺(tái)結(jié)構(gòu)下,應(yīng)用程序的生命周期。先在本地基于Docker引擎構(gòu)建和打包應(yīng)用程序,然后用DockerHub云服務(wù)將程序(集裝箱)放到DockerHub,希望運(yùn)行此應(yīng)用的平臺(tái)再去下載和運(yùn)行。

  Docker號(hào)稱Build once,run anywhere,就是鏡像一次構(gòu)建,容器到處運(yùn)行。就像這個(gè)圖上所示,當(dāng)使用Docker引擎構(gòu)建好應(yīng)用程序后放到DockerHub,開(kāi)發(fā),測(cè)試人員都可以獲取,拿來(lái)直接運(yùn)行,可以運(yùn)行在物理平臺(tái)上,也可以運(yùn)行的虛擬平臺(tái)上。整個(gè)過(guò)程非常的簡(jiǎn)單方便,在這種模式下極大地提高了開(kāi)發(fā)部署效率。

  簡(jiǎn)單介紹docker使用到的部分核心技術(shù),但不做深入探究,因?yàn)槊恳粋€(gè)技術(shù)都是一個(gè)獨(dú)立的項(xiàng)目,了解一下核心技術(shù)的作用就可以了。前面說(shuō)了,docker是基于LXC的,而LXC的核心就是namespaces,容器隔離和cgroups,資源控制。每個(gè)用戶實(shí)例之間相互隔離, 互不影響。 一般的硬件虛擬化方法給出的方法是VM,而LXC給出的方法是container,更細(xì)一點(diǎn)講就是namespace。

  PID,IPC,Network等系統(tǒng)資源不再是全局性的,而是屬于某個(gè)特定的Namespace。通過(guò)使用namespace對(duì)cpu、內(nèi)存、網(wǎng)絡(luò)和文件系統(tǒng)的隔離,在這種情況下一個(gè)容器不會(huì)影響另一個(gè)容器的資源。不同 namespace 中可以有相同pid,比如說(shuō)容器A里有個(gè)進(jìn)程號(hào)為123,在容器B里也可以存在一個(gè)進(jìn)程號(hào)為123。每一個(gè)docker容器都有自己的Namespace,在docker用戶層只能看到屬于自己namespace下的資源。對(duì)宿主機(jī)來(lái)說(shuō),docker就是一個(gè)進(jìn)程,但每個(gè)namespace看上去就像一個(gè)單獨(dú)的Linux系統(tǒng)。

  cgroups控制組可以提供對(duì)宿主機(jī)上的共享資源內(nèi)存、CPU、磁盤(pán) IO 等資源的限制和審計(jì)管理,限制相應(yīng)進(jìn)程或一組進(jìn)程使用的系統(tǒng)資源,實(shí)現(xiàn)了對(duì)資源的配額和度量。只有能控制分配到容器的資源,才能避免當(dāng)多個(gè)容器同時(shí)運(yùn)行時(shí)的對(duì)系統(tǒng)資源的競(jìng)爭(zhēng)。

  AUFS則可以讓大家像玩樂(lè)高那樣玩 Docker。我們先看一下它的結(jié)構(gòu):容器在最頂層,是writable,其下所有層都為readonly,將readonly的文件系統(tǒng)層稱作“image”,每一層鏡像的下面稱為其父鏡像,Docker鏡像位于bootfs之上,第一層鏡像為Base Image。因此想要從一個(gè)image啟動(dòng)一個(gè)container,docker會(huì)先加載其父image直到base image,用戶的進(jìn)程運(yùn)行在writeable的layer中。得益于AUFS的特性,每一個(gè)對(duì)readonly層文件/目錄的修改都只會(huì)存在于上層的writeable層中。這樣由于不存在競(jìng)爭(zhēng),多個(gè)container可以共享readonly的layer。所以docker將readonly的層稱作 "image"——對(duì)于container而言整個(gè)rootfs都是read-write的,但事實(shí)上所有的修改都寫(xiě)入最上層的writeable層中,image不保存用戶狀態(tài),可以用于模板、重建和復(fù)制。

  1. 節(jié)省存儲(chǔ)空間:多個(gè)container可以共享base image存儲(chǔ)

  2. 快速部署:如果要部署多個(gè)container,base image可以避免多次拷貝

  3. 內(nèi)存更?。阂?yàn)槎鄠€(gè)container共享base image, 以及OS的disk緩存機(jī)制,多個(gè)container中的進(jìn)程命中緩存內(nèi)容的幾率大大增加

  4. 升級(jí)更方便:相比于 copy-on-write 類型的FS,base-image也是可以掛載為可writeable的,可以通過(guò)更新base image而一次性更新其之上的container

  5. 允許在不更改base-image的同時(shí)修改其目錄中的文件:所有寫(xiě)操作都發(fā)生在最上層的writeable層中,這樣可以大大增加base image能共享的文件內(nèi)容。

  在這里我們講了兩個(gè)概念,容器和鏡像,大家可能還不是很理解,下面就給講一下docker的三大核心概念。

  docker三大核心概念是倉(cāng)庫(kù),鏡像,容器,從這個(gè)圖表我們可以知道,倉(cāng)庫(kù)里有鏡像,容器運(yùn)行在鏡像之上。

  倉(cāng)庫(kù)類似于代碼倉(cāng)庫(kù),是Docker集中儲(chǔ)存鏡像文件的場(chǎng)所。分為公開(kāi)倉(cāng)庫(kù)(Public)和私有倉(cāng)庫(kù)(Private)兩種形式。最大的公開(kāi)倉(cāng)庫(kù)就是前面提到的dockerHub,當(dāng)然,也可以在局域網(wǎng)內(nèi)構(gòu)建私有倉(cāng)庫(kù)。

  鏡像類似于虛擬機(jī)的鏡像,可以理解為面向Docker的只讀模板,包含了文件系統(tǒng)。鏡像是創(chuàng)建Docker的基礎(chǔ),所有的docker容器都是基于鏡像運(yùn)行。

  容器就是前面提到的集裝箱,是從鏡像創(chuàng)建的應(yīng)用實(shí)例,可以將其啟動(dòng)、開(kāi)始、停止、刪除、而這些容器都是相互隔離、互不可見(jiàn)的。

  鏡像相應(yīng)于是java代碼寫(xiě)的公用類,而容器是則是基于這個(gè)代碼運(yùn)行的實(shí)例,每個(gè)人都可以調(diào)用這個(gè)公用類,并且可以根據(jù)自己的需求傳入不同的參數(shù),形成不同內(nèi)容的實(shí)例,比如我們可以通過(guò)傳參指定實(shí)例名,啟動(dòng)基本weblogic鏡像容器,在同一臺(tái)機(jī)器上就可以基于同一個(gè)鏡像啟動(dòng)很多個(gè)實(shí)例名不一樣的進(jìn)程。但這些參數(shù)不會(huì)改變?cè)即a,所有的變更都只存于容器內(nèi)。所以說(shuō)鏡像是只讀的,而容器是可寫(xiě)的。三個(gè)概念之間究竟是怎么相互存在,相互影響的呢?我們可以通過(guò)docker的生命周期來(lái)進(jìn)一步了解。

  以鏡像為基礎(chǔ),我們來(lái)看一下docker的生命周期。在我們的本地計(jì)算機(jī)上,我們可以從docker倉(cāng)庫(kù)把鏡像下載下來(lái),也可以把本地的鏡像上傳到docker倉(cāng)庫(kù)。可以為鏡像的不同版本打上標(biāo)簽tag用來(lái)區(qū)別。

  可以基于鏡像創(chuàng)建一個(gè)容器,也可以把運(yùn)行的容器commint成一個(gè)鏡像,而容器則可以作為一個(gè)docker實(shí)例在本地運(yùn)行,可以啟動(dòng),停止,重啟,當(dāng)然也可以刪除。我們還可以通過(guò)save把鏡像保存到一個(gè)tar包,也可以通過(guò)load加載tar包里的鏡像。我們還可以通過(guò)dockerfile來(lái)構(gòu)建一個(gè)鏡像。Docker的操作命令相對(duì)來(lái)說(shuō)還是比較簡(jiǎn)單,如果發(fā)布一個(gè)鏡像是就docker push 鏡像名,加載tar包就是docker load 包名,運(yùn)行容器docker start 容器名,掌握這個(gè)圖上的命令基本就可以玩轉(zhuǎn)Docker了。而在這個(gè)里面比較復(fù)雜的就是用dockerfile構(gòu)建鏡像了,在這個(gè)圖里我們知道可以把一個(gè)運(yùn)行的容器通過(guò)commit命令制作成一個(gè)新的鏡像,相對(duì)比較簡(jiǎn)單,但是我們更建議使用dockerfile來(lái)構(gòu)建鏡像,為什么呢?下面簡(jiǎn)單介紹一下如何用dockerfile構(gòu)建鏡像。

  先我們看一下怎么用dockerfile構(gòu)建docker鏡像。只需要在當(dāng)前目錄下創(chuàng)建一個(gè)Dockerfile,記住Dockerfile的首字母D是大寫(xiě),再使用命令build就可以創(chuàng)建新的鏡像了。

  簡(jiǎn)單講解一下Dockerfile的命令格式

  FROM <image> 設(shè)置基本的鏡像,作為Dockerfile的第一條指令。比如右邊一個(gè)圖最底下,是基于ubuntu14.04版本創(chuàng)建的

  RUN <command> 創(chuàng)建一層鏡像,RUN命令的運(yùn)行過(guò)程等于把一個(gè)運(yùn)行的容器commit為鏡像。比如右邊第二層和第三層,創(chuàng)建了兩層鏡像,第二層的鏡像是先基于第一層的鏡像啟動(dòng)一個(gè)使用ubuntur操作系統(tǒng)的容器,然后在安裝ssh服務(wù),再用commit把第二層保存為一個(gè)鏡像。而第三是基于第二層鏡像啟動(dòng)一個(gè)容器,然后安裝java,tomcat等服務(wù),再用commit保存為第三層鏡像。

  ENV <key> <value> 用于設(shè)置環(huán)境變量

  CMD指令指定你制作出來(lái)的鏡像在啟動(dòng)成容器時(shí)運(yùn)行命令的默認(rèn)的參數(shù)。一個(gè)Dockerfile里只能有一個(gè)CMD,如果有多個(gè),只有最后一個(gè)生效。docker run命令如果指定了參數(shù)會(huì)把CMD里的參數(shù)覆蓋

  ENTRYPOINT cmd param1 param2 ... 也是設(shè)置在容器啟動(dòng)時(shí)執(zhí)行命令

  COPY復(fù)制本地主機(jī)的 <src> (為Dockerfile所在目錄的相對(duì)路徑)到容器中的 <dest> 。

  EXPOSE <port> [<port>...] EXPOSE 命令可以設(shè)置一個(gè)端口在運(yùn)行的鏡像中暴露在外,這樣容器外可以看到這個(gè)端口并與其通信。

  前面我們說(shuō)了,可以像玩樂(lè)高一樣玩docker,因?yàn)槊恳粚拥溺R像都是基本父鏡像形成的,他并不關(guān)心父鏡像具體是什么。我們可以一層一層的疊加鏡像,也可以根據(jù)需要增加刪除或修改每一層鏡像,再使用docker build生成一個(gè)最終版本的鏡像。所以強(qiáng)烈推薦在生產(chǎn)中使用dockerfile來(lái)構(gòu)建鏡像,一是可以通過(guò)dockerfile來(lái)“閱讀”鏡像,看一下鏡像里都包含了什么內(nèi)容,二是在升級(jí)等需要修改鏡像的場(chǎng)景下,直接優(yōu)化dockerfile的內(nèi)容,重構(gòu)新的鏡像就可以了。

  在使用鏡像的時(shí)候?yàn)楸苊忡R像間依賴過(guò)深,建議三層,分別是基礎(chǔ)的操作系統(tǒng)鏡像、中間件鏡像和應(yīng)用鏡像,一個(gè)容器里只運(yùn)行一個(gè)服務(wù)。環(huán)境干凈,結(jié)構(gòu)簡(jiǎn)單,啟動(dòng)快速。



本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,請(qǐng)及時(shí)通過(guò)電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。