1. 程式人生 > >Docker 之 基於容器的鏡像制作

Docker 之 基於容器的鏡像制作

rootfs red 高可擴展 otf mon ons docker 工作組 nsh

1 概述

鏡像包含啟動容器所需的文件系統和內容,可以理解為打包的文件,用於創建並啟動docker容器。

鏡像的生成途徑有三個:

1.基於dockerfile實現,鏡像制作的程序文件

2.基於容器實現,啟動容器後,將新的操作制作為新鏡像

3.docker hub automated builds

鏡像文件采用分層構建機制,最底層為bootfs,上面為rootfsrootfs上還可以有多層。位於最下層的鏡像文件為父鏡像(parent image,最底層為基礎鏡像(base imagerootfs為這一層,這一層必須存在).最上層為“可讀寫”層,其下的均為“只讀”層

如下截圖

技術分享圖片

其中:

bootfs:用於系統引導的文件系統,包含

bootloaderkernel,容器啟動完成後會被卸載以節約內存資源,可以理解為容器引擎,不是宿主機操作系統

rootfs:位於bootfs之上,表現為docker容器的根文件系統;

傳統模式中,系統啟動時,內核掛載rootfs時會首先將其掛載為只讀模式,完整性自檢完成後將其重新掛載為讀寫模式

docker中,rootfs由內核掛載為只讀模式,而後通過“聯合掛載”技術額外掛載一個“可寫”層。聯合掛載,需要文件系統支持,目前支持最好的文件系統為Aufs(advanced multi-layered unification filesystem),高級多層統一文件系統,用於為linux文件系統實現”聯合掛載“,

docker 最初使用aufs作為容器文件系統層,目前還作為存儲後端之一來支持,目前沒有基層到linux內核,需要對內核打補丁才能使用aufsdocker的分層鏡像,除了aufs,還支持btrfs,devicemappervfs。在ubuntu系統下,docker默認支持ubuntuaufs,這也是為什麽很多底層鏡像都是ubuntu的原因,因為ubuntu更好的支持aufs.centos7用的是devicemapper.但是,devicemapper在性能上有問題。linux 在3.18版本後把overlayfs整合到內核裏,docker-ce目前在centos7上支持的文件系統為overlay
,使用overlay作為docker的後端存儲機制,如果是按照extras源裏的docker包,版本1.12,後端的存儲為devicemapper文件系統

2 Regeistry介紹

Registry用於保存docker鏡像,包括鏡像的層次結構和元數據,RegistryRepositoryIndex兩個組件組成

啟動鏡像時,docker daemon會試圖從本地獲取相關的鏡像,本地鏡像不存在時,將從registry中下載該鏡像並保存到本地。

registry是一個無狀態,高可擴展的服務端應用程序,可以用於存儲和分發docker 鏡像。docker registry裏,index是一個重要組件,讓用戶可以查詢搜索到相關的鏡像,同時index支持認證功能。

registry分為兩種:

公共的registry,如docker hub,

私有化docker registry,自己搭建的registry。

通過應用程序包docker-distribution.x86_64 來實現私有registry搭建,在extras倉庫中。這個軟件沒有web頁面,也不支持認證。可以通過nginx配置反代,在nginx上實現認證

或者通過harbor這個軟件才實現私有化倉庫搭建,這個軟件有vmware公司維護,企業級的容器registry,是在docker-distribution基礎上添加功能實現的。建議用harbor創建私有registry(倉庫)

3 Repository介紹

Repository是指由某特定的docker鏡像的所有叠代版本組成的鏡像倉庫,一個Registry內部有多個Repository.其中,Repository可風味“頂層倉庫”和“用戶倉庫”,用戶倉庫名稱格式為“用戶名/倉庫名”。

每個倉庫可以包含多個Tag(標簽),每個標簽對象對應一個鏡像,可以手動打標簽,如果和官方有沖突,以本標簽地為準,統一鏡像可以有多個標簽,tag不一樣,但是image id一樣,便簽配置命令如下,把busybox的鏡像latest版本,再打一個標簽為sunny01,則busybox同時有兩個標簽,image id一樣

 docker tag busybox:latest busybox:sunny01

4 Index介紹

用於維護用戶賬號,鏡像的校驗以及公共名稱空間的信息

相當於為registry提供了一個可以完成用戶認證等功能的檢索接口

5 docker hub功能介紹

docker hub支持如下組件

image repositories:鏡像倉庫

automated builds:當修改原碼倉庫時自動構建鏡像,只需要上傳dockerfile就會構建鏡像

webhooks:自動構建的屬性之一,當成功推送一個文件到倉庫後webhooks觸發一個動作

organizations:工作組

github and bitbucket integration:和github整合起來,在github上開發,定義webhooks,當監控到github有新的推送後,自動執行構建鏡像,完成鏡像構建。

使用docker hub之外的第三方倉庫,推送鏡像,需要指定如下信息

向那個倉庫的那個端口,哪個名稱空間推送鏡像,鏡像名稱和標簽是什麽,其中port默認為5000,命令如下

docker pull  <registry>[:<prot>]/[<namespace>/]<name>:<tag>

6 基於容器制作鏡像

制作鏡像三個方法

1.基於容器制作

2.基於dockerfile實現,鏡像制作的程序文件

3.Docker Hub Automated Builds

這裏僅介紹基於容器制作鏡像

1.基於容器實現

啟動容器後,將新的操作制作為新鏡像

例子

啟動幹凈的鏡像文件busybox,然後再容器內創建httpd的根目錄和index.html文件,然後制作成行的鏡像

啟動容器,名稱為sunny01img

docker run -it --name sunny01img busybox:sunny01
#在容器內進行修改
/ # mkdir -p /web/html
/ # cd /web/html
/web/html # vi index.html
<h1>this is sunny docker image,it is a nice day!<\h1>

在另一個終端,執行如下命令

 docker commit -a "sunny<[email protected]>" -p -m "for test commit image"  sunny01img

用命令查看新生成的鏡像

docker images

查看到有tag為none的新生成的鏡像

將鏡像推送到阿裏雲鏡像倉庫中

登錄https://dev.aliyun.com,選擇產品和服務--》容器鏡像服務--》鏡像倉庫,創建一個本地倉庫,名稱為sunnytest

首先給本地鏡像打標簽

docker tag 3498bc48a842 registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb

這裏的鏡像名稱為新建的倉庫名

將打了標簽的鏡像推送到阿裏雲,要先登錄倉庫


docker login registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest

這裏registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest 為新建的倉庫名,輸入賬號為開發者平臺的賬號,密碼為Registry登錄密碼,不是登錄開發者平臺密碼

登錄成功後,將鏡像推送到阿裏雲倉庫sunnytest上,把鏡像推送到遠程倉庫,用push實現


 docker push registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb

這裏的registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb是鏡像名:tag

使用新的鏡像來啟動容器

新建一個標簽

docker tag 3498bc48a842 websrv:sunnyweb01

將新的鏡像websrv:sunnyweb01 運行為守護模式(-d,即後臺),然後指定進程為httpd,前端運行模式(-f),指定家目錄為/web/html

docker run --name sunnyweb01 -d websrv:sunnyweb01 httpd -f -h /web/html

查看

docker ps

查看到websrv:sunnyweb01鏡像運行為容器sunnyweb01.

查看進程信息

 docker top sunnyweb01

查看詳細容器信息

docker inspect sunnyweb01

查看到當前的容器ip為172.17.0.3

測試httpd的服務

curl 172.17.0.3

改變容器的默認啟動命令

在第一版新建鏡像websrv:sunnyweb01的基礎上創建第二版的鏡像,

在另一個終端上,不執行默認的cmd,而是默認啟動httpd服務

首先,先啟動鏡像,進入cmd,執行相關命令

docker run --name sunnyweb02 -it websrv:sunnyweb01

打開另一個shell終端,執行如下命令,生成一個新的鏡像

docker commit -a "sunny <[email protected]>" -p -m "web server" -c 'CMD ["/bin/httpd","-f","-h","/web/html"]' sunnyweb02

註意,-c,修改運行中的命令,後接一個字典,所有的字段都要分別傳遞,用引號引用,逗號隔開,否則參數傳遞失敗,導致鏡像不能啟動。

sunnyweb02是指當前要作為鏡像的模板容器名稱,如這裏以sunnyweb02這個容器作為模板來創建新鏡像

給新生成的鏡像打標簽

docker tag 990ff989b8fb registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb2.0

經新生成的鏡像推送到阿裏雲倉庫

 docker push registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb2.0

啟動鏡像,容器名稱為web2.0,並且運行在後臺(-d)

docker run --name web2.0 -d registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb2.0

測試

查看容器是否正常運行

docker ps

查看容器的ip

docker inspect web2.0

這裏查看到ip 為 172.17.0.6

測試httpd服務


curl 172.17.0.6

這個例子說明,制作鏡像是可以-c改變默認的命令,而不是默認的sh命令,可以讓容器基於新建鏡像啟動時運行指定的命令。

7 分發鏡像文件

docker允許把鏡像導入和導出,包括鏡像的源屬性信息和所有層存儲為tar格式的打包文件,並在其他服務器導入該鏡像,並運行

導出鏡像

默認情況下,會把導出文件打印在屏幕,因此需要用參數-o來指定輸入的鏡像文件

命令如下


docker save -o /root/testsave.tar sunnytest3:1.0

/root/testsave.tar 的鏡像打包文件傳到運行docker服務的10.10.10.73的服務器上


scp testsave.tar 10.10.10.73:/root

10.10.10.73上導入鏡像

註意,確保 10.10.10.73安裝docker,且運行docker服務,-i選項是指從tar備份文件輸入,而不是從標準輸入來輸入數據

docker load -i testsave.tar

10.10.10.73運行導入的鏡像sunnytest3:1.0,後臺運行(-d)

 docker run --name testload -d sunnytest3:1.0

測試

容器啟動成功後,運行一個httpd服務,因此用curl進行測試

 curl 172.17.0.2

以上用於分發需求較少的情況下使用,只能在數量不多,分發需求較少的環境實現。註意12版和17版命令有區別,17 docker image save / load

命令docker image --help來查看更多選項的介紹

用docker image history 查看鏡像的操作歷史

docker image history sunnytest3:1.0

命令stats用來統計容器的數據,查看容器的資源利用狀態,動態刷新,如容器的CPU,內存,網絡等信息,如下命令,統計容器testload的信息

docker stats testload


Docker 之 基於容器的鏡像制作