引言
如果你認為學習docker是運維該做的,那你就錯了。作為一名研發工程師,學會基礎的docker使用,能大大提高平時的效率。
雖然docker已經出來將近8年,但是相信還是有很多人並不知道docker是什麼?為什麼這麼受歡迎?讀完本篇,希望能解決你的疑惑。
痛點
不撞牆,哪知道另闢蹊徑?熟悉計算機發展史的應該知道,軟體開發的痛點就是環境配合問題。各種不同環境的計算機,導致開發出來的軟體只能在某個或某些計算機上運行。
安裝一個運行環境需要考慮各種組件和庫,還要考慮兼容問題。最常見的就是,「咦?在我的電腦上能運行起來啊」。既然是同樣的軟體包,那唯一的問題就是出在了運行環境上,那如果能把你的環境也帶上一併給我,不就可以運行起來了?
虛擬機
虛擬機(Virtual Machine)指通過軟體模擬的具有完整硬體系統功能的、運行在一個完全隔離環境中的完整計算機系統。虛擬機技術幫我們實現了可以在一個作業系統上運行另一個作業系統。
上大學時,在一臺windows系統上邊安裝三臺Linux虛擬機搭建hadoop,記憶猶新啊。雖然我們只要安裝好一臺虛擬機,並在上邊安裝上必要的軟體之後,就可以複製出來一個一模一樣的。但是缺點也是不言而喻的,它不僅佔用資源多(就算是純終端的一個虛擬機也有幾百兆),啟動也是超級慢,如果三臺虛擬機同時運行起來,是卡的一批啊(2核8G)
Linux容器
由於虛擬機存在的這些缺點,Linux 發展出了另一種虛擬化技術:Linux 容器(Linux Containers,縮寫為 LXC)
它可以提供輕量級的虛擬化,以便隔離進程和資源,而且不需要提供指令解釋機制以及全虛擬化的其他複雜性。相當於C++中的NameSpace。容器有效地將由單個作業系統管理的資源劃分到孤立的組中,以更好地在孤立的組之間平衡有衝突的資源使用需求。與傳統虛擬化技術相比,它的優勢在於
啟動快:容器裡面的應用,直接就是底層系統的一個進程,而不是虛擬機內部的進程。所以,啟動容器相當於啟動本機的一個進程,而不是啟動一個作業系統,速度就快很多
資源佔用少:容器只佔用需要的資源,不佔用那些沒有用到的資源;虛擬機由於是完整的作業系統,不可避免要佔用所有資源。另外,多個容器可以共享資源,虛擬機都是獨享資源
體積小:容器只要包含用到的組件即可,而虛擬機是整個作業系統的打包,所以容器文件比虛擬機文件要小很多
它就像是一個輕量級的虛擬機,可以提供虛擬化的環境,但是成本開銷小很多
總之,容器有點像輕量級的虛擬機,能夠提供虛擬化的環境,但是成本開銷小得多。
Docker
Docker是什麼?
Docker可以看做是上邊提到的Linux容器的一種封裝,提供簡單易用的容器使用接口。是目前最流行的Linux容器解決方案
Docker通過將應用程式和該程序的依賴,都打包到一個文件中,然後運行該文件,就會生成一個容器。程序就可以在這個容器中運行,效果是和在物理機上是一樣的。因此,有了Docker,就可以解決環境的問題了
Docker的用途
Docker的主要用途,目前有三大類。
提供一次性的環境。比如,本地測試他人的軟體、持續集成的時候提供單元測試和構建的環境
提供彈性的雲服務。因為 Docker 容器可以隨開隨關,很適合動態擴容和縮容
組建微服務架構。通過多個容器,一臺機器可以跑多個服務,因此在本機就可以模擬出微服務架構
Docker的安裝
安裝可參考官方文檔:
安裝完成之後,可以使用一下命令查看是否安裝成功
鏡像(image)
關於docker裡邊鏡像、容器、倉庫更加詳細的概念及命令,可以參考我之前的《docker基礎學習》。
Docker把應用程式及其依賴,打包在image文件裡面。通過這文件,可以生成Docker容器。image文件可以理解成是容器的模板。Docker根據image文件生成容器的實例。同一個image文件,可以生成多個同時運行的容器實例
image是二進位文件。實際開發中,一個image文件往往通過繼承另一個image文件,然後在其基礎上加一些個性化設置而生成。比如,你可以在Ubuntu的image基礎上,往裡面加入Apache伺服器,形成你的image。
image文件是通用的,一臺機器的image文件拷貝到另一臺機器,照樣可以使用。一般我們都會去dockerHub官網上下載別人製作好的image文件,這樣比較節省時間,如果需要增加一些特性,可以在別人的image基礎上進行添加
image實例
可以通過一個簡單的的image文件來感受一下。docker官方提供的有一個測試的鏡像:library/hello-world
首先通過前邊提到的拉取一個鏡像的命令來拉取測試鏡像
library/hello-world是image文件在倉庫裡面的位置,其中library是image文件所在的組,hello-world是image文件的名字
此時就可以通過docker images看到剛拉取到的image。然後通過下邊的命令運行這個image文件,就會生成一個正在運行的容器實例
輸出結果:
docker container run命令會先看本地是否有指定的image文件,如果沒有會從遠程倉庫拉取
對於上邊的測試鏡像,當其運行起來,輸出一段內容之後就自動終止了。但是有些容器不會自動終止,因為它可能提供的是服務。比如,安裝運行Ubuntu的image,就可以在命令行體驗Ubuntu系統
對於那些不會自動終止的容器,可以使用docker container kill命令手動終止
容器
image文件生成的容器實例,本身也是一個文件,稱為容器文件。也就是說,一旦容器生成,就會同時存在兩個文件:image文件和容器文件。而且關閉容器並不會刪除容器文件,只是容器停止運行而已
終止運行的容器文件,依然會佔據硬碟空間,可以使用docker container rm命令刪除
製作自己的Docker容器
了解了docker以及image文件之後,接下來的問題就是,如何可以生成image文件?如果你要推廣自己的軟體,肯定要自己製作 image文件。這就需要用到Dockerfile文件。它是一個文本文件,用來配置image。Docker根據該文件生成二進位的image文件。
下面就通過一個實例,演示如何編寫Dockerfile文件下邊是以一個開源的數據管理系統為例來介紹如何編寫Dockerfile文件,從而實現在容器中運行起來這個項目。
首先下載原始碼
編寫Dockerfile文件
如果項目中有哪些路徑下的文件不希望打包到image文件中,則可以在項目根目錄下創建一個.dockerignore文件,文件內容為要排除的文件的路徑,我這裡不希望將.git文件和node_modules目錄打包進image文件,因此.dockerignore文件內容為
然後在項目的根目錄下創建Dockerfile文本文件,內容為
FROM node:12.14:該image文件繼承官方的 node image,冒號表示標籤,這裡標籤是12.14,即12.14版本的node
COPY . /app:將當前目錄下的所有文件(除了.dockerignore排除的路徑),都打包進入image 文件的/app目錄
WORKDIR /app:指定接下來的工作路徑為/app(很像cd)
RUN npm install:在/app目錄下,運行npm install命令安裝依賴。注意,安裝後所有的依賴,都將打包進入image文件
EXPOSE 3000:將容器3000埠暴露出來, 允許外部連接這個埠
創建image文件
有了Dockerfile文件以後,就可以使用docker image build命令創建image文件了
在上邊的命令中,-t參數用來指定image文件的名字,後面還可以用冒號指定標籤(這裡需要注意,image名稱需要是小寫)。如果不指定,默認的標籤就是latest。最後的那個點表示Dockerfile文件所在的路徑,上例是當前路徑,所以是一個點。如果運行成功,就可以通過docker images命令看到新生成的image文件data-admin:v1了
生成容器
docker container run命令會從image文件生成容器
-p參數:容器的3000埠映射到本機的8000埠
-it參數:容器的Shell映射到當前的Shell,然後你在本機窗口輸入的命令,就會傳入容器
data-admin:v1:image文件的名字(如果有標籤,還需要提供標籤,默認是latest標籤)
/bin/bash:容器啟動以後,內部第一個執行的命令。這裡是啟動Bash,保證用戶可以使用Shell(當然也還有更多的參數,可以參考我之前的docker基礎文章)
如果一切正常,運行上面的命令以後,就會返回一個命令行提示符。這表示你已經在容器裡面了,返回的提示符就是容器內部的Shell提示符。執行npm run serve就可以將項目正常運行起來了(會遇到一個vue cli在容器中運行的問題,大家可自行解決,參考:https://github.com/vuejs/vue-cli/issues/1716)
該例中,Node進程運行在Docker容器的虛擬環境裡面,進程接觸到的文件系統和網絡接口都是虛擬的,與本機的文件系統和網絡接口是隔離的,因此需要定義容器與物理機的埠映射
CMD命令
在上邊的例子中,當我們將容器運行起來之後,還需要進入到容器中,執行yarn serve才能將項目運行起來。這個命令其實可以寫在Dockerfile中,此時,當容器運行起來後,該命令會自動執行
上面的 Dockerfile 裡面,多了最後一行CMD yarn serve,它表示容器啟動後自動執行yarn serve
RUN命令與CMD命令的區別,簡單說,RUN命令在image文件的構建階段執行,執行結果都會打包進入image文件;CMD命令則是在容器啟動後執行。另外,一個Dockerfile可以包含多個RUN命令,但是只能有一個CMD命令
注意:指定了CMD命令以後,docker container run命令就不能附加命令了(比如前面的/bin/bash),否則它會覆蓋CMD命令。現在,啟動容器可以使用下面的命令
如果想將image文件推送到dockerHub,可以參考我之前的《mac OS中使用docker安裝ubuntu+lnmp》這篇文章最下邊一部分
還是需要動手做起來,才能更深的理解
參考:
http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.htmlhttps://www.jianshu.com/p/63fea471bc43
作者:書旅
連結:https://juejin.im/post/6863230607518859271
來源:掘金
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。