5分鐘讓你秒懂Docker!

調皮仔3683發表於2017-12-02

Docker是啥?

開啟翻譯君輸入Docker 結果顯示碼頭工人,沒錯!碼頭工人搬運的是集裝箱,那麼今天要講的Docker其操作的也是集裝箱,這個集裝箱就靜態而言就是一個應用映象檔案,就動態而言,就是一個容器。蒙了吧?好吧,上圖解釋。

1509505546891_4196_1509505547603.PNG

Docker從狹義上來講就是一個程式,從廣義上來講是一個虛擬容器,其實更專業的叫法是應用容器( Application Container ),Docker程式和普通的程式沒有任何區別,它就是一個普通的應用程式。不過是用來操作映象檔案的。所以Docker程式+構建的應用映象檔案就等於Docker容器。本文所有講的Docker都是指Docker容器哦。

再繼續下文之前我們首先要明確幾個docker重要的基本概念吧,映象,容器,倉庫。

映象Docker images,就類似於VM虛擬機器裡面的快照,但是可比快照輕量化多了。快照不懂?那可以把images直接理解成一個資料夾。我們可以通過ID或者易識別的名字+tag來確認唯一的目標映象。ImagesID是一個64位的字元,但是一般我們都是使用前面12位就足夠區別了。

如圖中左邊紅框中redis: lates和右邊的紅框中5f515359c7f8都唯一表示為同一個映象。所以我們一般的映象可以命名為類似centos:latest、centos:centos7.1.1503等等。

映象是分層的,有基礎映象,僅僅包含作業系統,比如centos映象;有中介軟體映象,比如redis等資料庫映象;最後是應用映象,就是指具體的應用服務了,應用映象可以非常豐富,隨時可以釋出,這三者之間依次疊加。

所以當我們在使用 Docker構建映象的時候,每一個命令都會在前一個命令的基礎上形成一個新映象層。如下圖,基礎映象就是centos映象,中介軟體映象就是兩個紅色圈,應用映象就是紫色圈。其中redis+centos這樣疊加組合的中介軟體映象就可以供A服務或者B服務使用,這樣疊加組合更加靈活。仍和一種映象都可以從Docker hub公共倉庫中拉取。

1509505599609_5514_1509505599809.PNG

容器Docker containers,你可以從映象中建立容器,這如同從快照中建立虛擬機器,不過更輕量,啟動更快,秒啟。應用是在容器中執行的,打個比方,你首先下載了一個Ubuntu的映象,然後又安裝mysql和Django應用及其依賴,來完成對它Ubutun映象的修改,一個個人覺得非常完美應用映象生成了!就把這個映象分享給大家使用,大家通過這個映象就生成一個容器。容器啟動之後就會執行Django服務了。

1509505610758_1979_1509505610957.PNG

上面也說到了,容器就是一個個獨立的封閉的集裝箱,但是也需要對外提供服務的,所以Docker允許公開容器的特定埠,在啟動Docker的時候,我們就可以將容器的特定埠對映到宿主機上面的任意一個埠,所以,如果幾個服務都需要80埠,那麼容器的對外埠是80,但是對映到宿主機上面就是任意埠,就不會產生衝突,所以就不需要通過代理來解決衝突。容器對外埠與宿主機的埠對映可以通過下面的命令來完成。

啟動docker容器
 docker run -d -p 2222:22 --name 容器名 映象名
 -d 守護容器,就是後臺執行,退出命令視窗容器也不會停止
 -it 互動式容器 退出命令視窗容器就停止執行了
 -p宿主機埠和容器埠對映
 8081:80 宿主機埠:容器公開的埠

1509505645518_6311_1509505645877.PNG

倉庫Docker registeries,docker倉庫和存放集裝箱的倉庫是一樣的,不過docker使用來存放映象的。倉庫存在公有和私有之分,公有倉庫docker hub提供了非常多的映象檔案,這些映象直接拉取下來就可以執行了,你也可以上傳自己的映象到docker hub上面。同時也可以自己搭建私有倉庫用於團隊專案管理。

結合前面介紹的基本概念,我們可以將docker的幾個概念使用大致串起來,他們之間是如何運作的,也就是Docker的生命週期。

看下圖,主要是三步走。

1509505697234_6149_1509505697487.PNG

1、 開發構建映象並將映象push到Docker倉庫
2、 測試或者運維從Docker倉庫拷貝一份映象到本地
3、 通過映象檔案開啟Docker容器並提供服務

為啥要用Docker?能幹些啥?

為啥要用Docker?這要從目前軟體行業的痛點來講起 1、軟體更新發布及部署低效,過程繁瑣且需要人工介入,2、環境一致性難以保證,3、不同環境之間遷移成本太高。有了Docker可以很大程度解決上面的問題。

首先,Docker的使用簡單至極,從開發的角度來看就是三步走:構建,運輸,執行。其中關鍵步驟就是構建環節,即打包映象檔案。但是從測試和運維的角度來看,那就只有兩步:複製,執行。有了這個映象,那麼想複製到哪執行都可以,完全和平臺無關了。同時Docker這種容器技術隔離出了獨立的執行空間,不會和其他應用爭用系統資源了以及還不需要考慮應用之間相互影響,想想就開心。

其次,因為在構建映象的時候就處理完了服務程式對於系統的所有依賴,所以在你使用的時候,你可以忽略掉原本程式的依賴以及開發語言。對測試和運維而言,更多專注於自己的業務內容上。

最後,Docker於開發者而言提供了一種開發環境的管理辦法,與測試人員而言保證了環境的同步,於運維人員提供了可移植的標準化部署流程。

所以, Docker 能幹啥,總結如下:

  • 構建容易分發簡單

  • 隔離應用解除依賴

  • 快速部署測完就銷

Docker是個程式級的輕量化虛擬機器,和傳統虛擬機器有啥區別呢?

Docker這個虛擬機器超級輕量級,僅僅是一個程式而已。與傳統的虛擬機器比如VM有著巨大的差別

區別看下圖:

1509505721847_9376_1509505722083.PNG

我們來看一下二者的區別,因為 VM 的 Hypervisor 需要實現對硬體的虛擬化,並且還要搭載自己的作業系統,其中虛擬機器作業系統佔用記憶體是比較大的,一個作業系統有好幾個G,自然在啟動速度和資源利用率以及效能上有非常大的開銷,如果在本地,或者個人電腦,那麼影響還不是那麼大,但是在雲端就是一個非常大的資源浪費。

我們們很多時候做事情的時候不會考慮與事情本身無關的問題,比如造飛機的不會考慮飛機是否要潛水,對於我們目前很多移動網際網路的應用來說,很少會涉及到對作業系統的部分,其實我們主要關心的是應用的本身,而VM虛擬機器的上層是執行的執行時庫和應用,整個虛擬機器的空間是非常的龐大,但是容器化技術Docker技術的出現後,省去了作業系統這一層,多個容器之間相互隔離且共用了宿主作業系統和執行時庫。

所以Docker 應用容器相對於 VM 有以下幾個優點:

  • 啟動速度快,容器啟動本質就是一個開啟一個程式而已,因此都是秒啟,而 VM 通常要更久。

  • 資源利用率高,一臺普通 PC 可以跑成百上千個容器,你跑十個 VM 試試。

  • 效能開銷小, VM 通常需要額外的 CPU 和記憶體來完成 OS 的功能,這一部分佔據了額外的資源。

所以很多移動網際網路的應用或者雲端計算的後端節點都可以用docker來替換物理機器或者虛擬機器。比如騰訊地圖的很多後臺服務基本上都遷移docker部署了。

Docker是個啥架構?底層又是用的啥技術?

前面說了那麼多,始終還是霧裡看花。下面就詳細介紹一下技術架構,底層又是用的啥技術來實現上述那麼多優點的?

Docker技術架構圖:

1509505737833_7243_1509505738044.PNG

從Docker依賴的底層技術來看,Docker原生態是不能直接在Windows平臺上執行的,只支援linux系統,原因是Docker依賴linux kernel三項最基本的技術,namespaces充當隔離的第一級,是對Docker容器進行隔離,讓容器擁有獨立的hostname,ip,pid,同時確保一個容器中執行一個程式而且不能看到或影響容器外的其它程式;Cgroups是容器對使用的宿主機資源進行核算並限制的關鍵功能。

比如CPU,記憶體,磁碟等,union FS主要是對映象也就是image這一塊作支援,採用copy-on-write技術,讓大家可以共用某一層,對於某些差異層的話就可以在差異的記憶體儲存,Libcontainer是一個庫,是對上面這三項技術做一個封裝。

Docker engine 用來控制容器container的執行,以及映象檔案的拉取。

Docker咋裝呢?Docker怎麼用呢?

安裝之前,我們首先確保自己的linux系統核心版本高於3.10,並且系統是64位,才能體驗Docker哦。

通過uname -ir檢視是否滿足要求。

1509505760202_5796_1509505760440.PNG

Docker安裝

通過指令碼的方式安裝docker,非常簡單。

1、 獲取最新的docker安裝包

nicktang@nicktang-virtual-machine:~$ wget -qO- https://get.docker.com/ | sh

1509505773762_7195_1509505774091.PNG

輸入當前使用者的密碼後,就會下載指令碼並且安裝Docker及依賴包。

1509505787761_9057_1509505788337.PNG

1509505802877_2768_1509505803293.PNG

顯示上圖內容就表明安裝完成。

2、 啟動docker 後臺服務

root@nicktang-virtual-machine:/data # sudo service docker start #啟動守護程式
root@nicktang-virtual-machine:/data # docker -v

1509505834291_6949_1509505834568.PNG

能夠看見版本號,說明docker的安裝成功。簡單吧!至此就差一個映象了。自己製作還是從公共倉庫拉取就隨你啦。

root@nicktang-virtual-machine:/data # sudo service docker stop #關閉守護程式

Docker使用

Docker的使用,我們主要從【增刪查】幾方面來說說怎麼使用docker,為什麼沒有【改】呢,因為在我看來docker容器一旦出現問題了,根本沒有修復的必要,直接把容器停止並刪除,再啟動,這樣來得快。所以我們只需要掌握幾個基本命令即可,具體如下。

【查】檢視本地已有的映象 Docker images

1509505854794_8788_1509505855000.PNG

【增】執行一個映象,即啟動一個容器 docker run 映象名 ,比如我們執行docker run centos
鍵入這個命令的時候完成了三樣操作
1、 檢查本地是否有hello-world這個映象,有->就跳過第二步 沒有->依次執行
2、 就自動去docker hub下載這個映象
3、 就把映象載入到容器並且執行

再用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的。Docker是這些流程實現的基礎,就如同軟體開發,軟體程式碼才是根本,開發工具是輔助。所有搭建一個完整的自動化流程還需要github+jenkins+ registry三樣幫助。

持續整合和自動部署的原理如下圖所示:

  1. RD推送程式碼到git 倉庫或者svn等程式碼伺服器上面,git伺服器就會通過hook通知jenkins。

  2. jenkine 克隆git程式碼到本地,並通過dockerFile檔案進行編譯 。

  3. 打包生成一個新版本的映象並推送到倉庫 ,刪除當前容器 ,通過新版本映象重新執行。

而在整個過程中 RD只需要敲入三個命令Git add * ;Git commit –m “”;Git push即可完成持續整合、自動交付、自動部署。後面通過案例實際演示這個過程的神奇!

Docker還可以很方便的自動擴容哦,一般的自動擴容的兩種方式,一種就是docker容量擴大,另一種就是docker節點數擴充。第一種就修改配置檔案即可,第二種通過簡單的拷貝,執行就完成了節點的擴容。

總結

雖然Docker具有超輕量化,但是不建議一臺機器上面部署太多的應用,同時部署的時候一定要差異化部署,什麼意思呢?就是將大量計算的,和記憶體需要大的,IO操作頻繁的對系統資源需求不一致的部署到同一臺宿主機上。

作者丨唐文廣:騰訊工程師,負責無線研發部地圖測試

本文連結:https://cloud.tencent.com/community/article/288560?utm_source=csdn_geek


相關文章