天天看點

Docker系列之一:入門介紹

docker是dotcloud開源的、可以将任何應用包裝在linux container中運作的工具。2013年3月釋出首個版本,目前最新版本為1.3。docker基于go語言開發,代碼托管在github上,目前超過10000次commit。基于docker的沙箱環境可以實作輕型隔離,多個容器間不會互相影響;docker可以自動化打包和部署任何應用,友善地建立一個輕量級私有paas雲,也可以用于搭建開發測試環境以及部署可擴充的web應用等。

從下圖可以看出,vm是一個運作在主控端之上的完整的作業系統,vm運作自身作業系統會占用較多的cpu、記憶體、硬碟資源。docker不同于vm,隻包含應用程式以及依賴庫,基于libcontainer運作在主控端上,并處于一個隔離的環境中,這使得docker更加輕量高效,啟動容器隻需幾秒鐘之内完成。由于docker輕量、資源占用少,使得docker可以輕易的應用到建構标準化的應用中。但docker目前還不夠完善,比如隔離效果不如vm,共享主控端作業系統的一些基礎庫等;網絡配置功能相對簡單,主要以橋接方式為主;檢視日志也不夠友善靈活。

另外,ibm發表了一篇關于虛拟機和linux container性能對比的論文,論文中實際測試了虛拟機和linux container在cpu、記憶體、存儲io以及網絡的負載情況,結果顯示docker容器本身幾乎沒有什麼開銷,但是使用aufs會一定的性能損耗,不如使用docker volume,docker的nat在較高網絡資料傳輸中會引入較大的工作負載,帶來額外的開銷。不過container的性能與native相差不多,各方面的性能都一般等于或者優于虛拟機。container和虛拟機在io密集的應用中都需要調整優化以更好的支援io操作,兩者在io密集型的應用中都應該謹慎使用。

docker是cs架構,主要由下面三部分組成:

docker daemon: 運作在主控端上,docker守護程序,使用者通過docker client(docker指令)與docker daemon互動

docker client: docker 指令行工具,是使用者使用docker的主要方式,docker client與docker daemon通信并将結果傳回給使用者,docker client也可以通過socket或者restful api通路遠端的docker daemon

docker hub/registry: 共享和管理docker鏡像,使用者可以上傳或者下載下傳上面的鏡像,官方位址為https://registry.hub.docker.com/,也可以搭建自己私有的docker registry。

了解了docker的組成,再來了解一下docker的兩個主要概念:

docker image:鏡像是隻讀的,鏡像中包含有需要運作的檔案。鏡像用來建立container,一個鏡像可以運作多個container;鏡像可以通過dockerfile建立,也可以從docker hub/registry上下載下傳。

docker container:容器是docker的運作元件,啟動一個鏡像就是一個容器,容器是一個隔離環境,多個容器之間不會互相影響,保證容器中的程式運作在一個相對安全的環境中。

docker的網絡功能相對簡單,沒有過多複雜的配置,docker預設使用birdge橋接方式與容器通信,啟動docker後,主控端上會産生<code>docker0</code>這樣一個虛拟網絡接口, docker0不是一個普通的網絡接口, 它是一個虛拟的以太網橋,可以為綁定到docker0上面的網絡接口自動轉發資料包,這樣可以使容器與主控端之間互相通信。每次docker建立一個容器,會産生一對虛拟接口,在主控端上執行<code>ifconfig</code>,會發現多了一個類似<code>veth****</code>這樣的網絡接口,它會綁定到docker0上,由于所有容器都綁定到docker0上,容器之間也就可以通信。

在主控端上執行ifconfig,會看到docker0這個網絡接口, 啟動一個container,再次執行<code>ifconfig</code>, 會有一個類似<code>veth****</code>的interface,每個container的預設路由是主控端上docker0的ip,在container中執行<code>netstat -r</code>可以看到如下圖所示内容:

容器中的預設網關跟docker0的位址是一樣的:

當容器退出之後,veth*虛拟接口也會被銷毀。

除bridge方式,docker還支援host、container、none三種網絡通信方式,使用其它通信方式,隻要在docker啟動時,指定--net參數即可,比如:

host方式可以讓容器無需建立自己的網絡協定棧,而直接通路主控端的網絡接口,在容器中執行ip addr會發現與主控端的網絡配置是一樣的,host方式讓容器直接使用主控端的網絡接口,傳輸資料的效率會更加高效,避免bridge方式帶來的額外開銷,但是這種方式也可以讓容器通路主控端的d-bus等網絡服務,可能會帶來意想不到的安全問題,應謹慎使用host方式;container方式可以讓容器共享一個已經存在容易的網絡配置; none方式不會對容器的網絡做任務配置,需要使用者自己去定制。

首先要在主控端上安裝docker,docker安裝參考官方安裝文檔。

docker指令也比較類似git,支援push以及pull操作上傳以及下載下傳docker鏡像。

檢視目前docker的版本

檢視目前系統docker資訊

檢視主控端上的鏡像,docker鏡像儲存在<code>/var/lib/docker</code>目錄下:

從docker hub上下載下傳某個鏡像:

執行<code>docker pull ubuntu</code>會将ubuntu這個倉庫下面的所有鏡像下載下傳到本地repository。

啟動一個容器使用<code>docker run</code>:

檢視目前有哪些容器正在運作,使用<code>docker ps</code>:

啟動或停止某個container使用<code>docker start/stop container_id</code>:

使用<code>docker commit</code>可以将container的變化作為一個新的鏡像,比如:

除了從docker hub上下載下傳鏡像,也可以寫dockerfile建立一個鏡像,以建立一個django程式為例,dockerfile如下所示:

寫完dockerfile,在dockerfile所在目錄執行<code>docker build</code>建立鏡像:

将制作的鏡像上傳到private registry:

經過長時間使用,主機上存儲了很多已無用的鏡像,想将它們删除則用<code>docker rm</code>或者<code>docker rmi</code>,比如:

随着docker迅速火遍全球, 以docker為基礎的生态系統也迅速的發展起來,從以部署和運作container為基礎的coreos到各種各樣的管理工具和paas軟體,docker以及生态産品都在迅猛發展,以下介紹幾個代表性的軟體。

首先介紹coreos,它的出現極大地推動了docker技術的推廣和發展,coreos是專門為大規模服務部署而設計的一種新的linux發行版,通過運作輕量級的容器友善擴充和維護大規模的服務。它具有以下特點:

coreos使用container管理服務(容器即服務),即以容器的角度去管理服務,服務的代碼和依賴都打包到容器裡,打包後的容器直接在coreos上運作管理。通過容器使用者不再需要關注虛拟機環境等,極大地降低了服務和系統環境的耦合性。另外部署在coreos的多個容器都運作在各自獨立的環境中,不會互相影響。

coreos專門為cluster等大規模部署而設計,提供了etcd進行服務發現,以及fleet管理容器保證服務可用。

coreos更加精簡,比如ram使用比普通linux低40%。

coreos采用雙分區模式(dual-partition),主分區為主動模式,負責系統運作,被動模式分區負責系統更新,更新時将整個coreos系統下載下傳下來。

coreos是為叢集服務而設計的,提供了etcd、fleet等管理工具管理容器和服務。etcd是一種類似zookeeper的分布式key/value存儲服務,用于服務發現和配置管理。fleet是容器管理工具,保證服務的可用性,當某個機器的服務不可用時,fleet會将服務遷移到其它機器上運作。

docker生态中還有一個非常重要的容器管理工具--kubernetes,它是google開源的用于在叢集環境中管理、維護、自動擴充容器,通過kubernetes可以很友善地在多個機器上管理和部署容器服務。現在已經得到ibm、microsoft、redhat等多個大公司的支援。

在kubernetes中pod是一個基本單元,一個pod可以是提供相同功能的多個container,這些容器會被部署在同一個minion上。replication controller定義了多個pod或者容器需要運作,如果目前叢集中運作的pod或容器達不到配置的數量,replication controller會排程容器在多個minion上運作,保證叢集中的pod數量。service則定義真實對外提供的服務,一個service會對應後端運作的多個container。kubernetes的架構由一個master和多個minion組成,master通過api提供服務,接受kubectl的請求來排程管理整個叢集。minion是運作kubelet的機器,它接受master的指令建立pod或者容器。

最後介紹一下基于docker實作的paas軟體,docker paas軟體中以deis和flynn最為知名。deis是基于docker和coreos實作的輕量級的paas,受到heroku的啟發,遵循“十二要素”建構應用方法。deis是以應用程式為中心設計的,分為build、release、run三個階段,使用者執行"git push"後,deis使用docker 容器編譯并将編譯結果儲存在docker鏡像;釋出階段,一次build和配置檔案産生一個數字辨別的釋出鏡像,将釋出鏡像儲存到docker registry中以供後續釋出到線上運作;運作階段應用鏡像會被排程到主機上運作,并更新相應的路由。flynn與deis類似,也是以應用為中心,flynn元件分為兩層,layer0是底層資源的抽象,主要負責資源排程以及服務發現等,為上層應用容器的運作提供底層資源排程支援;layer1處理具體應用,通過docker容器編譯、部署和維護上層應用程式。

docker從2013年釋出第一個版本以來,已經火遍全球,技術疊代也比較頻繁,其周邊産品和技術也越來越豐富,由于docker更新頻繁,會出現新版本有時不相容舊版本的情況,docker周邊産品基本都處于開發階段還不具備生産環境下使用。

docker的輕量級容器不僅實作了資源隔離,而且幾乎可以運作在任何地方,使得部署和擴充變得非常容易,随着docker的日趨完善,希望docker被越來越多的公司應用到生産環境中。下一篇将詳細介紹美團如何使用docker。

https://docs.docker.com/articles/

https://docker.cn/

http://domino.research.ibm.com/library/cyberdig.nsf/papers/0929052195dd819c85257d2300681e7b/$file/rc25482.pdf

http://www.infoq.com/

https://github.com/docker/docker-registry

http://www.xmind.net/m/rhsz/

發現文章有錯誤、對内容有疑問,都可以關注美團點評技術團隊微信公衆号(meituantech),在背景給我們留言。我們每周會挑選出一位熱心小夥伴,送上一份精美的小禮品。快來掃碼關注我們吧!