Docker是Docker公司開源的一個基於輕量級虛擬化技術的容器引擎項目,整個項目基於Go語言開發,並聽從Apache 2.0協議。目前,Docker能夠在容器內部快速自動化部署應用,並能夠經過內核虛擬化技術(namespaces及cgroups等)來提供容器的資源隔離與安全保障等。因爲Docker經過操做系統層的虛擬化實現隔離,因此Docker容器在運行時,不須要相似虛擬機(VM)額外的操做系統開銷,提升資源利用率,而且提高諸如IO等方面的性能。linux
因爲衆多新穎的特性以及項目自己的開放性,Docker在不到兩年的時間裏迅速得到諸多廠商的青睞,其中更是包括Google、Microsoft、VMware等業界行業領導者。Google在今年六月份推出了Kubernetes,提供Docker容器的調度服務,而今年8月Microsoft宣佈Azure上支持Kubernetes,隨後傳統虛擬化巨頭VMware宣佈與Docker強強合做。今年9月中旬,Docker更是得到4000萬美圓的C輪融資,以推進分佈式應用方面的發展。git
Docker 項目的目標是實現輕量級的操做系統虛擬化解決方案。 Docker 的基礎是 Linux 容器(LXC)等技術。github
在 LXC 的基礎上 Docker 進行了進一步的封裝,讓用戶不須要去關心容器的管理,使得操做更爲簡便。用戶操做 Docker 的容器就像操做一個快速輕量級的虛擬機同樣簡單。docker
下面對比了Docker 和傳統虛擬化(KVM、XEN等)方式的不一樣之處,容器是在操做系統層面上實現虛擬化,直接複用本地主機的操做系統,而傳統方式則是在硬件的基礎上,虛擬出本身的系統,再在系統上部署相關的APP應用。數據庫
下圖爲傳統虛擬化方案:centos
以下爲Docker虛擬化方案:api
Docker虛擬化有三個概念須要理解,分別鏡像、容器、倉庫。安全
1) 鏡像:docker的鏡像其實就是模板,跟咱們常見的ISO鏡像相似,是一個樣板。服務器
2) 容器:使用鏡像常見的應用或者系統,咱們稱之爲一個容器。網絡
3) 倉庫:倉庫是存放鏡像的地方,分爲公開倉庫(Public)和私有倉庫(Private)兩種形式.
二. Docker虛擬化特色
三.爲何要使用Docker
1. 簡化配置
這是Docker公司宣傳的Docker的主要使用場景。虛擬機的最大好處是能在你的硬件設施上運行各類配置不同的平臺(軟件、系統),Docker在下降額外開銷的狀況下提供了一樣的功能。它能讓你將運行環境和配置放在代碼中而後部署,同一個Docker的配置能夠在不一樣的環境中使用,這樣就下降了硬件要求和應用環境之間耦合度。
2. 代碼流水線(Code Pipeline)管理
前一個場景對於管理代碼的流水線起到了很大的幫助。代碼從開發者的機器到最終在生產環境上的部署,須要通過不少的中間環境。而每個中間環境都有本身微小的差異,Docker給應用提供了一個從開發到上線均一致的環境,讓代碼的流水線變得簡單很多。
3. 提升開發效率
這就帶來了一些額外的好處:Docker能提高開發者的開發效率。若是你想看一個詳細一點的例子,能夠參考Aater在 DevOpsDays Austin 2014 大會或者是DockerCon上的演講。
不一樣的開發環境中,咱們都想把兩件事作好。一是咱們想讓開發環境儘可能貼近生產環境,二是咱們想快速搭建開發環境。
理想狀態中,要達到第一個目標,咱們須要將每個服務都跑在獨立的虛擬機中以便監控生產環境中服務的運行狀態。然而,咱們卻不想每次都須要網絡鏈接,每次從新編譯的時候遠程鏈接上去特別麻煩。這就是Docker作的特別好的地方,開發環境的機器一般內存比較小,以前使用虛擬的時候,咱們常常須要爲開發環境的機器加內存,而如今Docker能夠輕易的讓幾十個服務在Docker中跑起來。
4. 隔離應用
有不少種緣由會讓你選擇在一個機器上運行不一樣的應用,好比以前提到的提升開發效率的場景等。
咱們常常須要考慮兩點,一是由於要下降成本而進行服務器整合,二是將一個總體式的應用拆分紅松耦合的單個服務(譯者注:微服務架構)。若是你想了解爲何鬆耦合的應用這麼重要,請參考Steve Yege的 這篇論文,文中將Google和亞馬遜作了比較。
5. 整合服務器
正如經過虛擬機來整合多個應用,Docker隔離應用的能力使得Docker能夠整合多個服務器以下降成本。因爲沒有多個操做系統的內存佔用,以及能在多個實例之間共享沒有使用的內存,Docker能夠比虛擬機提供更好的服務器整合解決方案。
6. 調試能力
Docker提供了不少的工具,這些工具不必定只是針對容器,可是卻適用於容器。它們提供了不少的功能,包括能夠爲容器設置檢查點、設置版本和查看兩個容器之間的差異,這些特性能夠幫助調試Bug。你能夠在 《Docker拯救世界》的文章中找到這一點的例證。
7. 多租戶環境
另一個Docker有意思的使用場景是在多租戶的應用中,它能夠避免關鍵應用的重寫。咱們一個特別的關於這個場景的例子是爲IoT(譯者注:物聯網)的應用開發一個快速、易用的多租戶環境。這種多租戶的基本代碼很是複雜,很難處理,從新規劃這樣一個應用不但消耗時間,也浪費金錢。
使用Docker,能夠爲每個租戶的應用層的多個實例建立隔離的環境,這不只簡單並且成本低廉,固然這一切得益於Docker環境的啓動速度和其高效的diff命令。
你能夠在 這裏瞭解關於此場景的更多信息。
8. 快速部署
在虛擬機以前,引入新的硬件資源須要消耗幾天的時間。虛擬化技術(Virtualization)將這個時間縮短到了分鐘級別。而Docker經過爲進程僅僅建立一個容器而無需啓動一個操做系統,再次將這個過程縮短到了秒級。這正是Google和Facebook都看重的特性。
你能夠在數據中心建立銷燬資源而無需擔憂從新啓動帶來的開銷。一般數據中心的資源利用率只有30%,經過使用Docker並進行有效的資源分配能夠提升資源的利用率。
四.Docker 的體系結構
不難看出,用戶是使用Docker Client與Docker Daemon創建通訊,併發送請求給後者。
而Docker Daemon做爲Docker架構中的主體部分,首先提供Server的功能使其能夠接受Docker Client的請求;然後Engine執行Docker內部的一系列工做,每一項工做都是以一個Job的形式的存在。
Job的運行過程當中,當須要容器鏡像時,則從Docker Registry中下載鏡像,並經過鏡像管理驅動graphdriver將下載鏡像以Graph的形式存儲;當須要爲Docker建立網絡環境時,經過網絡管理驅動networkdriver建立並配置Docker容器網絡環境;當須要限制Docker容器運行資源或執行用戶指令等操做時,則經過execdriver來完成。
而libcontainer是一項獨立的容器管理包,networkdriver以及execdriver都是經過libcontainer來實現具體對容器進行的操做。
當執行完運行容器的命令後,一個實際的Docker容器就處於運行狀態,該容器擁有獨立的文件系統,獨立而且安全的運行環境等。
5、Docker 架構內各模塊的功能與實現分析
主要模塊
5.1 docker client [發起請求]
Docker Client是和Docker Daemon創建通訊的客戶端。用戶使用的可執行文件爲docker(相似可執行腳本的命令),docker命令後接參數的形式來實現一個完整的請求命令(例如docker images,docker爲命令不可變,images爲參數可變)。
Docker Client能夠經過如下三種方式和Docker Daemon創建通訊:tcp://host:port,unix://path_to_socket和fd://socketfd。
Docker Client發送容器管理請求後,由Docker Daemon接受並處理請求,當Docker Client接收到返回的請求相應並簡單處理後,Docker Client一次完整的生命週期就結束了。[一次完整的請求:發送請求→處理請求→返回結果],與傳統的C/S架構請求流程並沒有不一樣。
5.2 docker daemon [後臺守護進程]
Docker Daemon架構圖
一、Docker Server [調度分發請求]
docker Server 架構圖
一、Docker Server至關於C/S架構的服務端。功能爲接受並調度分發Docker Client發送的請求。接受請求後,Server經過路由與分發調度,找到相應的Handler來執行請求。
二、在Docker的啓動過程當中,經過包gorilla/mux,建立了一個mux.Router,提供請求的路由功能。在Golang中,gorilla/mux是一個強大的URL路由器以及調度分發器。該mux.Router中添加了衆多的路由項,每個路由項由HTTP請求方法(PUT、POST、GET或DELETE)、URL、Handler三部分組成。
三、建立完mux.Router以後,Docker將Server的監聽地址以及mux.Router做爲參數,建立一個httpSrv=http.Server{},最終執行httpSrv.Serve()爲請求服務。
四、在Server的服務過程當中,Server在listener上接受Docker Client的訪問請求,並建立一個全新的goroutine來服務該請求。在goroutine中,首先讀取請求內容,而後作解析工做,接着找到相應的路由項,隨後調用相應的Handler來處理該請求,最後Handler處理完請求以後回覆該請求。
二、Engine
一、Engine是Docker架構中的運行引擎,同時也Docker運行的核心模塊。它扮演Docker container存儲倉庫的角色,而且經過執行job的方式來操縱管理這些容器。
二、在Engine數據結構的設計與實現過程當中,有一個handler對象。該handler對象存儲的都是關於衆多特定job的handler處理訪問。舉例說明,Engine的handler對象中有一項爲:{"create": daemon.ContainerCreate,},則說明當名爲"create"的job在運行時,執行的是daemon.ContainerCreate的handler。
三、Job
一、一個Job能夠認爲是Docker架構中Engine內部最基本的工做執行單元。Docker能夠作的每一項工做,均可以抽象爲一個job。例如:在容器內部運行一個進程,這是一個job;建立一個新的容器,這是一個job。Docker Server的運行過程也是一個job,名爲serveapi。
二、Job的設計者,把Job設計得與Unix進程相仿。好比說:Job有一個名稱,有參數,有環境變量,有標準的輸入輸出,有錯誤處理,有返回狀態等。
5.3 docker registry [鏡像註冊中心]
Docker Registry是一個存儲容器鏡像的倉庫(註冊中心),可理解爲雲端鏡像倉庫,按repository來分類,docker pull 按照[repository]:[tag]來精肯定義一個image。
在Docker的運行過程當中,Docker Daemon會與Docker Registry通訊,並實現搜索鏡像、下載鏡像、上傳鏡像三個功能,這三個功能對應的job名稱分別爲"search","pull" 與 "push"。
可分爲公有倉庫(docker hub)和私有倉庫。
5.4 Graph [docker內部數據庫]
graph的架構圖
其中,GraphDB是一個構建在SQLite之上的小型圖數據庫,實現了節點的命名以及節點之間關聯關係的記錄。它僅僅實現了大多數圖數據庫所擁有的一個小的子集,可是提供了簡單的接口表示節點之間的關係。
同時在Graph的本地目錄中,關於每個的容器鏡像,具體存儲的信息有:該容器鏡像的元數據,容器鏡像的大小信息,以及該容器鏡像所表明的具體rootfs。
5.5 dirver
Driver是Docker架構中的驅動模塊。經過Driver驅動,Docker能夠實現對Docker容器執行環境的定製。即Graph負責鏡像的存儲,Driver負責容器的執行。在Docker Driver的實現中,能夠分爲如下三類驅動:graphdriver、networkdriver和execdriver。
一、graphdriver
一、graphdriver主要用於完成容器鏡像的管理,包括存儲與獲取。
二、存儲:docker pull下載的鏡像由graphdriver存儲到本地的指定目錄(Graph中)。
三、獲取:docker run(create)用鏡像來建立容器的時候由graphdriver到本地Graph中獲取鏡像。
二、networkdriver
networkdriver的用途是完成Docker容器網絡環境的配置,其中包括
一、Docker啓動時爲Docker環境建立網橋;
二、Docker容器建立時爲其建立專屬虛擬網卡設備;
三、Docker容器分配IP、端口並與宿主機作端口映射,設置容器防火牆策略等。
三、execdriver
一、execdriver做爲Docker容器的執行驅動,負責建立容器運行命名空間,負責容器資源使用的統計與限制,負責容器內部進程的真正運行等。
二、如今execdriver默認使用native驅動,不依賴於LXC。
5.6 libcontainer [函數庫]
架構圖
libcontainer是Docker架構中一個使用Go語言設計實現的庫,設計初衷是但願該庫能夠不依靠任何依賴,直接訪問內核中與容器相關的API。
Docker能夠直接調用libcontainer,而最終操縱容器的namespace、cgroups、apparmor、網絡設備以及防火牆規則等。
libcontainer提供了一整套標準的接口來知足上層對容器管理的需求。或者說,libcontainer屏蔽了Docker上層對容器的直接管理。
5.7 docker container[服務交付的最終形式]
container架構圖
Docker container(Docker容器)是Docker架構中服務交付的最終體現形式。
Docker按照用戶的需求與指令,訂製相應的Docker容器:
用戶經過指定容器鏡像,使得Docker容器能夠自定義rootfs等文件系統;
用戶經過指定計算資源的配額,使得Docker容器使用指定的計算資源;
用戶經過配置網絡及其安全策略,使得Docker容器擁有獨立且安全的網絡環境;
用戶經過指定運行的命令,使得Docker容器執行指定的工做。
六.Docker 安裝配置
咱們這裏主要講解如何在Centos6.x系列服務器安裝,默認docker只有在centos6.5以上機器才能使用yum直接安裝,若是其餘版本須要安裝centos擴展源epel。
docker官方文檔說要求Linux kernel至少3.8以上,通常爲centos6.5或者Ubuntu系統,那centos6.5如何來安裝呢?
在Centos6.x系列安裝docker軟件,首先要關閉selinux,而後須要安裝相應的epel源,以下:
阿里源:wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
sed -i '/SELINUX/s/enforcing/disabled/g' /etc/selinux/config
wget http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release-6-8.noarch.rpm (安裝擴展源)
yum install lxc(容器) libcgroup(docker組) device-mapper-event-libs(docker的一個存儲引擎)
而後安裝docker:
#yum install docker-io
Cd /mnt/cdrom/Packages
Yum install device-map* –y 都是屬於dockers物理存儲,能夠連接大數據平臺
安裝完後:
啓動docker進程:/etc/init.d/docker start
查看docker進程:ps -ef |grep docker
Docker簡單使用:
要使用docker虛擬化,首先咱們須要去下載一個鏡像,而後使用docker命令啓動。