Dockek系列之-Docker介紹

一、Docker概覽

Docker是⼀個⽤於開發、交付和運⾏應⽤的開放平臺,Docker被設計⽤於更
快地交付應⽤。Docker可以將應⽤程序和基礎設施層隔離,並且可以將基礎
設施當作程序⼀樣進⾏管理。使⽤Docker,可以更快地打包代碼、測試以及
部署,並且可以減少從編寫到部署運⾏代碼的週期。
Docker將內核容器特性(LXC)、⼯作流和⼯具集成,以幫助管理和部署應
⽤。
在這裏插入圖片描述

二、什麼是Docker

核⼼是,Docker了⼀種在安全隔離的容器中運⾏近乎所有應⽤的⽅式,這種
隔離性和安全性允許你在同⼀個主機上同時運⾏多個容器,⽽容器的這種輕
量級特性,⽆需消耗運⾏hpervisor所需的額外負載,意味着你可以節省更多
的硬件資源。
基於容器虛擬化的⼯具或平臺可提供:

  • 將應⽤(包括⽀撐組件)放⼊Docker容器中
  • 分發和交付這些容器給團隊,便於後續的開發和測試
  • 將容器部署到⽣產環境中,⽣產環境可以是本地的數據中⼼,也可以在
    雲端。

⾃從上世紀 90 年代硬件虛擬化被主流的技術⼴泛普及之後,對數據中⼼⽽
⾔,發⽣的最⼤的變⾰莫過於容器和容器管理⼯具,例如:Docker。在過去
的⼀年內,Docker 技術已經逐漸⾛向成熟,並且推動了⼤型初創公司例如
Twitter 和 Airbnb 的發展,甚⾄在銀⾏、連鎖超市、甚⾄ NASA 的數據中⼼
都贏得了⼀席之地。當我⼏年前第⼀次直到 Docker 的時候,我還對 Docker
的未來持懷疑的態度,我認爲他們是把以前的 Linux 容器的概念拿出來包裝
了⼀番推向市場。但是使⽤ Docker 成功進⾏了⼏個項⽬ 例如 Spantree 之
後,我改變了我的看法:Docker 幫助我們節省了⼤量的時間和經歷,並且已
經成爲我們技術團隊中不可或缺的⼯具。 GitHub 上⾯每天都會催⽣出各式
各樣的⼯具、形態各異的語⾔和千奇百怪的概念。如果你和我⼀樣,沒有時
間去把他們全部都測試⼀遍,甚⾄沒有時間去親⾃測試 Docker,那麼你可以
看⼀下我的這篇⽂章:我將會⽤我們在 Docker 中總結的經驗來告訴你什麼
是 Docker、爲什麼 Docker 會這麼⽕。

2.1.Docker 是容器管理⼯具

Docker 是⼀個輕量級、便攜式、與外界隔離的容
器,也是⼀個可以在容器中很⽅便地構建、傳輸、運⾏應⽤的引擎。和傳統
的虛擬化技術不同的是,Docker 引擎並不虛擬出⼀臺虛擬機,⽽是直接使⽤
宿主機的內核和硬件,直接在宿主機上運⾏容器內應⽤。也正是得益於此,
Docker 容器內運⾏的應⽤和宿主機上運⾏的應⽤性能差距⼏乎可以忽略不
計。 但是 Docker 本身並不是⼀個容器系統,⽽是⼀個基於原有的容器化⼯
具 LXC ⽤來創建虛擬環境的⼯具。類似 LXC 的⼯具已經在⽣產環境中使⽤
多年,Docker 則基於此提供了更加友好的鏡像管理⼯具和部署⼯具。

2.2.Docker 不是虛擬化引擎

Docker 第⼀次發佈的時候,很多⼈都拿 Docker 和
虛擬機 VMware、KVM 和 VirtualBox ⽐較。儘管從功能上看,Docker 和虛
擬化技術致⼒於解決的問題都差不多,但是 Docker 卻是採取了另⼀種⾮常
不同的⽅式。虛擬機是虛擬出⼀套硬件,虛擬機的系統進⾏的磁盤操作,其
實都是在對虛擬出來的磁盤進⾏操作。當運⾏ CPU 密集型的任務時,是虛
擬機把虛擬系統⾥的 CPU 指令「翻譯」成宿主機的CPU指令並進⾏執⾏。兩個
磁盤層,兩個處理器調度器,兩個操作系統消耗的內存,所有虛擬出的這些
都會帶來相當多的性能損失,⼀臺虛擬機所消耗的硬件資源和對應的硬件相
當,⼀臺主機上跑太多的虛擬機之後就會過載。⽽ Docker 就沒有這種顧
慮。Docker 運⾏應⽤採取的是「容器」的解決⽅案:使⽤ namespace 和
CGroup 進⾏資源限制,和宿主機共享內核,不虛擬磁盤,所有的容器磁盤
操作其實都是對 /var/lib/docker/ 的操作。簡⾔之,Docker 其實只是在宿主機
中運⾏了⼀個受到限制的應⽤程序。 從上⾯不難看出,容器和虛擬機的概念
並不相同,容器也並不能取代虛擬機。在容器⼒所不能及的地⽅,虛擬機可
以⼤顯身⼿。例如:宿主機是 Linux,只能通過虛擬機運⾏ Windows,
Docker 便⽆法做到。再例如,宿主機是 Windows,Windows 並不能直接運
⾏ Docker,Windows上的 Docker 其實是運⾏在 VirtualBox 虛擬機⾥的。

2.3.Docker 使⽤層級的⽂件系統

前⾯提到過,Docker 和現有容器技術 LXC 等
相⽐,優勢之⼀就是 Docker 提供了鏡像管理。對於 Docker ⽽⾔,鏡像是⼀
個靜態的、只讀的容器⽂件系統的快照。然⽽不僅如此,Docker 中所有的磁
盤操作都是對特定的Copy-On-Write⽂件系統進⾏的。下⾯通過⼀個例⼦解
釋⼀下這個問題。 例如我們要建⽴⼀個容器運⾏ JAVA Web 應⽤,那麼我
們應該使⽤⼀個已經安裝了 JAVA 的鏡像。在 Dockerfile(⼀個⽤於⽣成鏡
像的指令⽂件)中,應該指明「基於 JAVA 鏡像」,這樣 Docker 就會去
Docker Hub Registry 上下載提前構建好的 JAVA 鏡像。然後再 Dockerfile 中
指明下載並解壓 Apache Tomcat 軟件到 /opt/tomcat ⽂件夾中。這條命令並
不會對原有的 JAVA 鏡像產⽣任何影響,⽽僅僅是在原有鏡像上⾯添加了⼀
個改動層。當⼀個容器啓動時,容器內的所有改動層都會啓動,容器會從第
⼀層中運⾏ /usr/bin/java 命令,並且調⽤另外⼀層中的 /opt/tomcat/bin 命
令。實際上,Dockerfile 中每⼀條指令都會產⽣⼀個新的改動層,即便只有
⼀個⽂件被改動。如果⽤過 Git 就能更清楚地認識這⼀點,每條指令就像是
每次 commit,都會留下記錄。但是對於 Docker 來說,這種⽂件系統提供了
更⼤的靈活性,也可以更⽅便地管理應⽤程序。 我們Spantree的團隊有⼀個
⾃⼰維護的含有 Tomcat 的鏡像。發佈新版本也⾮常簡單:使⽤ Dockerfile
將新版本拷⻉進鏡像從⽽創建⼀個新鏡像,然後給新鏡像貼上版本的標籤。
不同版本的鏡像的不同之處僅僅是⼀個 90 MB ⼤⼩的 WAR ⽂件,他們所基
於的主鏡像都是相同的。如果使⽤虛擬機去維護這些不同的版本的話,還要
消耗掉很多不同的磁盤去存儲相同的系統,⽽使⽤ Docker 就只需要很⼩的
磁盤空間。即便我們同時運⾏這個鏡像的很多實例,我們也只需要⼀個基礎
的 JAVA / TOMCAT 鏡像。

2.4.Docker 可以節約時間

很多年前我在爲⼀個連鎖餐廳開發軟件時,僅僅是爲
了描述如何搭建環境都需要寫⼀個 12 ⻚的 Word ⽂檔。例如本地 Oracle 數
據庫,特定版本的 JAVA,以及其他七七⼋⼋的系統⼯具和共享庫、軟件
包。整個搭建過程浪費掉了我們團隊每個⼈⼏乎⼀天的時間,如果⽤⾦錢衡
量的話,花掉了我們上萬美⾦的時間成本。雖然客戶已經對這種事情習以爲
常,甚⾄認爲這是引⼊新成員、讓成員適應環境、讓⾃⼰的員⼯適應我們的
軟件所必須的成本,但是相⽐較起來,我們寧願把更多的時間花在爲客戶構
建可以增進業務的功能上⾯。 如果當時有 Docker,那麼構建環境就會像使
⽤⾃動化搭建⼯具 Puppet / Chef / Salt / Ansible ⼀樣簡單,我們也可以把整
個搭建時間週期從⼀天縮短爲⼏分鐘。但是和這些⼯具不同的地⽅在於,
Docker 可以不僅僅可以搭建整個環境,還可以將整個環境保存成磁盤⽂件,
然後複製到別的地⽅。需要從源碼編譯 Node.js 嗎?Docker 做得到。Docker
不僅僅可以構建⼀個 Node.js 環境,還可以將整個環境做成鏡像,然後保存
到任何地⽅。當然,由於 Docker 是⼀個容器,所以不⽤擔⼼容器內執⾏的
東⻄會對宿主機產⽣任何的影響。 現在新加⼊我們團隊的⼈只需要運⾏
docker-compose up 命令,便可以喝杯咖啡,然後開始⼯作了。

2.5.Docker 可以節省開銷

當然,時間就是⾦錢。除了時間外,Docker 還可以節 省在基礎設施硬件上的開銷。⾼德納和⻨肯錫的研究表明,數據中⼼的利⽤ 率在 6% - 12% 左右。不僅如此,如果採⽤虛擬機的話,你還需要被動地監 控和設置每臺虛擬機的 CPU 硬盤和內存的使⽤率,因爲採⽤了靜態分區 (static partitioning)所以資源並不能完全被利⽤。。⽽容器可以解決這個問 題:容器可以在實例之間進⾏內存和磁盤共享。你可以在同⼀臺主機上運⾏ 多個服務、可以不⽤去限制容器所消耗的資源、可以去限制資源、可以在不 需要的時候停⽌容器,也不⽤擔⼼啓動已經停⽌的程序時會帶來過多的資源 消耗。凌晨三點的時候只有很少的⼈會去訪問你的⽹站,同時你需要⽐較多 的資源執⾏夜間的批處理任務,那麼可以很簡單的便實現資源的交換。 虛擬 機所消耗的內存、硬盤、CPU 都是固定的,⼀般動態調整都需要重啓虛擬 機。⽽⽤ Docker 的話,你可以進⾏資源限制,得益於 CGroup,可以很⽅便 動態調整資源限制,讓然也可以不進⾏資源限制。Docker 容器內的應⽤對宿 主機⽽⾔只是兩個隔離的應⽤程序,並不是兩個虛擬機,所以宿主機也可以 ⾃⾏去分配資源。