Dockerfile 自动制作 Docker 镜像(三)—— 镜像的分层与 Dockerfile 的优化
Dockerfile 自动制作 Docker 镜像(三)—— 镜像的分层与 Dockerfile 的优化
前言
a. 本文主要为 Docker的视频教程 笔记。
b. 环境为 CentOS 7.0 云服务器
c. 上一篇:Dockerfile自动制作Docker镜像(二)—— 其它常用命令
1. 基本原理
镜像是按照互相的依赖关系逐层的构建起来的。比如:nginx 镜像依赖于 centos 镜像,而 php 镜像依赖于 nginx 镜像,则 php 镜像有3层:php,nginx,centos;nginx 镜像有2层:nginx 镜像和 centos 镜像。在分层中,每层只存储比较于上一层变化的部分,而不必存储所有依赖的镜像。
a.删除示例:
例如:基于 alpine 镜像制作了一个 apline1 镜像,删除 alpine 镜像实际上只是删除了标签。如果删除并重新导入 alpine,同样会还原 alpine 的原始镜像而不是重新添加。
Dockerfile 文件:
[root@VM_0_2_centos layer]# cat dockerfile
FROM alpine:latest
COPY test.txt /
构建完成后,删除原 alpine 镜像,可以看到只是 Untagged ,而并没有实际删除层(因为有 alpine1 镜像依赖于 alpine 镜像)(见1)。查看镜像的构建历史, 可以看到依赖的最底层的镜像变为了 <missing>(见2) 。此时再次导入 alpine 的镜像,可以看到实际上并没有导入层。但再次查看镜像的构建历史,结果仍为<missing>,而没有还原为原来的镜像名(见3)。
b. 文件结构查看示例
切换到 docker 数据存放的目录,可以看到,对于某些镜像,没有 parent ,而某些镜像的 parent 指向其它镜像:
TIPS: 如果直接使用 cat 输出某些文件,如果文件的最后不是换行符,则会在同一行返回,很不美观,如:
此时利用 echo 命令 :
echo `<YOUR_COMMAND>`
2. Dockerfile 优化策略
-
选择尽可能小的 Linux,如 alpine
-
尽可能合并 RUN 指令(使用 “&&” 连续执行 和 “\” 换行)
-
清理无用的文件(yum 缓存,拷贝进去的源码包)
-
修改 Dockerfile,把变化的内容尽可能放在 Dockerfile 结尾(以较多地利用缓存)
-
使用 .dockerignore
Docker 在构建镜像时,会把当前路径下的所有文件传输至 Docker 服务进程,可以在 .dockerignore 中添加文件以避免传输至服务进程,加快构建速度。如当前目录下有个 baidupinyin.zip 和 test.txt 文件,加入 .dockerignore 文件(文件中直接写要排出的文件名即可,有多个则换行)前后对比:
后记
今天早上正好看到了新闻,发现百度发布了可用于Deepin 和 Ubuntu 的输入法(CentOS 的 OS:那你就拿我实验???),因此想到了以此来演示排除文件。但是比较坑的是,百度给的下载链接要经过一次重定向才能指向真正的下载路径。
原路径为:
http://srf.baidu.com/?c=j&e=d&from=1000e&platform=l64&ref=index_entrance_android_click
重定向后的路径为:
https://imeres.baidu.com/imeres/ime-res/guanwang/img/Ubuntu_Deepin-fcitx-baidupinyin-64.zip
所以要给 curl 加参数 -L 表示跟踪重定向:
curl -L -o baidupinyin.zip 'http://srf.baidu.com/?c=j&e=d&from=1000e&platform=l64&ref=index_entrance_android_click'
需要注意的是,此时依然不能使用 -O 使用自动文件名,否则会把原路径服务器地址后的所有字符作为路径名。在此处就变成了了“?c=j&e=d&from=1000e&platform=l64&ref=index_entrance_android_click”。curl 后的下载路径要用引号引起来。