Docker镜像优化:如何从1.16GB优化到22.4MB

标签: docker 镜像 优化 | 发表时间:2021-02-17 22:16 | 作者:megrez
出处:http://weekly.dockone.io

https://miro.medium.com/proxy/0*cwFmgUG9LI9s97lX.png

图源  www.docker.com

Docker是软件开发者和系统管理员用容器构建、运行和共享应用程序的平台。一个 容器是一个运行在隔离环境中、拥有自己的文件系统上的进程;这个文件系统是使用 docker镜像构建的。镜像文件包括运行应用程序所需的一切(编译后的代码、依赖关系、库等)。镜像可以使用一个名为 Dockerfile的文件来定义

术语 Docker化(dockerization)或者 容器化(containerization)通常用于定义创建Docker容器的过程。

容器之所以流行,是因为它们具有以下一些特点,
  • 灵活:即使是最复杂的应用也可以被容器化。
  • 轻量级:容器共享主机内核,使其比虚拟机更高效。
  • 可移植:可在本地编译并在任何地方运行。可在本地编译并在任何地方运行。
  • 松耦合:容器各自是独立封装的,允许一个容器被替换或升级而不影响、中断其他容器。
  • 安全:容器采用积极的限制和隔离策略,不需要用户进行任何配置。


在本篇文章中,我将专注于优化Docker镜像以实现轻量级。

让我们从一个例子开始:在这个例子中,我们构建了一个React应用程序,我们想要将其docker化。运行 npx命令并创建Dockerfile后,我们的文件结构就像 图1一样。
npx create-react-app app --template typescript  


https://miro.medium.com/proxy/0*CwWLe_mX6YXnVlW5.png

图1: 文件结构

如果我们构建一个基础的Dockerfile,我们会得到一个如下所示的1.16GB的Docker镜像:
FROM node:10  

WORKDIR /app
COPY app /app
RUN npm install -g webserver.local
RUN npm install && npm run build

EXPOSE 3000
CMD webserver.local -d ./build


https://miro.medium.com/proxy/0*M2WiAKbrcoIwDO8W.png

图2: 镜像的初始大小为1.16GB

初次优化**: 使用轻量级的基础镜像**

Docker Hub(公共Docker仓库)中,有多个镜像可供下载,每个镜像都有不同的特点和大小。

通常情况下,基于 AlpineBusyBox的镜像与基于 Ubuntu等其他Linux发行版的镜像相比,体积极小。这是因为Alpine和其他的映像已经被优化,包含了最少的但必要的软件包。在下图中,你可以看到Ubuntu、Alpine、Node和基于Alpine的Node基础镜像大小的对比。

https://miro.medium.com/proxy/0*NyJgka2ebrfG6nzJ.png

图3: 不同大小的基础镜像

通过修改Dockerfile,使用Alpine作为基础镜像,最后我们的镜像大小是330MB:
FROM node:10-alpine  

WORKDIR /app
COPY app /app
RUN npm install -g webserver.local
RUN npm install && npm run build

EXPOSE 3000
CMD webserver.local -d ./build


https://miro.medium.com/proxy/0*qwtP4fm0dUL7VnN-.png

图4: 镜像优化后大小是330MB

第二次优化**: 使用多阶段构建**

通过多阶段构建,我们可以在Dockerfile中使用多个基础镜像,并将工件、配置文件等从一个阶段复制到另一个阶段,这样我们就可以丢弃不需要的东西。

在这个例子中,我们部署React应用需要的是编译后的代码,我们不需要源文件,也不需要 node_modules目录,也不需要 package.json等。

通过将Dockerfile改成下面这样,我们的镜像最终大小为91.5 MB。值得注意的是,上一阶段的镜像(第1-4行)不会自动删除,Docker会将其保存在缓存中,以便我们在另一个构建中使用相同阶段时运行速度更快,所以必须手动删除。
FROM node:10-alpine AS build  
WORKDIR /app
COPY app /app
RUN npm install && npm run build

FROM node:10-alpine
WORKDIR /app
RUN npm install -g webserver.local
COPY --from=build /app/build ./build
EXPOSE 3000
CMD webserver.local -d ./build


https://miro.medium.com/proxy/0*HKFCdIosZROgm8Vx.png

图5: 在第二次优化以后镜像的大小是91.5MB

现在,我们有一个Docker文件,其中定义有两个阶段:在第一个阶段,我们编译项目。在第二个阶段,我们将应用程序部署在Web服务器上。然而,Node容器并不是服务静态资源(HTML、CSS和JavaScript文件、图片等)的最佳选择,最佳的选择是使用像 NginxApache这样的服务器。在这种情况下,我选择使用Nginx。

通过将Docker文件改成下面这样,我们的镜像最终大小为22.4 MB。如果我们运行这个容器,我们可以看到这个应用能够正常工作( 图7)。
FROM node:10-alpine AS build  
WORKDIR /app
COPY app /app
RUN npm install && npm run build

FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]


https://miro.medium.com/proxy/0*HkJiAQcGsFz0UXXy.png

图6: 在第三次优化以后镜像大小为22.4MB

https://miro.medium.com/proxy/0*IX32KFTFcYcEuY5N.png

图7: 执行容器的最终结果

参考

相关 [docker 镜像 优化] 推荐:

Docker镜像优化:如何从1.16GB优化到22.4MB

- - DockOne.io
图源  www.docker.com. Docker是软件开发者和系统管理员用容器构建、运行和共享应用程序的平台. 一个 容器是一个运行在隔离环境中、拥有自己的文件系统上的进程;这个文件系统是使用 docker镜像构建的. 镜像文件包括运行应用程序所需的一切(编译后的代码、依赖关系、库等). 镜像可以使用一个名为 Dockerfile的文件来定义.

Docker镜像仓库Harbor

- - 灰狐博客
Habor是由VMWare公司开源的容器镜像仓库. Habor是在Docker Registry上进行了相应的企业级扩展,这些企业级特性包括:管理用户界面,基于角色的访问控制 ,AD/LDAP集成以及审计日志等. 京东使用了Harbor搭建了自己的私有Dockr镜像仓库. 用Harbor实现容器镜像仓库的管理和运维.

几款 Shadowsocks 的 Docker 镜像

- - Shadowsocks非官方网站
Docker 是一个开放源代码软件项目,让应用程序布署在软件容器下的工作可以自动化进行,借此在 Linux 操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化的自动管理机制. Docker 利用 Linux 核心中的资源分脱机制,例如 cgroups,以及 Linux 核心名字空间(name space),来创建独立的软件容器(containers).

解决Docker镜像爆满的问题

- - holmofy
使用过docker的人都知道,在正常情况下. 我们使用multi-stage构建利用docker镜像缓存机制,可以加快构建速度. 但是缓存的镜像一多,没有及时释放磁盘空间,磁盘就容易爆满. 容量 已用 可用 已用% 挂载点. 如果每次构建完手动 docker rmi又达不到加快构建速度的效果.

mdblog/Docker镜像中心.md at master · downgoon/mdblog · GitHub

- -
手把手体验DockerHelloWorld. Docker Image: 它是用来运行出. Docker Container的. nodejs image等. Docker Registry Mirrors: 为了让大家方便使用,不需要每个人都去制作. Docker Image,我们可以分享:你制作一个.

Docker 最佳实践:构建最小镜像

- - IT瘾-dev
镜像大小其实是衡量我们容器打包技术的重要指标,我们应该在不影响应用正常运行的情况下,尽量让我们的容器镜像变得更小,这样,不管是从安全还是维护效率角度来讲,都是最佳实践. 本文我们从两种情况阐述我们的问题和解决方案,我们从实现我们的application的编程语言角度,按照语言是解释型还是编译型语言来演示如何解决容器镜像体积大的问题.

docker/kubernetes国内源/镜像源解决方式

- - Xinkun Blog
最近在使用kubeadm时,被各种连接不上搞到崩溃. 这里统一整理了国内的一些镜像源,apt源,kubeadm源等,以便查阅. Azure China提供了目前用过的质量最好的镜像源. 而且都支持匿名拉取,也就是不需要登录. 这里,我开发了一个小的脚本azk8spull,这个脚本可以自动根据镜像名称进行解析,转换为azure的mirror镜像源域名.

Docker 最佳实践:5 个方法精简镜像

- - IT瘾-dev
本文记录了精简Docker镜像尺寸的必要性及好处. 上篇文章回顾: HBase实战:记一次Safepoint导致长时间STW的踩坑之旅. 精简Docker镜像的好处很多,不仅可以节省存储空间和带宽,还能减少安全隐患. 优化镜像大小的手段多种多样,因服务所使用的基础开发语言不同而有差异. 本文将介绍精简Docker镜像的几种通用方法.

使用Jib快速简便地创建Docker镜像

- - DockOne.io
在本文中,我们将看看Jib,它是Google提供的一个工具,可以轻松快速地创建Docker镜像. 无需创建Dockerfile文件,也无需安装Docker守护进程,Jib可直接使用. 到目前为止,我们一直使用来自Spotify的 dockerfile-maven-plugin来构建和推送Docker镜像.

Docker 多平台构建指南:构建 WebAssembly 镜像

- - Jimmy Song - 专注于探索后 Kubernetes 时代的云原生新范式 – 博客
Docker 多平台构建是一种用于构建 Docker 镜像以在多种 CPU 架构和操作系统上运行的技术. 它可以让用户在一个 Dockerfile 中定义一个通用的构建过程,然后使用 Docker CLI 命令将其构建为多个不同平台的镜像. 这些镜像可以在不同的计算机、云平台和容器编排系统上运行,从而为用户提供更广泛的部署选项.