Docker簡介
什么是Docker
Docker最初是dotCloud公司創(chuàng)始人Solomon Hykes發(fā)起的一個公司內部項目椭豫,它是基于dotCloud公司多年云服務技術的一次革新峡碉,并于2013年3月以 Apache 2.0授權協(xié)議開源抄课,主要項目代碼在GitHub上進行維護归形。Docker項目后來還加入了Linux基金會糯景,并成立推動開放容器聯(lián)盟(OCI)拴泌。
Docker自開源后受到廣泛的關注和討論,至今其GitHub項目已經超過5萬7千個星標和一萬多個fork肛炮。甚至由于Docker項目的火爆止吐,在2013年底,dotCloud公司決定改名為Docker侨糟。Docker最初是在Ubuntu 12.04上開發(fā)實現(xiàn)的碍扔;Red Hat則從RHEL 6.5開始對Docker進行支持;Google也在其PaaS產品中廣泛應用Docker秕重。
Docker使用Google公司推出的Go 語言進行開發(fā)實現(xiàn)不同,基于Linux內核的cgroup,namespace溶耘,以及OverlayFS類的Union FS等技術二拐,對進程進行封裝隔離,屬于操作系統(tǒng)層面的虛擬化技術凳兵。由于隔離的進程獨立于宿主和其它的隔離的進程百新,因此也稱其為容器。最初實現(xiàn)是基于LXC庐扫,從0.7版本以后開始去除LXC饭望,轉而使用自行開發(fā)的libcontainer,從1.11開始形庭,則進一步演進為使用runC和containerd铅辞。
runc是一個Linux命令行工具,用于根據(jù)OCI容器運行時規(guī)范創(chuàng)建和運行容器
containerd是一個守護程序萨醒,它管理容器生命周期斟珊,提供了在一個節(jié)點上執(zhí)行容器和管理鏡像的最小功能集
Docker在容器的基礎上,進行了進一步的封裝验靡,從文件系統(tǒng)倍宾、網絡互聯(lián)到進程隔離等等雏节,極大的簡化了容器的創(chuàng)建和維護胜嗓。使得Docker技術比虛擬機技術更為輕便高职、快捷。
為什么要用Docker
傳統(tǒng)虛擬機技術是虛擬出一套硬件后辞州,在其上運行一個完整操作系統(tǒng)怔锌,在該系統(tǒng)上再運行所需應用進程;而容器內的應用進程直接運行于宿主的內核变过,容器內沒有自己的內核埃元,而且也沒有進行硬件虛擬。作為一種新興的虛擬化方式媚狰,Docker跟傳統(tǒng)的虛擬化方式相比具有眾多的優(yōu)勢岛杀。
更高效的系統(tǒng)資源利用
由于容器不需要進行硬件虛擬以及運行完整操作系統(tǒng)等額外開銷,Docker對系統(tǒng)資源的利用率更高崭孤。無論是應用執(zhí)行速度类嗤、內存損耗或者文件存儲速度,都要比傳統(tǒng)虛擬機技術更高效辨宠。因此遗锣,相比虛擬機技術,一個相同配置的主機嗤形,往往可以運行更多數(shù)量的應用精偿。
更快速的啟動時間
傳統(tǒng)的虛擬機技術啟動應用服務往往需要數(shù)分鐘,而Docker容器應用赋兵,由于直接運行于宿主內核笔咽,無需啟動完整的操作系統(tǒng),因此可以做到秒級霹期、甚至毫秒級的啟動時間叶组。大大的節(jié)約了開發(fā)、測試经伙、部署的時間扶叉。
一致的運行環(huán)境
開發(fā)過程中一個常見的問題是環(huán)境一致性問題。由于開發(fā)環(huán)境帕膜、測試環(huán)境枣氧、生產環(huán)境不一致,導致有些bug并未在開發(fā)過程中被發(fā)現(xiàn)垮刹。而Docker的鏡像提供了除內核外完整的運行時環(huán)境达吞,確保了應用運行環(huán)境一致性,從而不會再出現(xiàn) “這段代碼在我機器上沒問題啊” 這類問題荒典。
持續(xù)交付和部署
使用Docker可以通過定制應用鏡像來實現(xiàn)持續(xù)集成酪劫、持續(xù)交付吞鸭、部署。開發(fā)人員可以通過Dockerfile來進行鏡像構建覆糟,并結合持續(xù)集成系統(tǒng)進行集成測試刻剥,而運維人員則可以直接在生產環(huán)境中快速部署該鏡像,甚至結合持續(xù)部署系統(tǒng)進行自動部署滩字。
而且使用Dockerfile使鏡像構建透明化造虏,不僅僅開發(fā)團隊可以理解應用運行環(huán)境,也方便運維團隊理解應用運行所需條件麦箍,幫助更好的生產環(huán)境中部署該鏡像漓藕。
更輕松的遷移
由于Docker確保了執(zhí)行環(huán)境的一致性,使得應用的遷移更加容易挟裂。Docker可以在很多平臺上運行享钞,無論是物理機、虛擬機诀蓉、公有云栗竖、私有云,甚至是筆記本交排,其運行結果是一致的划滋。因此用戶可以很輕易的將在一個平臺上運行的應用,遷移到另一個平臺上埃篓,而不用擔心運行環(huán)境的變化導致應用無法正常運行的情況处坪。
更輕松的維護和擴展
Docker使用的分層存儲以及鏡像的技術,使得應用重復部分的復用更為容易架专,也使得應用的維護更新更加簡單同窘,基于基礎鏡像進一步擴展鏡像也變得非常簡單。此外部脚,Docker團隊同各個開源項目團隊一起維護了一大批高質量的官方鏡像想邦,既可以直接在生產環(huán)境使用,又可以作為基礎進一步定制委刘,大大的降低了應用服務的鏡像制作成本丧没。
對比傳統(tǒng)虛擬機
特性 | 容器 | 虛擬機 |
---|---|---|
啟動 | 秒級 | 分鐘級 |
硬盤使用 | 一般為MB | 一般為GB |
性能 | 接近原生 | 弱于 |
系統(tǒng)支持量 | 單機支持上千個容器 | 一般幾十個 |
基本概念
Docker包括三個基本概念
鏡像(
Image
)容器(
Container
)倉庫(
Repository
)
理解了這三個概念,就理解了Docker的整個生命周期锡移。
鏡像
操作系統(tǒng)分為內核空間和用戶空間呕童。對于Linux而言,內核啟動后淆珊,會掛載root文件系統(tǒng)為其提供用戶空間支持夺饲。而Docker鏡像(Image),就相當于是一個root文件系統(tǒng)。比如官方鏡像ubuntu:18.04就包含了完整的一套Ubuntu 18.04最小系統(tǒng)的root文件系統(tǒng)往声。
Docker鏡像是一個特殊的文件系統(tǒng)擂找,除了提供容器運行時所需的程序、庫浩销、資源贯涎、配置等文件外,還包含了一些為運行時準備的一些配置參數(shù)(如匿名卷撼嗓、環(huán)境變量柬采、用戶等)欢唾。鏡像不包含任何動態(tài)數(shù)據(jù)且警,其內容在構建之后也不會被改變。
因為鏡像包含操作系統(tǒng)完整的root文件系統(tǒng)礁遣,其體積往往是龐大的斑芜,因此在Docker設計時,就充分利用Union FS的技術祟霍,將其設計為分層存儲的架構杏头。所以嚴格來說,鏡像并非是像一個ISO那樣的打包文件沸呐,鏡像只是一個虛擬的概念醇王,其實際體現(xiàn)并非由一個文件組成,而是由一組文件系統(tǒng)組成崭添,或者說寓娩,由多層文件系統(tǒng)聯(lián)合組成。
鏡像構建時呼渣,會一層層構建棘伴,前一層是后一層的基礎。每一層構建完就不會再發(fā)生改變屁置,后一層上的任何改變只發(fā)生在自己這一層焊夸。比如,刪除前一層文件的操作蓝角,實際不是真的刪除前一層的文件阱穗,而是僅在當前層標記為該文件已刪除。在最終容器運行的時候使鹅,雖然不會看到這個文件揪阶,但是實際上該文件會一直跟隨鏡像。因此并徘,在構建鏡像的時候遣钳,需要額外小心,每一層盡量只包含該層需要添加的東西,任何額外的東西應該在該層構建結束前清理掉蕴茴。
分層存儲的特征還使得鏡像的復用劝评、定制變的更為容易。甚至可以用之前構建好的鏡像作為基礎層倦淀,然后進一步添加新的層蒋畜,以定制自己所需的內容,構建新的鏡像撞叽。
容器
鏡像(Image
)和容器(Container
)的關系姻成,就像是面向對象程序設計中的類和實例一樣,鏡像是靜態(tài)的定義愿棋,容器是鏡像運行時的實體科展。容器可以被創(chuàng)建、啟動糠雨、停止才睹、刪除、暫停等甘邀。
容器的實質是進程琅攘,但與直接在宿主執(zhí)行的進程不同,容器進程運行于屬于自己的獨立的namespace松邪。因此容器可以擁有自己的root文件系統(tǒng)坞琴、自己的網絡配置、自己的進程空間逗抑,甚至自己的用戶ID空間剧辐。容器內的進程是運行在一個隔離的環(huán)境里,使用起來锋八,就好像是在一個獨立于宿主的系統(tǒng)下操作一樣浙于。這種特性使得容器封裝的應用比直接在宿主運行更加安全。
前面講過鏡像使用的是分層存儲挟纱,容器也是如此羞酗。每一個容器運行時,是以鏡像為基礎層紊服,在其上創(chuàng)建一個當前容器的存儲層檀轨,我們可以稱這個為容器運行時讀寫而準備的存儲層為容器存儲層。
容器存儲層的生存周期和容器一樣欺嗤,容器消亡時参萄,容器存儲層也隨之消亡。因此煎饼,任何保存于容器存儲層的信息都會隨容器刪除而丟失讹挎。
倉庫
鏡像構建完成后,可以很容易的在當前宿主機上運行,但是筒溃,如果需要在其它服務器上使用這個鏡像马篮,我們就需要一個集中的存儲、分發(fā)鏡像的服務怜奖,Docker Registry就是這樣的服務浑测。
一個Docker Registry中可以包含多個倉庫(Repository
);每個倉庫可以包含多個標簽(Tag
)歪玲;每個標簽對應一個鏡像迁央。
通常,一個倉庫會包含同一個軟件不同版本的鏡像滥崩,而標簽就常用于對應該軟件的各個版本岖圈。我們可以通過<倉庫名>:<標簽>
的格式來指定具體是這個軟件哪個版本的鏡像,如果不給出標簽夭委,將以latest
作為默認標簽幅狮。
以Ubuntu
鏡像為例,ubuntu
是倉庫的名字株灸,其內包含有不同的版本標簽滩届,如16.04洛口、18.04。我們可以通過ubuntu:16.04
膏燕,或者ubuntu:18.04
來具體指定所需哪個版本的鏡像鸠儿。如果忽略了標簽屹蚊,比如ubuntu
,那將視為ubuntu:latest
进每。
倉庫名經常以兩段式路徑形式出現(xiàn)汹粤,比如jwilder/nginx-proxy
,前者往往意味著Docker Registry多用戶環(huán)境下的用戶名田晚,后者則往往是對應的軟件名嘱兼。但這并非絕對,取決于所使用的具體Docker Registry的軟件或服務贤徒。
Docker Registry公開服務
Docker Registry公開服務是開放給用戶使用芹壕、允許用戶管理鏡像的Registry服務。一般這類公開服務允許用戶免費上傳接奈、下載公開的鏡像踢涌,并可能提供收費服務供用戶管理私有鏡像。
最常使用的Registry公開服務是官方的Docker Hub序宦,這也是默認的Registry睁壁,并擁有大量的高質量的官方鏡像。除此以外,還有Red Hat的Quay.io潘明;Google的Google Container Registry糠惫,Kubernetes的鏡像使用的就是這個服務。
由于某些原因钉疫,在國內訪問這些服務可能會比較慢硼讽。國內的一些云服務商提供了針對Docker Hub的鏡像服務(Registry Mirror
),這些鏡像服務被稱為加速器牲阁。常見的有阿里云加速器固阁、DaoCloud 加速器等。使用加速器會直接從國內的地址下載Docker Hub的鏡像城菊,比直接從Docker Hub下載速度會提高很多备燃。
國內也有一些云服務商提供類似于Docker Hub的公開服務。比如網易云鏡像服務凌唬、DaoCloud鏡像市場并齐、阿里云鏡像庫等。
私有Docker Registry
除了使用公開服務外客税,用戶還可以在本地搭建私有Docker Registry况褪。Docker官方提供了Docker Registry鏡像,可以直接使用做為私有Registry服務更耻。
開源的Docker Registry鏡像只提供了Docker Registry API的服務端實現(xiàn)测垛,足以支持docker命令,不影響使用秧均。但不包含圖形界面食侮,以及鏡像維護、用戶管理目胡、訪問控制等高級功能锯七。在官方的商業(yè)化版本Docker Trusted Registry中,提供了這些高級功能誉己。
除了官方的Docker Registry外眉尸,還有第三方軟件實現(xiàn)了Docker Registry API,甚至提供了用戶界面以及一些高級功能巫延,比如Harbor和Nexus效五。