1. 程式人生 > >Docker 源碼架構部署篇(一)

Docker 源碼架構部署篇(一)

docker

一. Docker入門簡介

Docker是Docker公司開源的一個基於輕量級虛擬化技術的容器引擎項目,整個項目基於Go語言開發,並遵從Apache 2.0協議。目前,Docker可以在容器內部快速自動化部署應用,並可以通過內核虛擬化技術(namespaces及cgroups等)來提供容器的資源隔離與安全保障等。由於Docker通過操作系統層的虛擬化實現隔離,所以Docker容器在運行時,不需要類似虛擬機(VM)額外的操作系統開銷,提高資源利用率,並且提升諸如IO等方面的性能。

由於眾多新穎的特性以及項目本身的開放性,Docker在不到兩年的時間裏迅速獲得諸多廠商的青睞,其中更是包括Google、Microsoft、VMware等業界行業領導者。Google在今年六月份推出了Kubernetes,提供Docker容器的調度服務,而今年8月

Microsoft宣布Azure上支持Kubernetes,隨後傳統虛擬化巨頭VMware宣布與Docker強強合作。今年9月中旬,Docker更是獲得4000萬美元的C輪融資,以推動分布式應用方面的發展。

Docker 項目的目標是實現輕量級的操作系統虛擬化解決方案。 Docker 的基礎是 Linux 容器(LXC)等技術。

在 LXC 的基礎上 Docker 進行了進一步的封裝,讓用戶不需要去關心容器的管理,使得操作更為簡便。用戶操作 Docker 的容器就像操作一個快速輕量級的虛擬機一樣簡單。

下面對比了Docker 和傳統虛擬化(KVM、XEN等)方式的不同之處,容器是在操作系統層面上實現虛擬化,直接復用本地主機的操作系統,而傳統方式則是在硬件的基礎上,虛擬出自己的系統,再在系統上部署相關的APP應用。

下圖為傳統虛擬化方案:

技術分享圖片


如下為Docker虛擬化方案:

技術分享圖片


Docker虛擬化有三個概念需要理解,分別鏡像、容器、倉庫。

1) 鏡像:docker的鏡像其實就是模板,跟我們常見的ISO鏡像類似,是一個樣板。

2) 容器:使用鏡像常見的應用或者系統,我們稱之為一個容器。

3) 倉庫:倉庫是存放鏡像的地方,分為公開倉庫(Public)和私有倉庫(Private)兩種形式.


二. Docker虛擬化特點

跟傳統VM比較具有如下優點:

1) 操作啟動快

運行時的性能可以獲取極大提升,管理操作(啟動,停止,開始,重啟等等) 都是以秒或毫秒為單位的。

2) 輕量級虛擬化

你會擁有足夠的操作系統,僅需添加或減小鏡像即可。在一臺服務器上可以布署
100~1000Containers容器。但是傳統虛擬化,你虛擬10-20個虛擬機就不錯了。

3) 開源免費

開源的,免費的,低成本的。由現代Linux內核支持並驅動。註* 輕量的Container必定可以在一個物理機上開啟更多容器,註定比VMs要便宜。

4) 前景及雲支持

正在越來越受歡迎,包括各大主流公司都在推動docker的快速發展,性能有很大的優勢。


三.為什麽要使用Docker

1、更高效的利用系統資源

由於容器不需要進行硬件虛擬及運行完整操作系統等額外開銷,Docker對系統資源的利用率更高。無論是應用執行速度、內存損耗或者文件存儲速度,都要比傳統的虛擬機技術更高效。因此,相比虛擬機技術,一個相同配置的主機,往往可以運行更多數量的應用。

2、輕量級啟動快速

傳統的虛擬機是基於hypervisor進行虛擬出來,而docker是內核級虛擬化,由於直接運行與宿主內核,無序啟動完整的操作系統,因此可以做到妙級,甚至毫秒級的啟動時間,大大的節約了開發,測試,部署的時間

3、快速部署,快速遷移

由於Docker確保了執行環境的一致性,使得應用的遷移更加容易,Docker可以在很多平臺上運行,無論是物理機,虛擬機,公有雲,私有雲,甚至是比較本,其運行結果是一致的,因此用戶可以很輕易的將在一個平臺上運行的應用,遷移到另一個平臺上,而不用擔心運行環境的變化導致應用無法正常運行的情況。

4、持續交付和部署

對於開發和運維人員來說,最希望的就是一次創建或配置,可以在任意地方正常運行。

使用Docker可以通過定制應用鏡像來實現持續集成,持續交付,部署。開發人員可以通過Dockerfile來進行鏡像構建,並結合持續集成系統進行集成測試,而運維人員則可以在生產環境中快速部署該鏡像,甚至結合持續部署系統進行自動部署

5、一致的運行環境

開發過程中一個常見的問題是環境一致性問題,由於開發環境,測試環境,生產環境不一致,導致有些bug並未在開發過程中被發現,而Docker的鏡像提供了除內核外完整的運行時環境,確保了應用運行環境一致性。從而不會再出現(這段代碼在我機器上運行沒問題啊)zz這類問題。

6、更輕松的維護和擴展

Docker使用的分層存數以及鏡像的技術,使得應用重復部分的復用更為容易,也使得應用的維護更新更加簡單,基於基礎鏡像進一步擴展鏡像也變得非常簡單,此外,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容器就處於運行狀態,該容器擁有獨立的文件系統,獨立並且安全的運行環境等。

五、Docker 架構內各模塊的功能與實現分析

主要模塊


5.1 docker client [發起請求]

  1. Docker Client是和Docker Daemon建立通信的客戶端。用戶使用的可執行文件為docker(類似可執行腳本的命令),docker命令後接參數的形式來實現一個完整的請求命令(例如docker images,docker為命令不可變,images為參數可變)。

  2. Docker Client可以通過以下三種方式和Docker Daemon建立通信:tcp://host:port,unix://path_to_socket和fd://socketfd。

  3. Docker Client發送容器管理請求後,由Docker Daemon接受並處理請求,當Docker Client接收到返回的請求相應並簡單處理後,Docker Client一次完整的生命周期就結束了。[一次完整的請求:發送請求→處理請求→返回結果],與傳統的C/S架構請求流程並無不同。

5.2 docker daemon [後臺守護進程]


Docker Daemon架構圖

技術分享圖片

1、Docker Server [調度分發請求]

docker Server 架構圖

技術分享圖片


1、Docker Server相當於C/S架構的服務端。功能為接受並調度分發Docker Client發送的請求。接受請求後,Server通過路由與分發調度,找到相應的Handler來執行請求。

2、在Docker的啟動過程中,通過包gorilla/mux,創建了一個mux.Router,提供請求的路由功能。在Golang中,gorilla/mux是一個強大的URL路由器以及調度分發器。該mux.Router中添加了眾多的路由項,每一個路由項由HTTP請求方法(PUT、POST、GET或DELETE)、URL、Handler三部分組成。

3、創建完mux.Router之後,Docker將Server的監聽地址以及mux.Router作為參數,創建一個httpSrv=http.Server{},最終執行httpSrv.Serve()為請求服務。

4、在Server的服務過程中,Server在listener上接受Docker Client的訪問請求,並創建一個全新的goroutine來服務該請求。在goroutine中,首先讀取請求內容,然後做解析工作,接著找到相應的路由項,隨後調用相應的Handler來處理該請求,最後Handler處理完請求之後回復該請求。

2、Engine

1、Engine是Docker架構中的運行引擎,同時也Docker運行的核心模塊。它扮演Docker container存儲倉庫的角色,並且通過執行job的方式來操縱管理這些容器。

2、在Engine數據結構的設計與實現過程中,有一個handler對象。該handler對象存儲的都是關於眾多特定job的handler處理訪問。舉例說明,Engine的handler對象中有一項為:{"create": daemon.ContainerCreate,},則說明當名為"create"的job在運行時,執行的是daemon.ContainerCreate的handler。

3、Job

1、一個Job可以認為是Docker架構中Engine內部最基本的工作執行單元。Docker可以做的每一項工作,都可以抽象為一個job。例如:在容器內部運行一個進程,這是一個job;創建一個新的容器,這是一個job。Docker Server的運行過程也是一個job,名為serveapi。

2、Job的設計者,把Job設計得與Unix進程相仿。比如說:Job有一個名稱,有參數,有環境變量,有標準的輸入輸出,有錯誤處理,有返回狀態等。

5.3 docker registry [鏡像註冊中心]

  1. Docker Registry是一個存儲容器鏡像的倉庫(註冊中心),可理解為雲端鏡像倉庫,按repository來分類,docker pull 按照[repository]:[tag]來精確定義一個image。

  2. 在Docker的運行過程中,Docker Daemon會與Docker Registry通信,並實現搜索鏡像、下載鏡像、上傳鏡像三個功能,這三個功能對應的job名稱分別為"search","pull" 與 "push"。

  3. 可分為公有倉庫(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。

1、graphdriver

技術分享圖片

1、graphdriver主要用於完成容器鏡像的管理,包括存儲與獲取。

2、存儲:docker pull下載的鏡像由graphdriver存儲到本地的指定目錄(Graph中)。

3、獲取:docker run(create)用鏡像來創建容器的時候由graphdriver到本地Graph中獲取鏡像。


2、networkdriver

技術分享圖片

networkdriver的用途是完成Docker容器網絡環境的配置,其中包括

  • 1、Docker啟動時為Docker環境創建網橋;

  • 2、Docker容器創建時為其創建專屬虛擬網卡設備;

  • 3、Docker容器分配IP、端口並與宿主機做端口映射,設置容器防火墻策略等。


3、execdriver

技術分享圖片

1、execdriver作為Docker容器的執行驅動,負責創建容器運行命名空間,負責容器資源使用的統計與限制,負責容器內部進程的真正運行等。

2、現在execdriver默認使用native驅動,不依賴於LXC。


5.6 libcontainer [函數庫]

架構圖

技術分享圖片


  1. libcontainer是Docker架構中一個使用Go語言設計實現的庫,設計初衷是希望該庫可以不依靠任何依賴,直接訪問內核中與容器相關的API。

  2. Docker可以直接調用libcontainer,而最終操縱容器的namespace、cgroups、apparmor、網絡設備以及防火墻規則等。

  3. libcontainer提供了一整套標準的接口來滿足上層對容器管理的需求。或者說,libcontainer屏蔽了Docker上層對容器的直接管理。

5.7 docker container[服務交付的最終形式]


container架構圖

技術分享圖片


  1. Docker container(Docker容器)是Docker架構中服務交付的最終體現形式。

  2. 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(容器) libcgroupdocker組) device-mapper-event-libsdocker的一個存儲引擎)

技術分享圖片


然後安裝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命令啟動。

技術分享圖片





Docker 源碼架構部署篇(一)