docker镜像大小优化方法

Docker镜像是由很多镜像层(Layers)组成的(最多127层), dockerfile 中的每个 FROM、RUN、COPY 命令都会创建一个单独的层,并增加镜像的整体大小和构建时间。

这个可以通过命令 docker history image_id 来查看每一层的大小

docker history image_id

1.我们可以减少 Dockerfile 中的层数

#myyii
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install mysqli

#myyii2
RUN docker-php-ext-install pdo_mysql \
    && docker-php-ext-install mysqli

查看大小确实少了1MB

 2.使用精简的基础镜像

alpine

Alpine一个基于 musl libc 和 busybox、面向安全的轻量级 Linux 发行版,压缩体积只有 3M 左右,很多流行的镜像都有基于 alpine 的制作的基础镜像。

scratch

scratch 是一个空镜像,如果你的应用是一个包含所有依赖的二进制(不依赖动态链接库),可以使用 scratch 作为基础镜像,这样镜像的体积几乎就等于你 COPY 进去的二进制的体积。

busybox

如果你希望镜像里可以包含一些常用的 Linux 工具,busybox 镜像是个不错选择,它集成了一百多个最常用 Linux 命令和工具的软件工具箱,镜像压缩体积只有不到 1M,非常便于构建小镜像

distroless

distroless 镜像,它仅包含您的应用程序及其运行时依赖项。它们不包含您希望在标准 Linux 发行版中找到的包管理器、shell或任何其他程序。 由于Distroless是原始操作系统的精简版本,不包含额外的程序。容器里并没有Shell!如果黑客入侵了我们的应用程序并获取了容器的访问权限,他也无法造成太大的损害。也就是说,程序越少则尺寸越小也越安全。不过,代价是调试更麻烦。

Distroless vs Alpine

如果是在生产环境中运行,并且注重安全性, Distroless 镜像可能会更合适。

Docker镜像中每增加一个二进制程序,就会给整个应用程序带来一定的风险。在容器中只安装一个二进制程序即可降低整体风险。

举个例子,如果黑客在运行于Distroless的应用中发现了一个漏洞,他也无法在容器中创建Shell,因为根本就没有。

如果更在意要是大小,则可以换成Alpine基础镜像。

这两个都很小,代价是兼容性。Alpine用了一个稍稍有点不一样的C标准库————muslc,时不时会碰到点兼容性的问题。

3.使用多阶段构建来减小大小

Dockerfile 支持多阶段构建,即有多个 FROM 指令,最终构建出的镜像由由最后一个 FROM 之后的指令决定,通常可以把这之前的指令用作编译,之后的指令用作打包,打包阶段可以将编译阶段产生的文件拷贝过来,这样可以实现在最终镜像中只保留运行程序所需要的内容

FROM golang:latest AS build
WORKDIR /workspace
COPY . .
# 静态编译二进制
RUN CGO_ENABLED=0 go build -o app -ldflags '-w -extldflags "-static"' .

FROM scratch
# 拷贝二进制到空镜像
COPY --from=build /workspace/app /usr/local/bin/app
CMD ["app"]

 4.优化.dockerignore文件

如果您不想将某些文件复制到 docker 镜像,那么使用 .dockerignore 文件可以为您节省一些空间。

在构建上下文中有一些隐藏的文件/文件夹,您可以使用 ADD 或 COPY 命令(如 .git 等)将其传输到镜像。使用 .dockerignore 文件来排除不需要的文件

# 排除编译生成的文件
bin/
obj/
 
# 排除日志文件
*.log
 
# 排除编辑器临时文件
*.tmp
*.swp
 
# 避免排除子目录下的对象文件
!obj/
 
# 排除所有的 .md 文件,除了 README.md
*.md
!README.md
 
# 排除所有的 .git 目录
.git/
 
# 排除 .dockerignore 文件本身
.dockerignore

5.清理不必要的文件、移除不必要的依赖

在构建过程中,删除不必要的文件和目录可以减少镜像大小

FROM ubuntu:18.04
RUN apt-get update && apt-get install -y \
    package-bar \
    package-baz && \
    rm -rf /var/lib/apt/lists/*
    
# 删除不必要的文件
RUN chown -R www-data:www-data /var/www/html \
       && rm -rf /var/www/html/.git \
       && rm -rf /var/www/html/.idea \
       && rm -rf /var/www/html/.gitlab-ci.yml \
       && rm -rf /var/www/html/tests \
       && rm -rf /var/www/html/vendor/bin

6.docker 镜像瘦身工具

1.Dive镜像分析工具,用于探索 Docker 镜像,各层内容以及发现缩小 Docker/OCI 镜像大小的方法。

地址: https://github.com/wagoodman/dive

docker pull wagoodman/dive

docker run --rm -it \
    -v /var/run/docker.sock:/var/run/docker.sock \
    wagoodman/dive:latest <你的镜像名字:tag>

2.docker 镜像瘦身工具docker-slim

地址: https://github.com/slimtoolkit/slim

#压缩示例:

Node.js application images:
from ubuntu:14.04 - 432MB => 14MB (minified by 30.85X)
from debian:jessie - 406MB => 25.1MB (minified by 16.21X)
from node:alpine - 66.7MB => 34.7MB (minified by 1.92X)
from node:distroless - 72.7MB => 39.7MB (minified by 1.83X)

Python application images:
from ubuntu:14.04 - 438MB => 16.8MB (minified by 25.99X)
from python:2.7-alpine - 84.3MB => 23.1MB (minified by 3.65X)
from python:2.7.15 - 916MB => 27.5MB (minified by 33.29X)
from centos:7 - 647MB => 23MB (minified by 28.57X)
from centos/python-27-centos7 - 700MB => 24MB (minified by 29.01X)
from python2.7:distroless - 60.7MB => 18.3MB (minified by 3.32X)

Ruby application images:
from ubuntu:14.04 - 433MB => 13.8MB (minified by 31.31X)
from ruby:2.2-alpine - 319MB => 27MB (minified by 11.88X)
from ruby:2.5.3 - 978MB => 30MB (minified by 32.74X)

Go application images:
from golang:latest - 700MB => 1.56MB (minified by 448.76X)
from ubuntu:14.04 - 531MB => 1.87MB (minified by 284.10X)
from golang:alpine - 258MB => 1.56MB (minified by 165.61X)
from centos:7 - 615MB => 1.87MB (minified by 329.14X)

安装: 

  • Latest Mac binaries (curl -L -o ds.zip https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_mac.zip)
  • Latest Mac M1 binaries (curl -L -o ds.zip https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_mac_m1.zip))
  • Latest Linux binaries (curl -L -o ds.tar.gz https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux.tar.gz)
  • Latest Linux ARM binaries (curl -L -o ds.tar.gz https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux_arm.tar.gz)
  • Latest Linux ARM64 binaries (curl -L -o ds.tar.gz https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux_arm64.tar.gz)

Linux (安装Latest Linux binaries dist_linux.tar.gz ):

tar -xvf ds.tar.gz
mv  dist_linux/slim /usr/local/bin/
mv  dist_linux/slim-sensor /usr/local/bin/
mv  dist_linux/docker-slim /usr/local/bin/

具体步骤:

我们拉取一个python的镜像

docker pull python

查看python镜像917MB

使用docker-slim优化一下python镜像

#说明  --http-probe默认会开启http的探测,安装时可以关闭 
docker-slim build --http-probe=false -target python:tag --tag new/python(镜像名字)

#也可以执行,他会在原有名字上加.slim即python.slim
docker-slim build --http-probe=false python

#执行命令
docker-slim build --http-probe=false -target python:latest --tag new/python

执行之后docker images查看镜像大小到了28.2MB

和所说的from python:2.7.15 - 916MB => 27.5MB (minified by 33.29X) 差不多

构建之后会在所在的当前目录生成一个slim.report.json的文件

查看cat slim.report.json 会看到里面详情的构建过程

类似于docker inspect 镜像id 

#docker inspect 命令用于获取 Docker 容器或镜像的底层信息。如果你想要获取特定镜像的信息,你需要提供镜像的 ID 或者名称。 
docker inspect 镜像id 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值