Docker學習筆記五:基於Commit定製鏡像

之前我們用到的鏡像,無論是ubuntu鏡像還是busybox鏡像,都是來自於官方Docker Hub中的鏡像。直接使用這些鏡像是可以滿足一定的需求,而當這些鏡像無法直接滿足需求時,就需要在這些鏡像的基礎上修改,來定製符合實際需求的鏡像。
以定製一個Web服務器鏡像爲例子講述如何定製一個鏡像。
在nginx鏡像的基礎上,定製一個以“Hello Docker”爲nginx歡迎界面的新鏡像nginx:v1.0。

對容器做出修改

首先使用docker pull nginx:latest從Docker Hub中拉取一個nginx:latest鏡像,其中Nginx是一款自由的、開源的、高性能的HTTP和反向代理服務器。

在Docker中,我們無法直接查看一個鏡像的內容,而且因爲鏡像是隻讀的,所以也無法對鏡像做出任何修改。但是如果以鏡像爲基礎創建並啓動一個容器,該容器會擁有鏡像的全部內容,也就通過容器查看鏡像的內容。除此以外,容器是可讀寫的!

nginx歡迎界面的內容保存在/usr/share/nginx/html/index.html中,如果想要將nginx歡迎界面的內容修改爲“Hello Docker”,只需要將/usr/share/nginx/html/index.html替換爲“Hello Docker”即可了。

執行docker run --name webserver -d -p 80:80 nginx命令,這條命令以nginx基礎鏡像創建了一個名爲webserver的容器,在這條命令中出現了一個以前沒有介紹的命令選項-p,-p用於端口映射,以此條命令爲例,-p 80:80代表將宿主機的80端口映射到容器的80端口,這意味着可以直接通過訪問宿主機ip:80訪問到容器的80端口!

容器創建完成後,執行docker exec -it webserver /bin/bash進入webserver容器。並且將/usr/share/nginx/html/index.html的內容修改爲Hello Docker!。如下所示:

[root@localhost Desktop]# docker exec -it webserver /bin/bash
root@da9d93718c3d:/# echo '<h1>Hello Docker!</h1>' > /usr/share/nginx/html/index.html
root@da9d93718c3d:/# cat /usr/share/nginx/html/index.html
<h1>Hello Docker!</h1>

在瀏覽器中訪問localhost:80,歡迎界面變成了“Hello Docker”。

將“對容器的修改”保存爲鏡像

在Docker中提供了一個命令docker commit,該命令會把對容器的修改提交成一個鏡像。換句話說,就是在原有鏡像的基礎上,再疊加上容器的存儲層(該存儲層僅僅保存了容器所做的修改),將這些內容構成一個新的鏡像。docker commit的基本語法如下:

docker commit [OPTIONS] CONTAINER [鏡像名]

其中:

  • docker commit:Docker拉取鏡像的命令關鍵詞;
  • [OPTIONS]:命令選項,其中–author指定作者,–message制定commit的信息;
  • CONTAINER:需要commit的容器;
  • 鏡像名:新鏡像的名字,以<倉庫名>:<標籤>的方式來指定。如果不顯示設置,將默認爲None:None。(這個代表沒有指定鏡像名)

現在將對webserver容器做出的修改提交爲一個新鏡像nginx:v1,只需要執行docker commit webserver nginx:v1。

現在驗證nginx:v1鏡像的歡迎界面的內容是否變成了“Hello Docker”

首先執行docker commit webserver nginx:v1,將對webserver容器做出的修改提交爲一個新鏡像nginx:v1。然後執行docker run -p 50:80 nginx:v1 cat /usr/share/nginx/html/index.html,以nginx:v1爲基礎鏡像創建啓動一個新容器,並將宿主機的50端口映射到容器的80端口。可以看到nginx歡迎界面的內容爲Hello Docker!,這說明我們成功了!!

[root@localhost Desktop]# docker commit webserver nginx:v1
sha256:081c446e9b657ac966dd7466fd93614a71a945600f9fe182435168554351c236
[root@localhost Desktop]# docker run -p 50:80 nginx:v1 cat /usr/share/nginx/html/index.html
<h1>Hello Docker!</h1>

使用commit定製鏡像的缺陷

在實際的環境中,我們一般不會使用Commit去構建一個鏡像,因爲它存在很多的缺陷:

首先,由於commit會將對容器做出所有的修改都保存爲鏡像,這就意味着我們可能會保存許多不必要的文件變化,例如我僅僅只是爲了修改nginx的歡迎頁,但是我新增了一些文件,那麼這些文件也會跟着保存到鏡像中去,顯然它們是多餘的。

此外,docker commit意味着所有對鏡像的操作都是黑箱操作,生成的鏡像也被稱爲黑箱鏡像,換句話說,就是除了製作鏡像的人知道執行過什麼命令、怎麼生成的鏡像,別人根本無從得知。而且,即使是這個製作鏡像的人,過一段時間後也無法記清具體在操作的。雖然docker diff或許可以告訴得到一些線索,但是遠遠不到可以確保生成一致鏡像的地步。這種黑箱鏡像的維護工作是非常痛苦的。

既然docker commit存在這麼多缺陷,是不是有更好的替代方法呢?沒錯,不要着急。後面我們會介紹更好的定製鏡像的方法:Dockerfile!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章