
作為軟件開發(fā)者,平常最痛恨的應(yīng)該就是環(huán)境配置問題了吧。比如說,我要在一臺(tái)新電腦(新環(huán)境)上安裝tomcat跑一個(gè)javaweb應(yīng)用,因?yàn)閠omcat是java代碼編寫的,所以首先我要安裝一個(gè)java運(yùn)行時(shí)環(huán)境(JRE),配置JAVA_HOME,然后才能安裝tomcat開始跑javaweb。還有,如果我要學(xué)習(xí)一門新的語言go、或新的中間件RabbitMQ、可能花費(fèi)在安裝這些環(huán)境的時(shí)間就讓你想放棄了。
而作為運(yùn)維人員,平時(shí)肯定也為部署新環(huán)境折騰得焦頭爛額,一下子要為好幾臺(tái)新機(jī)器配置運(yùn)行環(huán)境,每臺(tái)機(jī)器上執(zhí)行相同操作,十分機(jī)械化。
知道了平時(shí)開發(fā)中的痛點(diǎn),那是否有一種工具,能讓我快速安裝tomcat而不用去理會(huì)環(huán)境問題。能讓我把go、RabbitMQ整個(gè)環(huán)境下載下來,不需任何配置,我就能在這個(gè)環(huán)境中直接運(yùn)行g(shù)o代碼。能讓我配置了一臺(tái)機(jī)器后,原樣復(fù)制一份,發(fā)到其他機(jī)器直接運(yùn)行,不用再做配置就可以得到相同的環(huán)境?是有這種工具的,它就是虛擬化容器技術(shù),而docker,就是這門技術(shù)中的佼佼者。
1. 什么是docker
docker是一門虛擬化容器技術(shù),其設(shè)計(jì)理念是"build once, run anywhere"(一次構(gòu)建,到處運(yùn)行),聽起來,是不是跟java的"wirte once, run anywhere"(一次編寫,到處運(yùn)行)很像?那么,什么是虛擬化容器技術(shù)呢?docker 將應(yīng)用程序與該程序的依賴,打包在一個(gè)文件里面。運(yùn)行這個(gè)文件,就會(huì)生成一個(gè)虛擬容器,程序在這個(gè)虛擬容器里運(yùn)行,就好像在真實(shí)的物理機(jī)上運(yùn)行一樣。有了 Docker,就不用擔(dān)心環(huán)境問題。正如開篇第一張圖docker的標(biāo)志一樣,docker就是這條鯨魚,其上馱著的集裝箱,就是一個(gè)個(gè)互相隔離的容器,你可以隨時(shí)往上添加集裝箱,不會(huì)影響到原有集裝箱里的內(nèi)容。
2. docker和虛擬機(jī)的區(qū)別
docker 和傳統(tǒng)虛擬化方式的不同之處,傳統(tǒng)虛擬機(jī)技術(shù)是虛擬出一套硬件后,在其上運(yùn)行一個(gè)完整操作系統(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èi)核,而且也沒有進(jìn)行硬件虛擬。因此容器要比傳統(tǒng)虛擬機(jī)更為輕便。
[圖片上傳失敗...(image-926fd8-1572257136481)]
3. 安裝docker
docker可以在各個(gè)操作系統(tǒng)上安裝,過程很簡單,安裝教程請(qǐng)看這里:https://www.runoob.com/docker/windows-docker-install.html。
docker在windows上安裝是一件麻煩事,但不想在vm虛擬機(jī)中的linux上安裝因?yàn)閼械瞄_,所以還是在windows上安裝了,windows上有兩種安裝方法:
- docker toolbox:這個(gè)安裝包適用于所有windows版本(windows xp的當(dāng)我沒說),包括win7, win8, win10家庭版。我就是安裝的這個(gè)版本
- docker for windows:這個(gè)版本適合win10專業(yè)版,因?yàn)閣in10專業(yè)版帶有Hyper-v虛擬化功能,安裝前需要開啟該功能,具體看上面的安裝鏈接。
3.1. 安裝docker toolbox遇到的問題
這是安裝docker toolbox遇到的卡在下載boot2docker.iso的問題,安裝docker其他版本的這節(jié)可以忽略不看。
docker toolbox安裝完成后,會(huì)有如下三個(gè)圖標(biāo),
[圖片上傳失敗...(image-6ed3d3-1572257136481)]
啟動(dòng)docker需要點(diǎn)擊Docker Quickstart,其會(huì)查找指定目錄下的boot2docker.iso(一個(gè)輕量級(jí)的linux虛擬機(jī))文件,并根據(jù)該文件創(chuàng)建一個(gè)名為default的linux虛擬機(jī),初次點(diǎn)擊時(shí)找不到該文件,會(huì)從github下載,但docker下載速度相當(dāng)慢,等了個(gè)把小時(shí)都無法完成。提示如下:
Running pre-create checks...
(default) No default Boot2Docker ISO found locally, downloading the latest release...
(default) Latest release for github.com/boot2docker/boot2docker is v1.12.1
(default) Downloading C:\Users\huang\machine\cache\boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v1.12.1/boot2docker.iso...
解決方案是:使用瀏覽器(或者迅雷)到boot2docker的主頁下載最新版boot2docker.iso,地址:(https://github.com/boot2docker/boot2docker/releases),如下圖:

下載完成后斷開網(wǎng)絡(luò),將下載好的boot2docker.iso放到提示的位置,我這里是:
C:\Users\huang\machine\cache\目錄。記住要斷開網(wǎng)絡(luò),重新點(diǎn)擊Docker Quickstart圖標(biāo)啟動(dòng)docker即可,啟動(dòng)完成即可連接網(wǎng)絡(luò),開始學(xué)習(xí)docker了。
3.2. boot2docker
對(duì)boot2docker感興趣的可以看看其github的介紹,boot2docker是一個(gè)輕量級(jí)的、用于運(yùn)行docker容器的linux系統(tǒng),完全在內(nèi)存中運(yùn)行,大小只有45m左右,啟動(dòng)迅速。所以在windows中運(yùn)行docker,其原理是使用啟動(dòng)了一個(gè)linux虛擬機(jī),該虛擬機(jī)中安裝了docker,點(diǎn)擊Docker Quickstart后,我們可以看到控制臺(tái)的輸出,該虛擬主機(jī)名為default,默認(rèn)的ip是192.168.99.100。再從github中的介紹可以看到,該虛擬機(jī)有docker用戶,密碼為tcuser。因此,我們可以從secureCRT或者git bash中使用ssh登錄到該機(jī)器,在上面使用docker命令。當(dāng)然你可以在default虛擬機(jī)中安裝vim等工具,但是由于其是內(nèi)存操作系統(tǒng),重啟后這些新安裝的工具都會(huì)消失。

遠(yuǎn)程登錄命令:
ssh docker@192.168.99.100
# 密碼
tcuser
3.3. docker阿里云鏡像加速
這一節(jié)可以暫時(shí)不看,等你覺得docker下載太慢時(shí),可以看我的另一篇文章,配置鏡像加速,地址為:http://www.itdecent.cn/p/aff1a4a471de
4. docker架構(gòu)
這里我想先從docker的架構(gòu)圖和幾個(gè)重要的概念說起,最后再說具體的命令,這樣方便大家知道每一條命令的意思和執(zhí)行過程??赐赀@篇文章后 ,推薦一個(gè)docker教程,不長,鏈接在文章最下方的參考資料。
[圖片上傳失敗...(image-ccd01f-1572257136481)]
如上圖,docker采用的是C/S架構(gòu)??蛻舳讼蚍?wù)器發(fā)送請(qǐng)求,服務(wù)器負(fù)責(zé)構(gòu)建、運(yùn)行和分發(fā)容器??蛻舳撕头?wù)器可以運(yùn)行在同一個(gè)Host上,客戶端也可以通過socket或者REST API與遠(yuǎn)程的服務(wù)器通信。對(duì)照上圖,涉及到的概念如下:
- Client:docker客戶端,最常見的客戶端就是docker命令,如docker build、docker pull、docker run等,通過這些命令我們可以方便的在host上構(gòu)建和運(yùn)行容器。
- Daemon:docker deamon是服務(wù)器組件,以linux后臺(tái)服務(wù)的方式運(yùn)行。docker daemon運(yùn)行在宿主機(jī)docker host上,負(fù)責(zé)創(chuàng)建、運(yùn)行、監(jiān)控容器,構(gòu)建、存儲(chǔ)鏡像。
- image:鏡像,可將鏡像看成只讀模板,通過它可以創(chuàng)建docker容器。正如Java中了.class文件,通過.class可以創(chuàng)建出類的實(shí)例。鏡像是層疊的,最底層就是linux內(nèi)核,每添加一個(gè)文件或者操作都會(huì)在原來的基礎(chǔ)上疊加一層,如JDK環(huán)境疊加在linux內(nèi)核之上,tomcat又疊加在JDK環(huán)境之上,此時(shí)如果你的docker中已有JDK鏡像的話,就只需下載tomcat這層即可。因?yàn)殓R像是只讀的、共享的。
- container:容器,docker容器就是docker鏡像的運(yùn)行實(shí)例。
- registry:registry是存放docker鏡像的倉庫,我們可以將自己的鏡像推到遠(yuǎn)程,或者從遠(yuǎn)程下載鏡像到本地運(yùn)行,正如github。docker官方有一個(gè)docker hub,我們可以從上面下載官方的鏡像。如,下載一個(gè)官方的tomcat鏡像,直接運(yùn)行該鏡像即可啟動(dòng)tomcat,不需任何配置。
綜上,結(jié)合上圖,整個(gè)docker架構(gòu)交互流程為:啟動(dòng)docker,docker以守護(hù)進(jìn)程的方式運(yùn)行在linux主機(jī)上(docker toolbox下為boot2docker虛擬出來的linux上),我們發(fā)送docker命令給到docker daemon執(zhí)行,docker可以從docker hub中拉取所需要的image,再根據(jù)image創(chuàng)建出container。
5. 實(shí)戰(zhàn)
知道了上面docker架構(gòu)的交互流程了,我這里以運(yùn)行一個(gè)tomcat容器為例,一步步介紹常用的命令:
-
docker images:列出當(dāng)前docker中有哪些鏡像,如果是第一次執(zhí)行,當(dāng)然就沒有鏡像了。 -
docker search tomcat:在docker hub中搜索tomcat鏡像。當(dāng)然你可以在瀏覽器中訪問docker hub,地址為:(https://hub.docker.com/),就像訪問maven的遠(yuǎn)程倉庫一樣,可以搜索你需要的內(nèi)容。
20191028120959.png -
docker pull tomcat:拉取最新版的tomcat鏡像到本地,下載完成后再使用docker images就能看到感下載的鏡像了。 -
docker run --name mytomcat -p 8080:8080 -d tomcat:根據(jù)tomcat鏡像運(yùn)行出一個(gè)tomcat實(shí)例,執(zhí)行兩遍就有兩個(gè)實(shí)例了(注意改端口),--name表示為這個(gè)實(shí)例命名,-p 8080:8080表示將本地的8080端口綁定到容器中的8080端口,才能使用localhost:8080(docker toolbox是192.168.99.100:8080)訪問到tomcat端口。-d表示后臺(tái)運(yùn)行。 -
docker run --name mytomcat03 -p 8082:8080 -it tomcat /bin/bash:-it以交互、附加模式啟動(dòng)并進(jìn)入容器后執(zhí)行/bin/bash命令,不以后臺(tái)運(yùn)行,進(jìn)入容器后執(zhí)行exit命令后,會(huì)退出容器,此時(shí)使用docker ps -a命令查看會(huì)顯示為exit狀態(tài)。 -
ctrl+p+q:退出但是后臺(tái)運(yùn)行,如上一個(gè)命令,執(zhí)行exit退出后容器就會(huì)退出,此時(shí)若不想容器退出,可按這一組快捷鍵。 -
docker ps -a:顯示所有容器狀態(tài),docker ps只顯示運(yùn)行中的容器,-a表示顯示所有容器,包括已退出的容器。這時(shí)就能看到剛剛啟動(dòng)的tomcat了。 -
docker logs -f mytomcat:查看剛剛啟動(dòng)的tomcat打出來的日志,-f表示跟蹤滾動(dòng)日志打印。 -
docker exec -it mytomcat /bin/bash:exec表示執(zhí)行命令,命令最后需要帶將要執(zhí)行的命令,如/bin/bash,-it表示以交互、附加模式啟動(dòng)返回一個(gè)終端,/bin/bash表示進(jìn)入容器后首先執(zhí)行的命令。這條命令執(zhí)行后就登錄到了容器內(nèi)部,該容器中就是tomcat應(yīng)用。就像使用ssh登錄到容器內(nèi)部一樣。這時(shí)候你可以修改容器內(nèi)部的配置文件,當(dāng)然,生產(chǎn)環(huán)境不建議這么做,而是使用配置文件外部掛載的方式。 -
docker stop mytomcat:停止mytomcat實(shí)例,不會(huì)刪除容器內(nèi)的東西。 -
docker start -i mytomcat:啟動(dòng)已停止的mytomcat實(shí)例,如果啟動(dòng)前修改了容器內(nèi)的配置文件,此時(shí)重新啟動(dòng)會(huì)重新加載該配置,如果該配置文件是linux宿主機(jī)級(jí)別的,如/etc/profile文件,則不會(huì)加載,因?yàn)槿萜魇枪蚕硭拗鳈C(jī)的配置的。-i表示啟動(dòng)并進(jìn)入交互命令界面。 -
docker rm mytomcat:刪除已停止的mytomcat實(shí)例 -
docker run --name mytomcat02 -p8081:8080 -e JAVA_HOME=/path/to/java/home -v /host/path/file:/container/path/file -d tomcat:-e表示設(shè)置環(huán)境變量JAVA_HOME,進(jìn)入到容器中,使用echo $JAVA_HOME可以看到該環(huán)境變量的值。-v表示掛載宿主機(jī)的/host/path/file到容器中的/container/path/file,修改宿主機(jī)的文件時(shí),容器中的文件也會(huì)修改。如果使用的是docker toolbox,則宿主機(jī)掛在的文件需要在當(dāng)前用戶目錄下,即c:\user\yourname下才行,否則不會(huì)報(bào)錯(cuò)但無法掛載成功,當(dāng)時(shí)被這個(gè)問題坑了一個(gè)下午。 -
docker cp /host/path/file mytomcat02:/container/path/file:復(fù)制宿主機(jī)文件到容器中,可以用于當(dāng)修改了容器配置文件后,配置文件錯(cuò)誤導(dǎo)致無法啟動(dòng)時(shí),復(fù)制配置文件到宿主機(jī)修改配置,然后重新復(fù)制回容器即可。 -
docker inspect mytomcat:查看容器信息,包括容器ip等信息。
6. 構(gòu)建docker鏡像
假如我們下載了tomcat鏡像并啟動(dòng)了容器實(shí)例,并在tomcat容器中修改了配置文件。這時(shí),我們可以把配置文件也一起打包做成鏡像,發(fā)到另外的機(jī)器直接執(zhí)行,就不用再單獨(dú)對(duì)每一臺(tái)機(jī)器配置了。docker提供了兩種方式來構(gòu)建鏡像,如下:
- docker commit:通過容器構(gòu)建
- docker build:通過dockerfile文件構(gòu)建
dockerfile文件方式構(gòu)建需要編寫dockerfile,也只有幾個(gè)命令,不難,請(qǐng)自行查閱資料。此處講下docker commit命令。
docker commit mytomcat huangzb/tomcat:將當(dāng)前的mytomcat容器提交為鏡像,鏡像名為huangzb/tomcat
7. 容器的網(wǎng)絡(luò)結(jié)構(gòu)
熟悉docker的網(wǎng)絡(luò)結(jié)構(gòu)是相當(dāng)重要的,因?yàn)檫@樣我們就可以做集群啦。廢話不多說,那就直入主題吧。
docker的網(wǎng)絡(luò)使用了linux網(wǎng)絡(luò)中的bridge(網(wǎng)橋)和veth(virtual ethernet虛擬以太網(wǎng))虛擬設(shè)備。
- bridge:網(wǎng)絡(luò)橋接器,簡稱網(wǎng)橋,普通的網(wǎng)橋只有兩個(gè)接口,連接兩個(gè)網(wǎng)絡(luò),工作在二層(數(shù)據(jù)鏈路層),只要有mac地址就能轉(zhuǎn)發(fā)數(shù)據(jù)包。而linux得虛擬bridge有多個(gè)接口,并且能配置ip,更像一個(gè)路由器。安裝完docker后,在宿主機(jī)中使用ifconfig命令,可以看到網(wǎng)絡(luò)配置中出現(xiàn)了docker0網(wǎng)絡(luò)。docker0就是docker設(shè)置的linux虛擬網(wǎng)橋。
- veth:virtual ethernet是linux中的虛擬網(wǎng)絡(luò)設(shè)備,其像一條兩端有網(wǎng)卡的線,可以將兩個(gè)設(shè)備連接起來分別配置ip地址。
[圖片上傳失敗...(image-b672e-1572257136481)]
因此,在我windows下docker toolbox中的網(wǎng)絡(luò)如下圖。
[圖片上傳失敗...(image-3f9661-1572257136481)]
7.1. 容器間互聯(lián)
由上,docker中新建的容器默認(rèn)都使用了docker0網(wǎng)橋連接了起來,所有默認(rèn)的,docker創(chuàng)建的所有容器都在一個(gè)網(wǎng)絡(luò)中,互相可以訪問。
以上。有興趣的同學(xué)可以學(xué)習(xí)下面的參考資料。
參考資料
- docker教程:https://yeasy.gitbooks.io/docker_practice/introduction/what.html
- 極客學(xué)院視頻教程:https://www.bilibili.com/video/av17854410/?p=1
- docker bridge網(wǎng)橋:https://www.ibm.com/developerworks/cn/linux/1310_xiawc_networkdevice/index.html
- docker網(wǎng)絡(luò)深度研究:http://www.itdecent.cn/p/19d6f55b9563
