初試Docker-打包構建鏡像


在 docker 中,鏡像的結構是以層次划分的,也就是可以在每一層上添加自己的修改,變成新的鏡像。

docker 兩種打包方式如下:

  • commit
  • build

 

docker commit

注意: docker commit 命令除了學習之外,還有一些特殊的應用場合,比如被入侵后保存現場等。但是,不要使用 docker commit 定制鏡像,定制鏡像應該使用 Dockerfile 來完成。

鏡像是容器的基礎,每次執行 docker run 的時候都會指定哪個鏡像作為容器運行的基礎。比如我們所使用的都是來自於 Docker Hub 的鏡像,比如不同的linux系統版本有不同的官方基礎鏡像,如 CentOs,Ubuntu。直接使用這些鏡像是可以滿足一定的需求,而當這些鏡像無法直接滿足需求時,我們就需要定制這些鏡像。接下來看看 docker run 如何定制鏡像。

以基礎的 centos 鏡像為例,我們想在這個鏡像上安裝 vim。

docker image ls -a

 

 進入容器內安裝

$ docker exec -it centos bash
root@3729b97e8226:/# yum install vim
exit
我們以交互式終端方式進入 centos 容器,並執行了 bash 命令,也就是獲得一個可操作的 Shell。
然后,我們用 yum 安裝 vim
 

要知道,當我們運行一個容器的時候(如果不使用卷的話),我們做的任何文件修改都會被記錄於容器存儲層里。而 Docker 提供了一個 docker commit 命令,可以將容器的存儲層保存下來成為鏡像。換句話說,就是在原有鏡像的基礎上,再疊加上容器的存儲層,並構成新的鏡像。以后我們運行這個新鏡像的時候,就會擁有原有容器最后的文件變化。
docker commit 的語法格式為:

docker commit [選項] <容器ID或容器名> [<倉庫名>[:<標簽>]]

我們可以用下面的命令來保存新修改的鏡像:

$ docker commit \
    --author "Nobody <nobody@gmail.com>" \
    --message "安裝了vim" \
    centos \
    centos:v2
sha256:07e33465974800ce65751acc279adc6ed2dc5ed4e0838f8b86f0c87aa1795214

我們可以在 docker image ls 中看到這個新定制的鏡像:

$ docker image ls centos
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos               v2                  07e334659748        9 seconds ago       272.5 MB
centos               latest              e43d811ce2f4        4 weeks ago         272 MB

我們還可以用 docker history 具體查看鏡像內的歷史記錄,如果比較 nginx:latest 的歷史記錄

 

 

docker build

相比 docker commit,此命令就簡單很多。直接新建 DockerFile 文件:

touch DockerFile

vim ./DockerFile

添加以下內容:

FROM centos
RUN yum install -y vim

意思是基於 centos 鏡像基礎上
然后使用 run 命令執行命令:yum install -y vim 
 
使用此文件來進行打包:
docker build -t blackbinbin/docker-centos-vim ./

打包過程也非常有意思

step1 是直接使用 centos 鏡像。step2 是創建一個臨時的容器來執行 yum install

這里是符合我們上面所說的 docker 鏡像是層次結構的結論,在之后的文章我們會詳細闡述為什么 docker 會使用這樣的文件結構形式。

最后移除臨時的容器

並且打包成新鏡像,ID=8bf3a6c43631 
 

Dockerfile 是一個文本文件,其內包含了一條條的 指令(Instruction),每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。這種描述性語言,比 commit 更符合工程化的思想,因為只要確定 DockerFile 任何人都可以構建出來一樣的鏡像,便於迭代,這也是為什么搞 docker 和 k8s 的經常會被認為是面向 yaml 編程,描述性語言的利用,讓構建和運維的流程更清晰,便於溝通和迭代。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM