本文來自技術分享
1、Docker介紹
一、什麼是Docker
Docker是世界領先的軟件容器化平臺。
Docker公司開發,開源,託管在github
跨平臺,支持Windows、MacOS、Linux
Docker 使用 Google 公司推出的Go語言進行開發實現,基於 Linux 內核的cgroup,namespace,以及AUFS 類的 Union FS 等技術,對進程進行封裝隔離,屬於操做系統層面的虛擬化技術。
因爲隔離的進程獨立於宿主和其它的隔離的進程,所以也稱其爲容器。linux
Docker 在容器的基礎上,進行了進一步的封裝,從文件系統、網絡互聯到進程隔離等等,極大的簡化了容器的建立和維護。使得 Docker 技術比虛擬機技術更爲輕便、快捷。nginx
下面的圖片比較了 Docker 和傳統虛擬化方式的不一樣之處。傳統虛擬機技術是虛擬出一套硬件後,在其上運行一個完整操做系統,在該系統上再運行所需應用進程;而容器內的應用進程直接運行於宿主的內核,容器內沒有本身的內核,並且也沒有進行硬件虛擬。所以容器要比傳統虛擬機更爲輕便。git
通俗理解:github
Docker是容器技術的表明,容器技術從本質上講是將程序隔離、打包的技術。Docker解決了軟件包裝的問題,理順了開發和運維的環境的差別,使得開發和運維能用同種語言來溝通。docker
什麼是Docker?官方的解釋:Docker是一個開源的項目,能夠用來將任何應用以輕量級容器的形式來打包、發佈和運行。ubuntu
類比:能夠粗糙地理解爲輕量級的虛擬機。它和虛擬機某種程度上完成一樣的任務:就是把一個應用程序放在一個獨立的環境裏來運行。安全
Docker不是虛擬機!服務器
Host_OS:宿主機網絡
Hypervisor:虛擬層,虛擬出硬件運維
VM在虛擬層上安裝徹底獨立的Guest OS,在裏面運行各類個樣的程序。每一個虛擬化應用程序不只包括應用程序(可能只有10 MB)、必要的二進制文件和庫,還包括整個客戶操做系統(可能有10 GB)。
Docker在Docker Engine層上面運行各類程序,利用了Host OS裏的NameSpace,ControlGroup等來作到將應用程序分離。Docker Engine容器僅包含應用程序及其依賴項。它在主機操做系統的用戶空間中做爲獨立進程運行,與其餘容器共享內核。所以,它享受了VM的資源隔離和分配好處,可是更加便攜和高效。
二、爲何要用Docker
更高效的利用系統資源
因爲容器不須要進行硬件虛擬以及運行完整操做系統等額外開銷,Docker對系統資源的利用率更高,不管是應用執行速度,內存消耗以及文件存儲速度,都要比傳統虛擬機技術更高效。所以,相比虛擬機技術,一個相同配置的主機,每每能夠運行更多數量的應用。
更快速的啓動時間
傳統的虛擬機技術啓動應用服務每每須要數分鐘,而Docker容器應用,因爲直接運行與宿主內核,無序啓動完整的操做系統,所以能夠作到妙級,甚至毫秒級的啓動時間,大大的節約了開發,測試,部署的時間。
一致的運行環境
開發過程當中一個常見的問題是環境一致性問題,因爲開發環境,測試環境,生產環境不一致,致使有些bug並未在開發過程當中被發現,而Docker的鏡像提供了除內核外完整的運行時環境,確保了應用運行環境一致性。從而不會再出現(這段代碼在我機器上運行沒問題啊)zz這類問題。
持續交付和部署
對於開發和運維人員來講,最但願的就是一次建立或配置,能夠在任意地方正常運行。
使用Docker能夠經過定製應用鏡像來實現持續集成,持續交付,部署。開發人員能夠經過Dockerfile來進行鏡像構建,並結合持續集成系統進行集成測試,而運維人員則能夠在生產環境中快速部署該鏡像,甚至結合持續部署系統進行自動部署
更輕鬆的遷移
因爲Docker確保了執行環境的一致性,使得應用的遷移更加容易,Docker能夠在不少平臺上運行,不管是物理機,虛擬機,公有云,私有云,甚至是比較本,其運行結果是一致的,所以用戶能夠很輕易的將在一個平臺上運行的應用,遷移到另外一個平臺上,而不用擔憂運行環境的變化致使應用沒法正常運行的狀況。
更輕鬆的維護和擴展
Docker使用的分層存數以及鏡像的技術,使得應用重複部分的複用更爲容易,也使得應用的維護更新更加簡單,基於基礎鏡像進一步擴展鏡像也變得很是簡單,此外,Docker團隊同各個開源項目團隊一塊兒維護了一大批高質量的官方鏡像,既能夠直接在生產環境使用,又能夠做爲基礎進一步定製,大大的下降了應用服務的鏡像製做成本。
三、基本概念
鏡像(Image)
容器(Container)
倉庫(Repository)
理解了這三個概念,就理解了 Docker 的整個生命週期。
3.1 鏡像
Docker 鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建以後也不會被改變。
分層存儲
鏡像只是一個虛擬的概念,其實際體現並不是由一個文件組成,而是由一組文件系統組成,或者說,由多層文件系統聯合組成。
Union FS
聯合文件系統是(Union FS)是linux的存儲技術,也是Docker鏡像的存儲方式。 它是分層的文件系統,將不一樣目錄拉到同一個虛擬目錄下。下圖展現了Docker用Union FS 搭建的分層鏡像:(好比最下層是操做系統的引導,上一層是Linux操做系統,再上一層是Tomcat,jdk,再上一層是應用代碼)
這些層是隻讀的,加載完後這些文件會被當作是同一個目錄,至關於只有一個文件系統。
咱們能夠經過docker info查看鏡像的一些信息,能夠看到存儲驅動用的並非Union FS 而是overlay2,overlay也是一個聯合文件系統,因此上述主要介紹聯合文件系統的概念,至於這些存儲驅動的演變過程和優缺點,能夠閱讀http://dockone.io/article/1765。
鏡像構建時,會一層層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在本身這一層。(好比,刪除前一層文件的操做,實際不是真的刪除前一層的文件,而是僅在當前層標記爲該文件已刪除。在最終容器運行的時候,雖然不會看到這個文件,可是實際上該文件會一直跟隨鏡像。所以,在構建鏡像的時候,須要額外當心,每一層儘可能只包含該層須要添加的東西,任何額外的東西應該在該層構建結束前清理掉。)
分層存儲的特徵還使得鏡像的複用、定製變的更爲容易。甚至能夠用以前構建好的鏡像做爲基礎層,而後進一步添加新的層,以定製本身所需的內容,構建新的鏡像。
3.2 容器
鏡像(Image)和容器(Container)的關係,就像是面向對象程序設計中的 類 和 實例 同樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器能夠被建立、啓動、中止、刪除、暫停等。
容器的實質是進程,但與直接在宿主執行的進程不一樣,容器進程運行於屬於本身的獨立的命名空間。所以容器能夠擁有本身的 root 文件系統、本身的網絡配置、本身的進程空間,甚至本身的用戶 ID 空間。容器內的進程是運行在一個隔離的環境裏,使用起來,就好像是在一個獨立於宿主的系統下操做同樣。這種特性使得容器封裝的應用比直接在宿主運行更加安全。也由於這種隔離的特性,不少人初學 Docker 時經常會混淆容器和虛擬機。
前面講過鏡像使用的是分層存儲,容器也是如此。每個容器運行時,是以鏡像爲基礎層,在其上建立一個當前容器的存儲層,咱們能夠稱這個爲容器運行時讀寫而準備的存儲層爲容器存儲層。
容器存儲層的生存週期和容器同樣,容器消亡時,容器存儲層也隨之消亡。所以,任何保存於容器存儲層的信息都會隨容器刪除而丟失。
3.3 倉庫
鏡像構建完成後,能夠很容易的在當前宿主機上運行,可是,若是須要在其它服務器上使用這個鏡像,咱們就須要一個集中的存儲、分發鏡像的服務,Docker Registry 就是這樣的服務。
一個 Docker Registry 中能夠包含多個倉庫(Repository);每一個倉庫能夠包含多個標籤(Tag);每一個標籤對應一個鏡像。
一般,一個倉庫會包含同一個軟件不一樣版本的鏡像,而標籤就經常使用於對應該軟件的各個版本。咱們能夠經過 <倉庫名> : <標籤> 的格式來指定具體是這個軟件哪一個版本的鏡像。若是不給出標籤,將以 latest 做爲默認標籤。(以 Ubuntu 鏡像爲例,ubuntu 是倉庫的名字,其內包含有不一樣的版本標籤,如,14.04, 16.04。咱們能夠經過 ubuntu:14.04,或者 ubuntu:16.04 來具體指定所需哪一個版本的鏡像。若是忽略了標籤,好比 ubuntu,那將視爲 ubuntu:latest。)
倉庫名常常以兩段式路徑形式出現,好比 huangbaoling/nginx-proxy,前者每每意味着 Docker Registry 多用戶環境下的用戶名,後者則每每是對應的軟件名。但這並不是絕對,取決於所使用的具體 Docker Registry 的軟件或服務。