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!!

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