文章目录
1. 为什么要做镜像优化?
随着我们对 docker 镜像的持续使用,在此过程中如果不加以注意并且优化,镜像的体积会越来越大
很多时候我们在使用 docker 部署应用时,会发现镜像的体积至少有 1G 以上
镜像体积的增大,不单单会增加磁盘资源与网络资源的开销,也会影响应用的部署效率,使得应用的部署时间会越来越长
因此我们需要减少部署镜像的体积以加快部署效率,降低资源的开销
而对于镜像的优化,可以通过对 dockerfile 的优化来实现
2. 构建镜像的几个原则
(1) 镜像最小化原则
选择最精简的基础镜像
选择体积最小的基础镜像可有效降低镜像体积。如:alpine、busybox 等.
清理镜像构建的中间产物
构建镜像的过程中,当 dockerfile 的指令执行完成后,删除镜像不需要用的的文件。
如使用 yum 安装组件,最后可使用 yum clean all 镜像清理不需要的文件或者使用系统 rm 命令删除不需要的源文件等。
减少镜像的层数
镜像是一个分层存储的文件,并且镜像对层数也是有一定数量的限制,当前镜像的层数最高是 127 层,
如果不多加注意,将会导致镜像越来越臃肿。
在使用 dockerfile 构建镜像时,dockerfile 中的每一条指令都会生成一个层,
因此可以通过合并 dockerfile 中可合并的指令,减少最终生成镜像的层数。
例如:在 dockerfile 中使用 RUN 执行 shell 命令是,可以用 ”&&” 将多条命令连接起来
采用最最基础的镜像
:
镜像越小越精简
(2) 构建速度最快化原则
充分利用镜像构建缓存
我们可以利用构建的缓存来加快镜像构建速度,Docker 构建默认会开启缓存,缓存生效有三个关键点,
镜像父层没有发生变化,构建指令不变,添加文件校验和一致。
只要一个构建指令满足这三个条件,这一层镜像构建就不会再执行,它会直接利用之前构建的结果。
某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效。
我们应该把变化最少的部分放在 Dockerfile 的前面,这样可以充分利用镜像缓存。
dockerfile 中有可能导致缓存失效的命令 WORKDIR、CMD、ENV、ADD 等,
像这些命令最好放到 dockerfile 底部,以便在构建镜像过程中最大限度使用缓存。
删除构建目录中(默认:Dockerfile 所在目录)不需要用的的文件
编写. dockerignore 文件过滤构建过程中不必要的文件或者创建单独的目录,并且目录中仅存在镜像构建过程中需要使用的文件。
Docker 在运行时分为 Docker 引擎(也就是服务端守护进程)和客户端工具。
Docker 的引擎提供了一组 REST API,被称为 Docker Remote API,
而如 docker 命令这样的客户端工具,则是通过这组 API 与 Docker 引擎交互,从而完成各种功能。
因此,虽然表面上我们好像是在本机执行各种 docker 功能,但实际上,一切都是使用的远程调用形式在服务端(Docker 引擎)完成。docker build 命令构建镜像,其实并非在本地构建,而是在服务端,也就是 Docker 引擎中构建的。
构建镜像时,Docker 需要先准备 context ,将所有需要的文件收集到进程中。
默认的 context 包含 Dockerfile 目录中的所有文件。
(3) 注意优化网络请求
我们使用一些镜像源或者在 dockerfile 中使用互联网上的 url 时,
去用一些网络比较好的开源站点,这样可以节约时间、减少失败率。
3. 在虚拟机模拟源码编译 nginx
选择最精简的基础镜像
减少镜像的层数
清理镜像构建的中间产物
注意优化网络请求
尽量去用构建缓存
启动docker
:
查看镜像并删除无用的镜像
:
先源码编译nginx,熟悉步骤后好在容器中运行nginx
:
关闭debug
:
查看执行命令
:
4. 镜像的优化
阶段构建镜像接下来我们以 rhel7 镜像构建容器,并在容器中安装 nginx 的源码包。以此容器构建新的镜像并做做优
(1) 在真机上面给 server1 传两个包
优化思路:将RUN都放在一行,减少镜像层数
:
编写 Dockerfile 如下
优化思路:使用多阶段构建
:
Dokcerfile 如下:
先模拟命令行关闭 debug:
优化思路:从底层优化
:
首先我们需要导入一个distroless和nginx镜像
distroless”镜像只包含应用程序及其运行时依赖项,不包含程序包管理器、shell以及在标准Linux发行版中可以找到的任何其他程序
用distroless去除容器中所有不必要的东西
- 从 github 网站查看例子:
(2) 从真机给 server1 发送东西
(3)导入镜像
(4) 编写 Dockerfile 如下
(5) 构建镜像并查看镜像大小
(6) 构建容器并测试
查看 IP 并能正常访问到 Nginx 默认发布页,证明容器镜像可以正常使用,但只要内网可以访问:
按照查看桥接的工具:
查看桥接:
做端口映射
可以通过外网访问了: