歡迎你們前往騰訊雲社區,獲取更多騰訊海量技術實踐乾貨哦~mysql
做者丨唐文廣:騰訊工程師,負責無線研發部地圖測試。linux
導語:Docker,近兩年才流行起來的超輕量級虛擬機,它可讓你輕鬆完成持續集成、自動交付、自動部署,而且實現開發環境、測試環境、運維環境三方環境的真正同步。本文從Docker定義,做用,技術架構,安裝和使用等全方位帶你看懂Docker。git
打開翻譯君輸入Docker 結果顯示碼頭工人,沒錯!碼頭工人搬運的是集裝箱,那麼今天要講的Docker其操做的也是集裝箱,這個集裝箱就靜態而言就是一個應用鏡像文件,就動態而言,就是一個容器。蒙了吧?好吧,上圖解釋。
github
Docker從狹義上來說就是一個進程,從廣義上來說是一個虛擬容器,其實更專業的叫法是應用容器( Application Container ),Docker進程和普通的進程沒有任何區別,它就是一個普通的應用進程。不過是用來操做鏡像文件的。因此Docker進程+構建的應用鏡像文件就等於Docker容器。本文全部講的Docker都是指Docker容器哦。redis
再繼續下文以前咱們首先要明確幾個docker重要的基本概念吧,鏡像,容器,倉庫。sql
鏡像Docker images,就相似於VM虛擬機裏面的快照,可是可比快照輕量化多了。快照不懂?那能夠把images直接理解成一個文件夾。咱們能夠經過ID或者易識別的名字+tag來確認惟一的目標鏡像。ImagesID是一個64位的字符,可是通常咱們都是使用前面12位就足夠區別了。
docker
如圖中左邊紅框中redis: lates和右邊的紅框中5f515359c7f8都惟一表示爲同一個鏡像。因此咱們通常的鏡像能夠命名爲相似centos:latest、centos:centos7.1.1503等等。數據庫
鏡像是分層的,有基礎鏡像,僅僅包含操做系統,好比centos鏡像;有中間件鏡像,好比redis等數據庫鏡像;最後是應用鏡像,就是指具體的應用服務了,應用鏡像能夠很是豐富,隨時能夠發佈,這三者之間依次疊加。json
因此當咱們在使用 Docker構建鏡像的時候,每個命令都會在前一個命令的基礎上造成一個新鏡像層。以下圖,基礎鏡像就是centos鏡像,中間件鏡像就是兩個紅色圈,應用鏡像就是紫色圈。其中redis+centos這樣疊加組合的中間件鏡像就能夠供A服務或者B服務使用,這樣疊加組合更加靈活。仍和一種鏡像均可以從Docker hub公共倉庫中拉取。
後端
容器Docker containers,你能夠從鏡像中建立容器,這如同從快照中建立虛擬機,不過更輕量,啓動更快,秒啓。應用是在容器中運行的,打個比方,你首先下載了一個Ubuntu的鏡像,而後又安裝mysql和Django應用及其依賴,來完成對它Ubutun鏡像的修改,一個我的以爲很是完美應用鏡像生成了!就把這個鏡像分享給你們使用,你們經過這個鏡像就生成一個容器。容器啓動以後就會運行Django服務了。
上面也說到了,容器就是一個個獨立的封閉的集裝箱,可是也須要對外提供服務的,因此Docker容許公開容器的特定端口,在啓動Docker的時候,咱們就能夠將容器的特定端口映射到宿主機上面的任意一個端口,因此,若是幾個服務都須要80端口,那麼容器的對外端口是80,可是映射到宿主機上面就是任意端口,就不會產生衝突,因此就不須要經過代理來解決衝突。容器對外端口與宿主機的端口映射能夠經過下面的命令來完成。
啓動docker容器
docker run -d -p 2222:22 --name 容器名 鏡像名
-d 守護容器,就是後臺運行,退出命令窗口容器也不會中止
-it 交互式容器 退出命令窗口容器就中止運行了
-p宿主機端口和容器端口映射
8081:80 宿主機端口:容器公開的端口
倉庫Docker registeries,docker倉庫和存放集裝箱的倉庫是同樣的,不過docker使用來存放鏡像的。倉庫存在公有和私有之分,公有倉庫docker hub提供了很是多的鏡像文件,這些鏡像直接拉取下來就能夠運行了,你也能夠上傳本身的鏡像到docker hub上面。同時也能夠本身搭建私有倉庫用於團隊項目管理。
結合前面介紹的基本概念,咱們能夠將docker的幾個概念使用大體串起來,他們之間是如何運做的,也就是Docker的生命週期。看下圖,主要是三步走。
一、 開發構建鏡像並將鏡像push到Docker倉庫
二、 測試或者運維從Docker倉庫拷貝一份鏡像到本地
三、 經過鏡像文件開啓Docker容器並提供服務
爲啥要用Docker?這要從目前軟件行業的痛點來說起 一、軟件更新發布及部署低效,過程繁瑣且須要人工介入,二、環境一致性難以保證,三、不一樣環境之間遷移成本過高。有了Docker能夠很大程度解決上面的問題。
首先,Docker的使用簡單至極,從開發的角度來看就是三步走:構建,運輸,運行。其中關鍵步驟就是構建環節,即打包鏡像文件。可是從測試和運維的角度來看,那就只有兩步:複製,運行。有了這個鏡像,那麼想複製到哪運行均可以,徹底和平臺無關了。同時Docker這種容器技術隔離出了獨立的運行空間,不會和其餘應用爭用系統資源了以及還不須要考慮應用之間相互影響,想一想就開心。
其次,由於在構建鏡像的時候就處理完了服務程序對於系統的全部依賴,因此在你使用的時候,你能夠忽略掉本來程序的依賴以及開發語言。對測試和運維而言,更多專一於本身的業務內容上。
最後,Docker於開發者而言提供了一種開發環境的管理辦法,與測試人員而言保證了環境的同步,於運維人員提供了可移植的標準化部署流程。
因此, Docker 能幹啥,總結以下:
Docker是個進程級的輕量化虛擬機,和傳統虛擬機有啥區別呢?
Docker這個虛擬機超級輕量級,僅僅是一個進程而已。與傳統的虛擬機好比VM有着巨大的差異,區別看下圖:
咱們來看一下兩者的區別,由於 VM 的 Hypervisor 須要實現對硬件的虛擬化,而且還要搭載本身的操做系統,其中虛擬機操做系統佔用內存是比較大的,一個操做系統有好幾個G,天然在啓動速度和資源利用率以及性能上有很是大的開銷,若是在本地,或者我的電腦,那麼影響還不是那麼大,可是在雲端就是一個很是大的資源浪費。
我們不少時候作事情的時候不會考慮與事情自己無關的問題,好比造飛機的不會考慮飛機是否要潛水,對於咱們目前不少移動互聯網的應用來講,不多會涉及到對操做系統的部分,其實咱們主要關心的是應用的自己,而VM虛擬機的上層是運行的運行時庫和應用,整個虛擬機的空間是很是的龐大,可是容器化技術Docker技術的出現後,省去了操做系統這一層,多個容器之間相互隔離且共用了宿主操做系統和運行時庫。
因此Docker 應用容器相對於 VM 有如下幾個優勢:
因此不少移動互聯網的應用或者雲計算的後端節點均可以用docker來替換物理機器或者虛擬機。好比騰訊地圖的不少後臺服務基本上都遷移docker部署了。
前面說了那麼多,始終仍是霧裏看花。下面就詳細介紹一下技術架構,底層又是用的啥技術來實現上述那麼多優勢的?
Docker技術架構圖:
從Docker依賴的底層技術來看,Docker原生態是不能直接在Windows平臺上運行的,只支持linux系統,緣由是Docker依賴linux kernel三項最基本的技術,namespaces充當隔離的第一級,是對Docker容器進行隔離,讓容器擁有獨立的hostname,ip,pid,同時確保一個容器中運行一個進程並且不能看到或影響容器外的其它進程;Cgroups是容器對使用的宿主機資源進行覈算並限制的關鍵功能。
好比CPU,內存,磁盤等,union FS主要是對鏡像也就是image這一塊做支持,採用copy-on-write技術,讓你們能夠共用某一層,對於某些差別層的話就能夠在差別的內存存儲,Libcontainer是一個庫,是對上面這三項技術作一個封裝。
Docker engine 用來控制容器container的運行,以及鏡像文件的拉取。
安裝以前,咱們首先確保本身的linux系統內核版本高於3.10,而且系統是64位,才能體驗Docker哦。
經過uname -ir查看是否知足要求。
經過腳本的方式安裝docker,很是簡單。
nicktang@nicktang-virtual-machine:~$ wget -qO- https://get.docker.com/ | sh
輸入當前用戶的密碼後,就會下載腳本而且安裝Docker及依賴包。
顯示上圖內容就代表安裝完成。
root@nicktang-virtual-machine:/data # sudo service docker start #啓動守護進程
root@nicktang-virtual-machine:/data # docker -v
可以看見版本號,說明docker的安裝成功。簡單吧!至此就差一個鏡像了。本身製做仍是從公共倉庫拉取就隨你啦。
root@nicktang-virtual-machine:/data # sudo service docker stop #關閉守護進程
Docker的使用,咱們主要從【增刪查】幾方面來講說怎麼使用docker,爲何沒有【改】呢,由於在我看來docker容器一旦出現問題了,根本沒有修復的必要,直接把容器中止並刪除,再啓動,這樣來得快。因此咱們只須要掌握幾個基本命令便可,具體以下。
【查】查看本地已有的鏡像 Docker images
【增】運行一個鏡像,即啓動一個容器 docker run 鏡像名 ,好比咱們運行docker run centos
鍵入這個命令的時候完成了三樣操做
一、 檢查本地是否有hello-world這個鏡像,有->就跳過第二步 沒有->依次執行
二、 就自動去docker hub下載這個鏡像
三、 就把鏡像加載到容器而且運行
再用docker images查看的時候本地就增長了centos鏡像。
Tag爲latest就表示是最新版本的centos系統鏡像。由於會從docker hub拉取沒有的鏡像,因此算【增】裏面。
【增】拉取指定的鏡像文件 docker pull 鏡像名:TAG
上面那種經過直接運行的方式拉取的是docker hub中最新的鏡像,可是有時候我想拉取指定的鏡像文件就須要使用docker pull命令來拉取。由於從官方拉取鏡像文件,一般是比較慢的,因此咱們能夠經過加速器技術來從國內的鏡像倉庫拉取。
【查】查看全部的容器docker ps -a 能夠用來查看全部的容器,包括運行中的和已經中止的。
第一個字段就是已經啓動的容器ID,第二個字段就是這個容器是根據哪一個鏡像生成的。可是上面這個命令只是臨時啓動一下容器,上面圖中的status 是exited(0),表示容器是退出狀態。若是想容器在後臺運行,因此咱們須要啓動守護式容器才能夠,只要在啓動命令中添加一個 -d參數,即docker run -d centos就能夠了。
【查】查看鏡像/容器的具體信息 docker inspect鏡像ID(鏡像名)/容器ID(容器名) docker inspect centos
這個命令是返回一個鏡像或者容器詳細信息的json串。其中包括ID,ip,版本,容器的主程序等很是多的信息,根據這些信息咱們能夠進行二次開發。在這個命令的基礎之上增長一個-f參數咱們能夠指定獲取本身須要的信息,好比獲取redis容器的IP地址,內存信息,CPU使用狀況。docker inspect -f '{{.NetworkSettings.IPAddress}}' [ID /Name]
【查】進入容器 docker run -it centos 即啓動一個交互式容器
-it 完成容器終端和當前終端進行關聯,即當前終端的顯示就會切換到容器終端的顯示。
查看容器目錄結構,發現和物理機器的目錄結構徹底一致,這就是爲何有的人稱docker容器也稱之爲虛擬機的緣由啦。Exit能夠退出容器終端。
【刪】刪除容器,docker rm 容器ID,刪除多個容器就能夠多個容器ID之間用空格隔開便可。
這年頭見面不聊點自動化什麼的,持續什麼的,都很差意思。因此,我們也要了解一下持續集成,自動交付,自動部署。可是上面說了這麼多,沒發現Docker有那三樣功能啊,是的,Docker是沒有這個功能,可是你在完成上述三樣自動化的步驟都是依賴Docker的。Docker是這些流程實現的基礎,就如同軟件開發,軟件代碼纔是根本,開發工具是輔助。全部搭建一個完整的自動化流程還須要github+jenkins+ registry三樣幫助。
持續集成和自動部署的原理以下圖所示:
而在整個過程當中 RD只須要敲入三個命令Git add * ;Git commit –m 「」;Git push便可完成持續集成、自動交付、自動部署。後面經過案例實際演示這個過程的神奇!
Docker還能夠很方便的自動擴容哦,通常的自動擴容的兩種方式,一種就是docker容量擴大,另外一種就是docker節點數擴充。第一種就修改配置文件便可,第二種經過簡單的拷貝,運行就完成了節點的擴容。
Docker雖好,可不要貪杯哦!雖然Docker具備超輕量化,可是不建議一臺機器上面部署太多的應用,同時部署的時候必定要差別化部署,什麼意思呢,就是將大量計算的,和內存須要大的,IO操做頻繁的對系統資源需求不一致的部署到同一臺宿主機上。
歡迎關注【騰訊織雲】,獲取最新技術資訊
此文已由做者受權騰訊雲技術社區發佈,轉載請註明文章出處
原文連接:https://cloud.tencent.com/community/article/288560
海量技術實踐經驗,盡在騰訊雲社區!