Docker虛擬化技術概述及部署安裝
一、虛擬化概述及簡介
通俗的說,虛擬化就是把物理資源轉(zhuǎn)變?yōu)檫壿嬌峡梢怨芾淼馁Y源,以打破物理結構間的壁壘,計算元件運行在虛擬的基礎上而不是真實的基礎上,可以擴大硬件的容量,簡化軟件的重新配置過程。
允許一個平臺同時運行多個操作系統(tǒng),并且應用程序都可以在相互獨立的空間內(nèi)運行而互不影響,從而顯著提高計算機的工作效率,是一個為了簡化管理,優(yōu)化資源的解決方案。
目前主流的虛擬化技術主要有:KVM、Xen、VMware、VirtualBox、Docker,虛擬化技術也越來越廣泛的應用在企業(yè)中,例如Taobao、Google等。
虛擬化原理:虛擬化解決方案的底部是要進行虛擬化的物理機器。這臺機器可能直接支持虛擬化,也可能不會直接支持虛擬化;那么就需要系統(tǒng)管理程序?qū)拥闹С?。系統(tǒng)管理程序(Virtual machine monitor),或稱為 VMM,可以看作是平臺硬件和操作系統(tǒng)的抽象化。在某些情況中,這個系統(tǒng)管理程序就是一個操作系統(tǒng);此時,它就稱為主機操作系統(tǒng)。
圖 1. 虛擬化的分層抽象

完全擬化技術實際上是通過軟件實現(xiàn)對操作系統(tǒng)的資源再分配,比較成熟,例如我們的KVM、virtualBOX;
而半虛擬化技術則是通過代碼修改已有的系統(tǒng),形成一種新的可虛擬化的系統(tǒng),調(diào)用硬件資源去安裝多個系統(tǒng),整體速度上相對高一點,代表產(chǎn)品有Xen。
二、Docker入門簡介
Docker 是一個開源的應用容器引擎,讓開發(fā)者可以打包他們的應用以及依賴包到一個可移植的容器中,然后發(fā)布到任何流行的Linux機器上,也可以實現(xiàn)虛擬化。
容器是完全使用沙箱機制,相互之間不會有任何接口(類似 iPhone 的 app)。幾乎沒有性能開銷,可以很容易地在機器和數(shù)據(jù)中心中運行。最重要的是,他們不依賴于任何語言、框架或包括系統(tǒng)。
"Docker"應該是2014年最火爆的技術之一,如果沒有聽說過,那么你就out了,2015年將開啟新的跨越。
Docker 自開源后受到廣泛的關注和討論,以至于 dotCloud 公司后來都改名為 Docker Inc。Redhat 已經(jīng)在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 產(chǎn)品中廣泛應用。
Docker 項目的目標是實現(xiàn)輕量級的操作系統(tǒng)虛擬化解決方案。 Docker 的基礎是 Linux 容器(LXC)等技術。
在 LXC 的基礎上 Docker 進行了進一步的封裝,讓用戶不需要去關心容器的管理,使得操作更為簡便。用戶操作 Docker 的容器就像操作一個快速輕量級的虛擬機一樣簡單。
下面對比了Docker 和傳統(tǒng)虛擬化(KVM、XEN等)方式的不同之處,Docker容器是在操作系統(tǒng)層面上實現(xiàn)虛擬化,直接復用本地主機的操作系統(tǒng),而傳統(tǒng)方式則是在硬件的基礎上,虛擬出自己的系統(tǒng),再在系統(tǒng)上部署相關的APP應用。
虛擬化要運行一下Nginx軟件
下圖為傳統(tǒng)虛擬化方案:

如下為Docker虛擬化方案:

三、Docker虛擬化有三個概念需要理解,分別鏡像、容器、倉庫。
鏡像:docker的鏡像其實就是模板,跟我們常見的ISO鏡像類似,是一個樣板。
容器:使用鏡像常見的應用或者系統(tǒng),我們稱之為一個容器。
倉庫:倉庫是存放鏡像的地方,分為公開倉庫(Public)和私有倉庫(Private)兩種形式。
Docker LXC及Cgroup
Docker最早為 LXC+AUFS組合,Docker0.9.0版本開始引入libcontainer,可以視作LXC的替代品)。其中LXC負責資源管理,AUFS負責鏡像管理;而LXC包括cgroup、namespace、chroot等組件,并通過cgroup進行資源管理。
從資源管理來看,Docker、LXC、Cgroup三者的關系是:Cgroup在***層落實資源管理,LXC在cgroup上封裝了一層,Docker又在LXC封裝了一層,要想學好Docker,需要了解負責資源管理的CGroup和LXC。

Cgroups是control groups的縮寫,是Linux內(nèi)核提供的一種可以限制、記錄、隔離進程組(process groups)所使用的物理資源(如:CPU, Memory, IO等)的機制。
最初由Google的工程師提出,后來被整合進Linux內(nèi)核。Cgroups也是LXC為實現(xiàn)虛擬化所使用的資源管理手段,可以說沒有Cgroups就沒有LXC,也就沒有Docker。
Cgroups最初的目標是為資源管理提供的一個統(tǒng)一的框架,既整合現(xiàn)有的Cpuset等子系統(tǒng),也為未來開發(fā)新的子系統(tǒng)提供接口?,F(xiàn)在的Cgroups適用于多種應用場景,從單個進程的資源控制,到實現(xiàn)操作系統(tǒng)層次的虛擬化(OS Level Virtualization)。
LinuxContainer容器可以提供輕量級的虛擬化,以便隔離進程和資源,而且不需要提供指令解釋機制以及全虛擬化的其他復雜性。容器有效地將由單個操作系統(tǒng)管理的資源劃分到孤立的組中,以更好地在孤立的組之間平衡有沖突的資源使用需求。
LXC建立在CGroup基礎上,我們可以粗略的認為LXC = Cgroup+ namespace + Chroot + veth +用戶態(tài)控制腳本。LXC利用內(nèi)核的新特性(CGroup)來提供用戶空間的對象,用來保證資源的隔離和對于應用或者系統(tǒng)的資源控制。
典型的Linux文件系統(tǒng)由bootfs和rootfs兩部分組成,bootfs(boot file system)主要包含 bootloader和kernel,bootloader主要是引導加載kernel,當kernel被加載到內(nèi)存中后 bootfs就被umount。rootfs (root file system) 包含的就是典型 Linux 系統(tǒng)中的/dev,/proc,/bin,/etc等標準目錄和文件。
Docker容器的文件系統(tǒng)最早是建立在Aufs基礎上的,Aufs(Another Union File System)是一種Union FS, 簡單來說就是支持將不同的目錄掛載到同一個虛擬文件系統(tǒng)下,并實現(xiàn)一種layer的概念。
由于Aufs未能加入到Linux內(nèi)核,考慮到兼容性問題,加入了Devicemapper的支持。Docker目前默認運行在Devicemapper基礎上。
Aufs將掛載到同一虛擬文件系統(tǒng)下的多個目錄分別設置成read-only,read-write以及whiteout-able權限,對read-only目錄只能讀,而寫操作只能實施在read-write目錄中。重點在于,寫操作是在read-only上的一種增量操作,不影響read-only目錄。當掛載目錄的時候要嚴格按照各目錄之間的這種增量關系,將被增量操作的目錄優(yōu)先于在它基礎上增量操作的目錄掛載,待所有目錄掛載結束了,繼續(xù)掛載一個read-write目錄,如此便形成了一種層次結構。
傳統(tǒng)的Linux加載bootfs時會先將rootfs設為read-only,然后在系統(tǒng)自檢之后將rootfs從read-only改為read-write,然后我們就可以在rootfs上進行寫和讀的操作了。但Docker的鏡像卻不是這樣,它在bootfs自檢完畢之后并不會把rootfs的read-only改為read-write。而是利用union mount(UnionFS的一種掛載機制)將一個或多個read-only的rootfs加載到之前的read-only的rootfs層之上。
在加載了這么多層的rootfs之后,仍然讓它看起來只像是一個文件系統(tǒng),在Docker的體系里把union mount的這些read-only的rootfs叫做Docker的鏡像。但是,此時的每一層rootfs都是read-only的,我們此時還不能對其進行操作。當我們創(chuàng)建一個容器,也就是將Docker鏡像進行實例化,系統(tǒng)會在一層或是多層read-only的rootfs之上分配一層空的read-write的rootfs。

Device Mapper 是 Linux2.6 內(nèi)核中支持邏輯卷管理的通用設備映射機制,它為實現(xiàn)用于存儲資源管理的塊設備驅(qū)動提供了一個高度模塊化的內(nèi)核架構,Device Mapper的內(nèi)核體系架構:

在內(nèi)核中它通過一個一個模塊化的 target driver 插件實現(xiàn)對 IO 請求的過濾或者重新定向等工作,當前已經(jīng)實現(xiàn)的 target driver 插件包括軟 raid、軟加密、邏輯卷條帶、多路徑、鏡像、快照等,圖中 linear、mirror、snapshot、multipath 表示的就是這些 target driver。Device mapper 進一步體現(xiàn)了在 Linux 內(nèi)核設計中策略和機制分離的原則,將所有與策略相關的工作放到用戶空間完成,內(nèi)核中主要提供完成這些策略所需要的機制。
Device mapper 用戶空間相關部分主要負責配置具體的策略和控制邏輯,比如邏輯設備和哪些物理設備建立映射,怎么建立這些映射關系等等,而具體過濾和重定向 IO 請求的工作由內(nèi)核中相關代碼完成。因此整個 device mapper 機制由兩部分組成--內(nèi)核空間的 device mapper 驅(qū)動、用戶空間的device mapper 庫以及它提供的 dmsetup 工具。
四、Docker虛擬化特點
跟傳統(tǒng)VM比較具有如下優(yōu)點:
操作啟動快
運行時的性能可以獲取極大提升,管理操作(啟動,停止,開始,重啟等等) 都是以秒或毫秒為單位的。
輕量級虛擬化
你會擁有足夠的"操作系統(tǒng)",僅需添加或減小鏡像即可。在一臺服務器上可以布署100~1000個Containers容器。但是傳統(tǒng)虛擬化,你虛擬10-20個虛擬機就不錯了。
開源免費
開源的,免費的,低成本的。由現(xiàn)代Linux內(nèi)核支持并驅(qū)動。注* 輕量的Container必定可以在一個物理機上開啟更多"容器",注定比VMs要便宜。
前景及云支持
正在越來越受歡迎,包括各大主流公司都在推動docker的快速發(fā)展,性能有很大的優(yōu)勢。
跟傳統(tǒng)VM比較具有如下缺點:
- 目前知道的人比較少;
- 相關的技術資料欠缺;
- Go語言還沒完全成熟。
五、為什么使用Docker
Docker 在如下幾個方面具有較大的優(yōu)勢:
更快速的交付和部署
Docker在整個開發(fā)周期都可以***的輔助你實現(xiàn)快速交付。Docker允許開發(fā)者在裝有應用和服務本地容器做開發(fā)??梢灾苯蛹傻娇沙掷m(xù)開發(fā)流程中。
開發(fā)者可以使用一個標準的鏡像來構建一套開發(fā)容器,開發(fā)完成之后,運維人員可以直接使用這個容器來部署代碼。 Docker 可以快速創(chuàng)建容器,快速迭代應用程序,并讓整個過程全程可見,使團隊中的其他成員更容易理解應用程序是如何創(chuàng)建和工作的。 Docker 容器很輕很快!容器的啟動時間是秒級的,大量地節(jié)約開發(fā)、測試、部署的時間。
高效的部署和擴容
Docker 容器幾乎可以在任意的平臺上運行,包括物理機、虛擬機、公有云、私有云、個人電腦、服務器等。 這種兼容性可以讓用戶把一個應用程序從一個平臺直接遷移到另外一個。
Docker的兼容性和輕量特性可以很輕松的實現(xiàn)負載的動態(tài)管理。你可以快速擴容或方便的下線的你的應用和服務,這種速度趨近實時。
更高的資源利用率
Docker 對系統(tǒng)資源的利用率很高,一臺主機上可以同時運行數(shù)千個 Docker 容器。容器除了運行其中應用外,基本不消耗額外的系統(tǒng)資源,使得應用的性能很高,同時系統(tǒng)的開銷盡量小。傳統(tǒng)虛擬機方式運行 10 個不同的應用就要起 10 個虛擬機,而Docker 只需要啟動 10 個隔離的應用即可。
更簡單的管理
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分發(fā)和更新,從而實現(xiàn)自動化并且高效的管理。
Docker引擎架構
docker引擎是一個C/S結構的應用,組件如圖所示:

- Server是一個常駐進程;
- REST API 實現(xiàn)了client和server間的交互協(xié)議;
- CLI 實現(xiàn)容器和鏡像的管理,為用戶提供統(tǒng)一的操作界面。
Docker使用C/S架構,Client 通過接口與Server進程通信實現(xiàn)容器的構建,運行和發(fā)布。client和server可以運行在同一臺集群,也可以通過跨主機實現(xiàn)遠程通信,架構如圖所示:

實戰(zhàn)操作如下:
六、Docker安裝配置
系統(tǒng)環(huán)境:Centos7.4(docker官方文檔說要求Linux kernel至少3.8以上),執(zhí)行以下命令
- [root@localhost ~]# yum -y install docker

安裝完后:
啟動docker進程:systemctl start docker.service
查看docker進程: ps -ef | grep docker

Docker簡單使用
要使用docker虛擬化,首先我們需要去下載一個鏡像,然后使用docker命令啟動
1)下載鏡像
- [root@localhost ~]# docker search centos
- [root@localhost ~]# docker pull centos
2)啟動Docker容器

3)進入容器
- [root@localhost ~]# docker exec -it f48a681da213 /bin/bash

docker version #查看版本
docker search centos #搜索可用docker鏡像
docker images #查看當前docker所有鏡像
docker pull centos #下載鏡像
cat centos.tar | docker import - centos6_newname #Docker導入鏡像
docker export 容器_id > cenos6.tar #Docker導出鏡像
docker run centos echo "hello word" #在docker容器中運行hello world!
docker run centos yum install ntpdate #在容器中安裝ntpdate的程序
docker ps -l #命令獲得***一個容器的id
docker ps -a #查看所有的容器。
運行docker commit 提交剛修改的容器,例如:
docker commit 2313132 centos:v1
docker run -i –t -d centos /bin/bash 在容器里啟動一個/bin/bash shell環(huán)境,可以登錄進入操作,其中-t 表示打開一個終端的意思,-i表示可以交互輸入。
docker run -d centos:v1 /bin/bash ,-d表示在后臺啟動,以daemon方式啟動。
Docker stop id #關閉容器
Docker start id #啟動某個容器
docker rm id #刪除容器
docker rmi images #刪除鏡像
docker run -d -p 80:80 -p 8022:22 centos:v2,解析:-p指定容器啟動后docker上運行的端口映射及容器里運行的端口,80:80,***個80表示docker系統(tǒng)上的80,第二個80表示docker虛擬機里面的端口。用戶默認訪問本機80端口,自動映射到容器里面的80端口。
docker exec -it id /bin/bash #進入容器