一绣溜、什么是Docker
官方文檔描述:“Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production.”
一句話概括容器:容器就是將軟件打包成標(biāo)準(zhǔn)化單元募胃,以用于開發(fā)、交付和部署。
Docker使用Google公司推出的Go語言進(jìn)行開發(fā)實現(xiàn),基于Linux內(nèi)核的cgroup,namespace孔厉,以及AUFS類的UnionFS等技術(shù)拯钻,對進(jìn)程進(jìn)行封裝隔離帖努,屬于操作系統(tǒng)層面的虛擬化技術(shù)。 由于隔離的進(jìn)程獨立于宿主和其它的隔離的進(jìn)程粪般,因此也稱其為容器拼余。Docke最初實現(xiàn)是基于LXC。
容器鏡像是輕量的亩歹、可執(zhí)行的獨立軟件包 匙监,包含軟件運(yùn)行所需的所有內(nèi)容:代碼、運(yùn)行時環(huán)境小作、系統(tǒng)工具亭姥、系統(tǒng)庫和設(shè)置。
容器化軟件適用于基于Linux和Windows的應(yīng)用顾稀,在任何環(huán)境中都能夠始終如一地運(yùn)行达罗。
容器賦予了軟件獨立性,使其免受外在環(huán)境差異(例如静秆,開發(fā)和預(yù)演環(huán)境的差異)的影響粮揉,從而有助于減少團(tuán)隊間在相同基礎(chǔ)設(shè)施上運(yùn)行不同軟件時的沖突。
再來看看容器較為通俗的解釋:
如果需要通俗的描述容器的話抚笔,我覺得容器就是一個存放東西的地方扶认,就像書包可以裝各種文具、衣柜可以放各種衣服殊橙、鞋架可以放各種鞋子一樣辐宾。我們現(xiàn)在所說的容器存放的東西可能更偏向于應(yīng)用比如網(wǎng)站、程序甚至是系統(tǒng)環(huán)境膨蛮。
二螃概、為什么要用Docker
- Docker的鏡像提供了除內(nèi)核外完整的運(yùn)行時環(huán)境,確保了應(yīng)用運(yùn)行環(huán)境一致性鸽疾,從而不會再出現(xiàn)“這段代碼在我機(jī)器上運(yùn)行沒問題啊”這類問題吊洼;--一致的運(yùn)行環(huán)境
- 可以做到秒級、甚至毫秒級的啟動時間制肮。大大的節(jié)約了開發(fā)冒窍,測試递沪,部署的時間。--更快速的啟動時間
- 避免公用的服務(wù)器综液,資源會容易受到其他用戶的影響款慨。--隔離性
- 善于處理集中爆發(fā)的服務(wù)器使用壓力。--彈性伸縮谬莹,快速擴(kuò)展
- 可以很輕易的將在一個平臺上運(yùn)行的應(yīng)用檩奠,遷移到另一個平臺上,而不用擔(dān)心運(yùn)行環(huán)境的變化導(dǎo)致應(yīng)用無法正常運(yùn)行的情況附帽。--遷移方便
- 使用Docker可以通過定制應(yīng)用鏡像來實現(xiàn)持續(xù)集成埠戳、持續(xù)交付、部署蕉扮。--持續(xù)交付和部署
三整胃、Docker容器與虛擬機(jī)的區(qū)別
簡單來說: 容器和虛擬機(jī)具有相似的資源隔離和分配優(yōu)勢,但功能有所不同喳钟,因為容器虛擬化的是操作系統(tǒng)屁使,而不是硬件,因此容器更容易移植奔则,效率也更高蛮寂。
傳統(tǒng)虛擬機(jī)技術(shù)是虛擬出一套硬件后,在其上運(yùn)行一個完整操作系統(tǒng)易茬,在該系統(tǒng)上再運(yùn)行所需應(yīng)用進(jìn)程酬蹋;而容器內(nèi)的應(yīng)用進(jìn)程直接運(yùn)行于宿主的內(nèi)核,容器內(nèi)沒有自己的內(nèi)核疾呻,而且也沒有進(jìn)行硬件虛擬除嘹。因此容器要比傳統(tǒng)虛擬機(jī)更為輕便。
兩者對比圖:
容器與虛擬機(jī) (VM) 總結(jié)
- 容器是一個應(yīng)用層抽象岸蜗,用于將代碼和依賴資源打包在一起尉咕。 多個容器可以在同一臺機(jī)器上運(yùn)行,共享操作系統(tǒng)內(nèi)核璃岳,但各自作為獨立的進(jìn)程在用戶空間中運(yùn)行 年缎。與虛擬機(jī)相比, 容器占用的空間較少(容器鏡像大小通常只有幾十兆)铃慷,瞬間就能完成啟動 单芜。
- 虛擬機(jī)(VM)是一個物理硬件層抽象,用于將一臺服務(wù)器變成多臺服務(wù)器犁柜。 管理程序允許多個VM在一臺機(jī)器上運(yùn)行洲鸠。每個VM都包含一整套操作系統(tǒng)、一個或多個應(yīng)用、必要的二進(jìn)制文件和庫資源扒腕,因此占用大量空間绢淀。而且VM啟動也十分緩慢 。
通過Docker官網(wǎng)瘾腰,我們知道了這么多Docker的優(yōu)勢皆的,但是大家也沒有必要完全否定虛擬機(jī)技術(shù),因為兩者有不同的使用場景蹋盆。虛擬機(jī)更擅長于徹底隔離整個運(yùn)行環(huán)境费薄。例如,云服務(wù)提供商通常采用虛擬機(jī)技術(shù)隔離不同的用戶栖雾。而Docker通常用于隔離不同的應(yīng)用 楞抡,例如前端,后端以及數(shù)據(jù)庫岩灭。就我目前項目而言拌倍,對于兩者無所謂誰會取代誰赂鲤,而是兩者可以和諧共存噪径。
容器與虛擬機(jī)(VM)兩者共存:
三、Docker的基本概念
Docker 中包括三個基本的概念:
- Image(鏡像)
- Container(容器)
- Repository(倉庫)
Image(鏡像)
鏡像是 Docker 運(yùn)行容器的前提数初,倉庫是存放鏡像的場所找爱,可見鏡像更是 Docker 的核心。
那么鏡像到底是什么呢泡孩?Docker 鏡像可以看作是一個特殊的文件系統(tǒng)车摄,除了提供容器運(yùn)行時所需的程序、庫仑鸥、資源吮播、配置等文件外,還包含了一些為運(yùn)行時準(zhǔn)備的一些配置參數(shù)(如匿名卷眼俊、環(huán)境變量意狠、用戶等)。
鏡像不包含任何動態(tài)數(shù)據(jù)疮胖,其內(nèi)容在構(gòu)建之后也不會被改變环戈。鏡像(Image)就是一堆只讀層(read-only layer)的統(tǒng)一視角,也許這個定義有些難以理解澎灸,下面的這張圖能夠幫助讀者理解鏡像的定義:
從左邊我們看到了多個只讀層院塞,它們重疊在一起。除了最下面一層性昭,其他層都會有一個指針指向下一層拦止。這些層是 Docker 內(nèi)部的實現(xiàn)細(xì)節(jié),并且能夠在主機(jī)的文件系統(tǒng)上訪問到糜颠。
統(tǒng)一文件系統(tǒng)(Union File System)技術(shù)能夠?qū)⒉煌膶诱铣梢粋€文件系統(tǒng)汹族,為這些層提供了一個統(tǒng)一的視角艺玲。這樣就隱藏了多層的存在,在用戶的角度看來鞠抑,只存在一個文件系統(tǒng)饭聚。我們可以在圖片的右邊看到這個視角的形式。
鏡像有多種生成方法:
從無到有開始創(chuàng)建鏡像
下載并使用別人創(chuàng)建好的現(xiàn)成的鏡像
在現(xiàn)有鏡像上創(chuàng)建新的鏡像
我們可以將鏡像的內(nèi)容和創(chuàng)建步驟描述在一個文本文件中搁拙,這個文件被稱作 Dockerfile 秒梳,通過執(zhí)行 docker build命令可以構(gòu)建出 Docker 鏡像。
Container容器
容器(Container)的定義和鏡像(Image)幾乎一模一樣箕速,也是一堆層的統(tǒng)一視角酪碘,唯一區(qū)別在于容器的最上面那一層是可讀可寫的。
由于容器的定義并沒有提及是否要運(yùn)行容器盐茎,所以實際上兴垦,容器 = 鏡像 + 讀寫層。
Repository(倉庫)
Docker倉庫是集中存放鏡像文件的場所字柠。鏡像構(gòu)建完成后探越,可以很容易的在當(dāng)前宿主上運(yùn)行。
但是窑业,如果需要在其他服務(wù)器上使用這個鏡像钦幔,我們就需要一個集中的存儲、分發(fā)鏡像的服務(wù)常柄,Docker Registory(倉庫注冊服務(wù)器)就是這樣的服務(wù)鲤氢。
有時候會把倉庫(Repository)和倉庫注冊服務(wù)器(Registry)混為一談,并不嚴(yán)格區(qū)分西潘。
Docker倉庫的概念跟 Git 類似卷玉,注冊服務(wù)器可以理解為 GitHub 這樣的托管服務(wù)。
所以說喷市,鏡像倉庫是 Docker 用來集中存放鏡像文件的地方相种,類似于我們之前常用的代碼倉庫。
通常东抹,一個倉庫會包含同一個軟件不同版本的鏡像蚂子,而標(biāo)簽就常用于對應(yīng)該軟件的各個版本 。
我們可以通過<倉庫名>:<標(biāo)簽>的格式來指定具體是這個軟件哪個版本的鏡像缭黔。如果不給出標(biāo)簽食茎,將以 Latest 作為默認(rèn)標(biāo)簽。
倉庫又可以分為兩種形式:
- Public(公有倉庫)
- Private(私有倉庫)
Docker Registry 公有倉庫是開放給用戶使用馏谨、允許用戶管理鏡像的 Registry 服務(wù)别渔。
一般這類公開服務(wù)允許用戶免費上傳、下載公開的鏡像,并可能提供收費服務(wù)供用戶管理私有鏡像哎媚。
除了使用公開服務(wù)外喇伯,用戶還可以在本地搭建私有 Docker Registry。Docker 官方提供了 Docker Registry 鏡像拨与,可以直接使用做為私有 Registry 服務(wù)稻据。
當(dāng)用戶創(chuàng)建了自己的鏡像之后就可以使用 Push 命令將它上傳到公有或者私有倉庫,這樣下次在另外一臺機(jī)器上使用這個鏡像時候买喧,只需要從倉庫上 Pull 下來就可以了捻悯。
以上我們主要把 Docker 的一些常見概念如 Image,Container淤毛,Repository 做了詳細(xì)的闡述今缚,也從傳統(tǒng)虛擬化方式的角度闡述了 Docker 的優(yōu)勢。
四低淡、Docker的架構(gòu)
Docker使用C/S結(jié)構(gòu)姓言,即客戶端/服務(wù)器體系結(jié)構(gòu)。Docker客戶端與Docker服務(wù)器進(jìn)行交互蔗蹋,Docker服務(wù)端負(fù)責(zé)構(gòu)建何荚、運(yùn)行和分發(fā)Docker鏡像。
Docker 客戶端和服務(wù)端可以運(yùn)行在一臺機(jī)器上纸颜,也可以通過 RESTful 兽泣、 Stock 或網(wǎng)絡(luò)接口與遠(yuǎn)程 Docker 服務(wù)端進(jìn)行通信绎橘。
這張圖展示了 Docker 客戶端胁孙、服務(wù)端和 Docker 倉庫(即 Docker Hub 和 Docker Cloud ),默認(rèn)情況下 Docker 會在 Docker 中央倉庫尋找鏡像文件称鳞。
這種利用倉庫管理鏡像的設(shè)計理念類似于 Git 涮较,當(dāng)然這個倉庫是可以通過修改配置來指定的,甚至我們可以創(chuàng)建我們自己的私有倉庫冈止。
五狂票、Docker常用命令
我們可以通過 docker -h 去查看命令的詳細(xì)的幫助文檔。在這里會講一些日常我們可能會用的比較多的一些命令熙暴。
例如闺属,我們需要拉取一個 Docker 鏡像,我們可以用如下命令:
docker pull image_name
image_name 為鏡像的名稱周霉,而如果我們想從 Docker Hub 上去下載某個鏡像掂器,我們可以使用以下命令:
docker pull centos:latest
cento:lastest 是鏡像的名稱,Docker Daemon 發(fā)現(xiàn)本地沒有我們需要的鏡像俱箱,會自動去 Docker Hub 上去下載鏡像国瓮,下載完成后,該鏡像被默認(rèn)保存到 /var/lib/docker 目錄下。
接著我們?nèi)绻氩榭粗鳈C(jī)下存在多少鏡像乃摹,我們可以用如下命令:
docker images
我們要想知道當(dāng)前有哪些容器在運(yùn)行禁漓,我們可以用如下命令:
docker ps -a
-a 是查看當(dāng)前所有的容器,包括未運(yùn)行的孵睬。我們該如何去對一個容器進(jìn)行啟動播歼,重啟和停止呢?
我們可以用如下命令:
docker start container_name/container_id
docker restart container_name/container_id
docker stop container_name/container_id
這個時候我們?nèi)绻脒M(jìn)入到這個容器中掰读,我們可以使用 attach 命令:
docker attach container_name/container_id
那如果我們想運(yùn)行這個容器中的鏡像的話荚恶,并且調(diào)用鏡像里面的 bash ,我們可以使用如下命令:
docker run -t -i container_name/container_id /bin/bash
那如果這個時候磷支,我們想刪除指定鏡像的話谒撼,由于 Image 被某個 Container 引用(拿來運(yùn)行),如果不將這個引用的 Container 銷毀(刪除)雾狈,那 Image 肯定是不能被刪除廓潜。
我們首先得先去停止這個容器:
docker ps
docker stop container_name/container_id
然后我們用如下命令去刪除這個容器:
docker rm container_name/container_id
然后這個時候我們再去刪除這個鏡像:
docker rmi image_name
常用的 Docker 相關(guān)的命令就講到這里為止了,我們在后續(xù)的文章中還會反復(fù)地提到這些命令善榛。