衔接上一篇的内容,继续学习 Docker 的相关知识 主人博客
虚悬镜像
中间层镜像
列出部分镜像
docker images 会列出所以镜像,当添加多个镜像只好几个参数
以特定格式显示
docker images -q 显示所有镜像的id信息
下面的命令会直接列出镜像结果,并且只包含镜像 ID 和仓库名:
docker images -format "{{.ID}}:{{.Repository}}"
或者打算以表格等距显示,并且有标题行,和默认一样,不同自己定义列:
docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
利用 Commit 理解镜像构成
回顾知识:镜像是多层存储,每一层是前一层的基础上进行的修改;而容器也是多层存储,是在以镜像为基础层,在其基础上加一层作为容器运行时的存储层
我们定制一个 Web 服务器为例子,来讲解镜像是如何构建的。
docker run --name webserver -d -p 80:80 nginx
这条命令会用nginx镜像启动一个容器,名称为webserver,并且映射了80端口,如果使用的是 Docker for Windows 直接 通过 loclhost 访问。如果使用的是 Docker Toolbox ,或者是在虚拟机、云服务器上安装的 Docker ,则需要将 loclhost 换位虚拟机地址或者云服务器的地址
出现问题图片
docker: Error response from daemon: Conflict. The container name "/webserver"
is already in use by container
"9ea8beeb72c9f62b300ce1628f9a1660b37091636c8fc95774a3cb682b8b0819".
You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
问题:上述命令下载nginx 镜像后,再次报错?
解决:上述出错信息是你不能使用80端口,所以我们修改了端口,解决后的命令如下
docker run --name webserver -d -p 81:80 nginx
如果你的机器运行失败,使用docker ps -l
查看正在运行的镜像,然后docker kill commit_ID
结束并删除docker rm commit_ID
,然后在使用上面的命令,成功后返回一个 id
最后通过localhost:81访问
我们可以通过docker exec
命令进入容器,修复其内容
docker exec -it webserver bash
解释:我们以交互式终端方式进入 webserver 容器,并执行了 bash 命令, 也就是获得一个可以操作的 Shell。
然后,我们用 Hello ,Docker! 内容覆盖/usr/share/nginx/html/index.html
的内容
我们修改了容器的文件,也就是改动了容器的储存层。我们可以通过 docker diff 命令看到具体的改动
docker diff webserver
现在我们定制好了变化,将其保存下来形成镜像。Docker 提供了一个 docker commit 命令, 可以将容器的存储层保存下来成为镜像。 换句话说,就是在原有镜像的基础上,在叠加容器的存储层,并构成新的镜像
docker commit [选项] <容器ID或容器名>[<仓库名>[:<标签>]]
docker commit \
--author "didiaoyuan <didiaoyuan@gmail.com>" \
--message "修改了默认网页" \
webserver \
nginx:v2
现在我们可以在 docker images 中看到这个修改后的镜像:
docker images nginx
(注意在生成新nginx:v2的时候注意拼写错误,本人在这上面卡了一会!)
通过docker history
查看镜像内的历史变化
docker history nginx:v2
然后我们允许新的镜像
docker run --name web2 -d -p 82:80 nginx:v2
通过localhost:82访问
慎用 docker commit
大部分引用书上的解释和自己的理解,文书出处与 GitBook《Docker 从入门与实践》
虽然,上面解释 docker commit 可以直观的理解镜像的分层概念,但是实际上不会使用 commit 来生成镜像,而是使用 dockerfile 生成镜像。
原因:
1. 如果你仔细发现 docker diff webserver 的结果,会发现,除了我们修改的 index.html 文件外还有许多文件被改动了或者添加。如果是安装了软件包、编译构建,那会产生大量的无关内容被添加进来,会导致镜像十分臃肿。
2. 使用 docker commit 对镜像的操作都是暗箱操作,生成的镜像都是黑箱镜像,因为除了制作人知道怎么生成,别人都不清楚,何况时间久了制作人也不清楚具体的操作,所以这种操作维护起来很难。
3. 回顾之前的分层储存概念,除当前层外,之前的层是不会发生变化的,就是任何改变结果仅仅是在当前层进行操作(标记、添加、修改..)而不会改动上一层,使用 commit 制作镜像,以及后期修改,每一层都会让镜像更臃肿一次,所删除的上一层的东西不会消失,会一直如影随形的跟着这个镜像,只会让这个镜像更加臃肿。