一奔则、Docker簡(jiǎn)介
Docker是什么?
Docker的英文本意是“搬運(yùn)工”先嬉,在程序員的世界里泵肄,Docker搬運(yùn)的是集裝箱(Container)煌寇,集裝箱里裝的是任意類型的App焕蹄,開發(fā)者通過(guò)Docker可以將App變成一種標(biāo)準(zhǔn)化的、可移植的阀溶、自管理的組件腻脏,可以在任何主流系統(tǒng)中開發(fā)、調(diào)試和運(yùn)行银锻。
說(shuō)白了,docker是一種用了新穎方式實(shí)現(xiàn)的輕量級(jí)虛擬機(jī),類似于VM,但是在原理和應(yīng)用上和VM的差別還是很大的.并且docker的專業(yè)叫法是應(yīng)用容器(Application Container)永品。
?為啥要用容器?
應(yīng)用容器是個(gè)啥樣子呢,一個(gè)做好的應(yīng)用容器長(zhǎng)得就像一個(gè)裝好了一組特定應(yīng)用的虛擬機(jī)一樣,比如我現(xiàn)在想用mysql,那我就找個(gè)裝好了mysql的容器就可以了,然后運(yùn)行起來(lái),我就能使用mysql了。
為啥不能直接安裝一個(gè)mysql?安裝一個(gè)SQL Server也可以啊,可是有的時(shí)候根據(jù)每個(gè)人電腦的不同,在安裝的時(shí)候可能會(huì)報(bào)出各種各樣的錯(cuò)誤,萬(wàn)一你的機(jī)器中毒了,你的電腦掛了,你所有的服務(wù)都需要重新安裝.但是有了docker,或者說(shuō)有了容器就不同了,你就相當(dāng)于有了一個(gè)可以運(yùn)行起來(lái)的虛擬機(jī),只要你能運(yùn)行容器,mysql的配置就省了.而且如果你想換個(gè)電腦,直接把容器”端過(guò)來(lái)”就可以使用容器里面的服務(wù).
Docker 基于 Go 語(yǔ)言開發(fā)击纬,代碼托管在Github上鼎姐,并遵循Apache 2.0 開源協(xié)議。Docker 容器可以封裝任何有效負(fù)載,幾乎可以在任何服務(wù)器之間進(jìn)行一致性運(yùn)行炕桨。換句話說(shuō)饭尝,開發(fā)者構(gòu)建的應(yīng)用只需一次構(gòu)建即可多平臺(tái)運(yùn)行。運(yùn)營(yíng)人員只需配置他們的服務(wù)献宫,即可運(yùn)行所有的應(yīng)用芋肠。
若是利用容器的話,那么開發(fā)直接在容器里開發(fā),測(cè)試的時(shí)候把整個(gè)容器給測(cè)試,測(cè)好了把測(cè)試后容器再上線就好了.通過(guò)容器,整個(gè)開發(fā),測(cè)試和生產(chǎn)環(huán)境可以保持高度一致。
此外容器也VM一樣具有一定得隔離性,各個(gè)容器之間的數(shù)據(jù)和內(nèi)存空間相互隔離,可以保證一定的安全性遵蚜。
Hyper-V帖池、KVM和Xen等虛擬機(jī)管理程序都“基于虛擬化硬件仿真機(jī)制。這意味著吭净,它們對(duì)系統(tǒng)要求很高.然而睡汹,容器卻使用共享的操作系統(tǒng)。這意味著它們?cè)谑褂孟到y(tǒng)資源方面比虛擬機(jī)管理程序要高效得多寂殉。容器不是對(duì)硬件進(jìn)行虛擬化處理囚巴,而是駐留在一個(gè)Linux實(shí)例上。
Docker可以解決虛擬機(jī)能夠解決的問題友扰,同時(shí)也能夠解決虛擬機(jī)由于資源要求過(guò)高而無(wú)法解決的問題彤叉。
為什么要使用docker?
1 村怪、快速交付應(yīng)用程序
?開發(fā)者使用一個(gè)標(biāo)準(zhǔn)的 image 來(lái)構(gòu)建開發(fā)容器秽浇,開發(fā)完成之后,系統(tǒng)管理員就可以使用這個(gè)容器來(lái)部署代碼
?docker可以快速創(chuàng)建容器甚负,快速迭代應(yīng)用程序柬焕,并讓整個(gè)過(guò)程可見,使團(tuán)隊(duì)中的其他成員更容易理解應(yīng)用程序是如何創(chuàng)建和工作的梭域。
?docker容器很輕斑举!很快!容器的啟動(dòng)時(shí)間是次秒級(jí)的病涨,節(jié)約開發(fā)富玷、測(cè)試、部署的時(shí)間
2 既穆、更容易部署和擴(kuò)展
?docker容器可以在幾乎所有的環(huán)境中運(yùn)行赎懦,物理機(jī)、虛擬機(jī)循衰、公有云铲敛、私有云、個(gè)人電腦会钝、服務(wù)器等等伐蒋。
?docker容器兼容很多平臺(tái)工三,這樣就可以把一個(gè)應(yīng)用程序從一個(gè)平臺(tái)遷移到另外一個(gè)。
3 先鱼、效率更高
?docker容器不需要 hypervisor 俭正,他是內(nèi)核級(jí)的虛擬化。
4 焙畔、快速部署也意味著更簡(jiǎn)單的管理
?通常只需要小小的改變就可以替代以往巨型和大量的更新工作掸读。
Docker的常用案例包括:
? 自動(dòng)打包和部署應(yīng)用
? 創(chuàng)建輕量、私有的 PaaS 環(huán)境
? 自動(dòng)化測(cè)試和持續(xù)集成/部署
? 部署并擴(kuò)展 Web 應(yīng)用宏多、數(shù)據(jù)庫(kù)和后端服務(wù)器
那么為啥不用VM?
那么既然容器和VM這么類似為啥不用VM?docker容器相對(duì)于VM還是有很多優(yōu)點(diǎn)的:
1.啟動(dòng)速度快,容器通常在一秒內(nèi)可以啟動(dòng).而VM要很久.
2.資源利用率高,一臺(tái)普通服務(wù)器可以跑上千個(gè)容器儿惫,而跑VM就。伸但。肾请。。更胖。铛铁。
3.性能開銷小,VM需要額外的CPU和內(nèi)存來(lái)完成OS的功能,這一部分占據(jù)了額外的資源.
為啥相似的功能在性能上會(huì)有如此巨大的差距呢?看一下他們的設(shè)計(jì)圖,先看VM的:
下面的圖片比較了 Docker 和傳統(tǒng)虛擬化方式的不同之處
可見容器是在操作系統(tǒng)層面上實(shí)現(xiàn)虛擬化,直接復(fù)用本地主機(jī)的操作系統(tǒng)却妨,而傳統(tǒng)方式則是在硬件層面實(shí)現(xiàn)饵逐。
Docker優(yōu)勢(shì)和劣勢(shì)
作為一種新興的虛擬化方式,Docker 跟傳統(tǒng)的虛擬化方式相比具有眾多的優(yōu)勢(shì)彪标。
首先倍权,Docker 容器的啟動(dòng)可以在秒級(jí)實(shí)現(xiàn),這相比傳統(tǒng)的虛擬機(jī)方式要快得多捐下。
其次账锹,Docker 對(duì)系統(tǒng)資源的利用率很高萌业,一臺(tái)主機(jī)上可以同時(shí)運(yùn)行數(shù)千個(gè) Docker 容器坷襟。
容器除了運(yùn)行其中應(yīng)用外,基本不消耗額外的系統(tǒng)資源生年,使得應(yīng)用的性能很高婴程,同時(shí)系統(tǒng)的開銷盡量小。傳統(tǒng)虛擬機(jī)方式運(yùn)行 10 個(gè)不同的應(yīng)用就要起 10 個(gè)虛擬機(jī)抱婉,而 Docker 只需要啟動(dòng) 10 個(gè)隔離的應(yīng)用即可档叔。
具體說(shuō)來(lái),Docker 在如下幾個(gè)方面具有較大的優(yōu)勢(shì)蒸绩。
更快速的交付和部署
對(duì)開發(fā)和運(yùn)維(devop)人員來(lái)說(shuō)衙四,最希望的就是一次創(chuàng)建或配置,可以在任意地方正常運(yùn)行患亿。開發(fā)者可以使用一個(gè)標(biāo)準(zhǔn)的鏡像來(lái)構(gòu)建一套開發(fā)容器传蹈,開發(fā)完成之后押逼,運(yùn)維人員可以直接使用這個(gè)容器來(lái)部署代碼。 Docker 可以快速創(chuàng)建容器惦界,快速迭代應(yīng)用程序挑格,并讓整個(gè)過(guò)程全程可見,使團(tuán)隊(duì)中的其他成員更容易理解應(yīng)用程序是如何創(chuàng)建和工作的沾歪。 Docker 容器很輕很快漂彤!容器的啟動(dòng)時(shí)間是秒級(jí)的,大量地節(jié)約開發(fā)灾搏、測(cè)試挫望、部署的時(shí)間。
更高效的虛擬化
Docker 容器的運(yùn)行不需要額外的 hypervisor 支持狂窑,它是內(nèi)核級(jí)的虛擬化士骤,因此可以實(shí)現(xiàn)更高的性能和效率。
更輕松的遷移和擴(kuò)展
Docker 容器幾乎可以在任意的平臺(tái)上運(yùn)行蕾域,包括物理機(jī)拷肌、虛擬機(jī)、公有云旨巷、私有云巨缘、個(gè)人電腦、服務(wù)器等采呐。這種兼容性可以讓用戶把一個(gè)應(yīng)用程序從一個(gè)平臺(tái)直接遷移到另外一個(gè)若锁。
更簡(jiǎn)單的管理
使用 Docker,只需要小小的修改斧吐,就可以替代以往大量的更新工作又固。所有的修改都以增量的方式被分發(fā)和更新,從而實(shí)現(xiàn)自動(dòng)化并且高效的管理煤率。
對(duì)比傳統(tǒng)虛擬機(jī)總結(jié)
特性容器虛擬機(jī)
啟動(dòng)秒級(jí)分鐘級(jí)
硬盤使用一般為MB一般為GB
性能接近原生弱于
系統(tǒng)支持量單機(jī)支持上千個(gè)容器?
二仰冠、Docker 的體系結(jié)構(gòu)
docker使用C/S 架構(gòu),docker daemon 作為 server 端接受 client 的請(qǐng)求蝶糯,并處理(創(chuàng)建洋只、運(yùn)行、分發(fā)容器)昼捍,他們可以運(yùn)行在一個(gè)機(jī)器上识虚,也通過(guò) socket或者 RESTful API通信
Docker
daemon 一般在宿主主機(jī)后臺(tái)運(yùn)行。
Docker
client以系統(tǒng)命令的形式存在妒茬,用戶用docker命令來(lái)跟docker daemon 交互担锤。
Docker守護(hù)進(jìn)程(Docker daemon)
如上圖所示,Docker 守護(hù)進(jìn)程運(yùn)行在一臺(tái)主機(jī)上乍钻。用戶并不直接和守護(hù)進(jìn)程進(jìn)行交互肛循,而是通過(guò) Docker 客戶端間接和其通信蛛株。
Docker客戶端(Docker client)Docker 客戶端,實(shí)際上是docker的二進(jìn)制程序育拨,是用戶與 Docker 交互方式谨履。它接收用戶指令并且與背后的 Docker 守護(hù)進(jìn)程通信。
Docker內(nèi)部:
要理解 Docker 內(nèi)部構(gòu)建熬丧,需要理解以下三種部件:
Docker鏡像- Docker images
Docker倉(cāng)庫(kù)- Docker registeries
Docker容器- Docker containers
Docker 鏡像
Docker鏡像是 Docker 容器運(yùn)行時(shí)的只讀模板笋粟,鏡像可以用來(lái)創(chuàng)建 Docker 容器。每一個(gè)鏡像由一系列的層 (layers) 組成析蝴。Docker 使用UnionFS(聯(lián)合文件系統(tǒng))來(lái)將這些層聯(lián)合到單獨(dú)的鏡像中害捕。UnionFS允許獨(dú)立文件系統(tǒng)中的文件和文件夾(稱之為分支)被透明覆蓋,形成一個(gè)單獨(dú)連貫的文件系統(tǒng)闷畸。正因?yàn)橛辛诉@些層的存在尝盼,Docker 是如此的輕量。當(dāng)你改變了一個(gè) Docker 鏡像佑菩,比如升級(jí)到某個(gè)程序到新的版本盾沫,一個(gè)新的層會(huì)被創(chuàng)建。因此殿漠,不用替換整個(gè)原先的鏡像或者重新建立(在使用虛擬機(jī)的時(shí)候你可能會(huì)這么做)赴精,只是一個(gè)新的層被添加或升級(jí)了。現(xiàn)在你不用重新發(fā)布整個(gè)鏡像绞幌,只需要升級(jí)蕾哟,層使得分發(fā) Docker 鏡像變得簡(jiǎn)單和快速。
每個(gè)docker都有很多層次構(gòu)成莲蜘,docker使用? unionfile systems? 將這些不同的層結(jié)合到一個(gè)image 中去谭确。
例如:centos鏡像中安裝nginx,就成了nginx鏡像”票渠,其實(shí)在此時(shí)Docker鏡像的層級(jí)概念就體現(xiàn)出來(lái)了逐哈。底層一個(gè)centos操作系統(tǒng)鏡像,上面疊加一個(gè)ngnx層庄新,就完成了一個(gè)nginx鏡像的構(gòu)建鞠眉。層級(jí)概念就不難理解,此時(shí)我們一般centos操作系統(tǒng)鏡像稱為nginx鏡像層的父鏡像择诈。
Docker 倉(cāng)庫(kù)
Docker 倉(cāng)庫(kù)用來(lái)保存鏡像,可以理解為代碼控制中的代碼倉(cāng)庫(kù)出皇。同樣的羞芍,Docker 倉(cāng)庫(kù)也有公有和私有的概念。公有的 Docker 倉(cāng)庫(kù)名字是 Docker Hub郊艘。Docker Hub 提供了龐大的鏡像集合供使用荷科。這些鏡像可以是自己創(chuàng)建唯咬,或者在別人的鏡像基礎(chǔ)上創(chuàng)建。
倉(cāng)庫(kù)是集中存放鏡像文件的場(chǎng)所畏浆。有時(shí)候會(huì)把倉(cāng)庫(kù)和倉(cāng)庫(kù)注冊(cè)服務(wù)器(Registry)混為一談胆胰,并不嚴(yán)格區(qū)分。實(shí)際上刻获,倉(cāng)庫(kù)注冊(cè)服務(wù)器上往往存放著多個(gè)倉(cāng)庫(kù)蜀涨,每個(gè)倉(cāng)庫(kù)中又包含了多個(gè)鏡像,每個(gè)鏡像有不同的標(biāo)簽(tag)蝎毡。
倉(cāng)庫(kù)分為公開倉(cāng)庫(kù)(Public)和私有倉(cāng)庫(kù)(Private)兩種形式厚柳。
最大的公開倉(cāng)庫(kù)是 Docker Hub,存放了數(shù)量龐大的鏡像供用戶下載沐兵。國(guó)內(nèi)的公開倉(cāng)庫(kù)包括 Docker Pool等别垮,可以提供大陸用戶更穩(wěn)定快速的訪問。
當(dāng)然扎谎,用戶也可以在本地網(wǎng)絡(luò)內(nèi)創(chuàng)建一個(gè)私有倉(cāng)庫(kù)碳想。
當(dāng)用戶創(chuàng)建了自己的鏡像之后就可以使用push命令將它上傳到公有或者私有倉(cāng)庫(kù),這樣下次在另外一臺(tái)機(jī)器上使用這個(gè)鏡像時(shí)候毁靶,只需要從倉(cāng)庫(kù)上pull下來(lái)就可以了移袍。
*注:Docker 倉(cāng)庫(kù)的概念跟Git類似,注冊(cè)服務(wù)器可以理解為 GitHub 這樣的托管服務(wù)老充。
Docker 容器
Docker利用容器來(lái)運(yùn)行應(yīng)用葡盗,一個(gè)Docker容器包含了所有的某個(gè)應(yīng)用運(yùn)行所需要的環(huán)境。每一個(gè) Docker 容器都是從 Docker 鏡像創(chuàng)建的啡浊。Docker 容器可以運(yùn)行觅够、開始、停止巷嚣、移動(dòng)和刪除喘先。每一個(gè) Docker 容器都是獨(dú)立和安全的應(yīng)用平臺(tái)。
容器是從鏡像創(chuàng)建的運(yùn)行實(shí)例廷粒。它可以被啟動(dòng)窘拯、開始、停止坝茎、刪除涤姊。每個(gè)容器都是相互隔離的、保證安全的平臺(tái)嗤放。
可以把容器看做是一個(gè)簡(jiǎn)易版的 Linux 環(huán)境(包括root用戶權(quán)限思喊、進(jìn)程空間、用戶空間和網(wǎng)絡(luò)空間等)和運(yùn)行在其中的應(yīng)用程序次酌。
*注:鏡像是只讀的恨课,容器在啟動(dòng)的時(shí)候創(chuàng)建一層可寫層作為最上層舆乔。
與虛擬機(jī)相比,容器有一個(gè)很大的差異剂公,它們被設(shè)計(jì)用來(lái)運(yùn)行"單進(jìn)程"希俩,無(wú)法很好地模擬一個(gè)完整的環(huán)境。Docker設(shè)計(jì)者極力推崇“一個(gè)容器一個(gè)進(jìn)程的方式”纲辽,如果你要選擇在一個(gè)容器中運(yùn)行多個(gè)進(jìn)程颜武,那唯一情況是:出于調(diào)試目的。
容器是設(shè)計(jì)來(lái)運(yùn)行一個(gè)應(yīng)用的文兑,而非一臺(tái)機(jī)器盒刚。你可能會(huì)把容器當(dāng)虛擬機(jī)用,但你將失去很多的靈活性绿贞,因?yàn)镈ocker提供了用于分離應(yīng)用與數(shù)據(jù)的工具因块,使得你可以快捷地更新運(yùn)行中的代碼/系統(tǒng),而不影響數(shù)據(jù)籍铁。
Docker 從 0.9 版本開始使用libcontainer 替代 lxc涡上,libcontainer和 Linux 系統(tǒng)的交互圖如下:
Docker? 底層技術(shù)
docker底層的 2 個(gè)核心技術(shù)分別是 Namespaces 和Control groups
Namespaces用來(lái)隔離各個(gè)容器
1)pidnamespace
不同用戶的進(jìn)程就是通過(guò)pid namespace 隔離開的,且不同?namespace? 中可以有相同pid拒名。所有的LXC進(jìn)程在docker中的父進(jìn)程為docker進(jìn)程吩愧,每個(gè)lxc進(jìn)程具有不同的 namespace 。
2) netnamespace
有了pid namespace,? 每個(gè) namespace 中的pid能夠相互隔離增显,但是網(wǎng)絡(luò)端口還是共享 host 的端口雁佳。網(wǎng)絡(luò)隔離是通過(guò) net namespace 實(shí)現(xiàn)的,每個(gè) net namespace 有獨(dú)立的?network devices, IP addresses, IP routing tables, /proc/net? 目錄同云。這樣每個(gè) container 的網(wǎng)絡(luò)就能隔離開來(lái)糖权。docker默認(rèn)采用veth的方式將 container 中的虛擬網(wǎng)卡同 host 上的一個(gè)docker bridge: docker0 連接在一起。
3) ipcnamespace
container中進(jìn)程交互還是采用linux常見的進(jìn)程間交互方法 (interprocess communication -
IPC),包括常見的信號(hào)量炸站、消息隊(duì)列和共享內(nèi)存星澳。container? 的進(jìn)程間交互實(shí)際上還是host 上具有相同pid namespace 中的進(jìn)程間交互。
4) mntnamespace
類似chroot旱易,將一個(gè)進(jìn)程放到一個(gè)特定的目錄執(zhí)行禁偎。mnt namespace 允許不同 namespace 的進(jìn)程看到的文件結(jié)構(gòu)不同,這樣每個(gè)?namespace? 中的進(jìn)程所看到的文件目錄就被隔離開了阀坏。在container里頭如暖,看到的文件系統(tǒng),就是一個(gè)完整的linux系統(tǒng)全释,有/etc装处、/lib 等,通過(guò)chroot實(shí)現(xiàn)浸船。
5) utsnamespace
UTS("UNIX
Time-sharing System") namespace 允許每個(gè) container 擁有獨(dú)立的 hostname 和domain name,?使其在網(wǎng)絡(luò)上可以被視作一個(gè)獨(dú)立的節(jié)點(diǎn)而非 Host 上的一個(gè)進(jìn)程妄迁。
6)user namespace
每個(gè) container 可以有不同的?user? 和?group id,? 也就是說(shuō)可以在 container 內(nèi)部用 container 內(nèi)部的用戶執(zhí)行程序而非 Host 上的用戶。
有了以上 6 種 namespace 從進(jìn)程李命、網(wǎng)絡(luò)登淘、IPC、文件系統(tǒng)封字、UTS和用戶角度的隔離黔州,一個(gè) container 就可以對(duì)外展現(xiàn)出一個(gè)獨(dú)立計(jì)算機(jī)的能力,并且不同 container 從 OS 層面實(shí)現(xiàn)了隔離阔籽。然而不同 namespace 之間資源還是相互競(jìng)爭(zhēng)的流妻,仍然需要類似ulimit來(lái)管理每個(gè) container 所能使用的資源 - -cgroup。
cgroups(Control groups)實(shí)現(xiàn)了對(duì)資源的配額和度量笆制。