返回介绍

5.3 镜像管理

发布于 2024-09-08 18:53:00 字数 7013 浏览 0 评论 0 收藏 0

镜像&容器清理

  • <none><none> iamge : 它们代表中间映像,可以使用 docker images -a 看到,它们不会导致磁盘空间问题,但这绝对是屏幕空间问题。

  • <none><none> —— dangling=true (会导致磁盘空间问题),可用 docker image prune 清除,可释放磁盘空间。

1. 批量删除 tag 为 None 的镜像

描述

原因 :有时候重新构建镜像(build) 的时候,该镜像正在被某容器使用中,那么在重新构建同名同版本镜像后,docker 保留原来的镜像,即容器还是用原来的,除非重启。那么原来的镜像名称变成 NONE,TAG 也成了 NONE。

解决方法:(4 种方法,慎用)

# 删除镜像
docker images|grep none|awk '{print $3}'|xargs docker rmi
docker rmi $(docker images | grep "^<none>" | awk "{print $3}")

# 清除 dangling 悬空镜像,下面二种清除方法
docker image prune
docker rmi $(docker images -f "dangling=true" -q)

2. 清理容器 (可以在镜像清理前操作)

# (推荐)删除停止的容器,可以回容器名。-a 显示所有  正在运行的容器要先停止 stop 才会被删除 rm
docker rm $(docker ps -a -q)

# 清理当前未运行的容器
docker container prune

# 停止正在运行的容器
docker stop $(docker container ls -q)
  1. 清理镜像和容器
# 清理已停止的容器、没有被容器使用的网络、悬空镜像、悬空构建缓存
$ docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - all dangling build cache

镜像体积裁减

体积分析

Docker 镜像是由很多镜像层(Layers)组成的(最多 127 层), Dockerfile 中的每条指定都会创建镜像层,不过 只有 RUN , COPY , ADD 会使镜像的体积增加 。这个可以通过命令 docker history image_id 来查看每一层的大小。 这里我们以官方的 alpine:3.12 为例看看它的镜像层情况。

$ docker images |grep alpine
alpine                                          latest       0ac33e5f5afa   5 weeks ago     5.57MB
redis                                           alpine       3900abf41552   5 months ago    32.4MB
python                                          3.4-alpine   c06adcf62f6e   3 years ago     72.9MB
$ docker image ls alpine
$ docker history 
# 查看 redis 镜像图层组成,使用 redis 镜像 ID
$ docker history 3900abf41552
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
3900abf41552   5 months ago   /bin/sh -c #(nop)  CMD ["redis-server"]         0B        
<missing>      5 months ago   /bin/sh -c #(nop)  EXPOSE 6379                  0B        
<missing>      5 months ago   /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B        
<missing>      5 months ago   /bin/sh -c #(nop) COPY file:c48b97ea65422782…   377B      
<missing>      5 months ago   /bin/sh -c #(nop) WORKDIR /data                 0B        
<missing>      5 months ago   /bin/sh -c #(nop)  VOLUME [/data]               0B        
<missing>      5 months ago   /bin/sh -c mkdir /data && chown redis:redis …   0B        
<missing>      5 months ago   /bin/sh -c set -eux;   apk add --no-cache --…   25.5MB    
<missing>      5 months ago   /bin/sh -c #(nop)  ENV REDIS_DOWNLOAD_SHA=5b…   0B        
<missing>      5 months ago   /bin/sh -c #(nop)  ENV REDIS_DOWNLOAD_URL=ht…   0B        
<missing>      5 months ago   /bin/sh -c #(nop)  ENV REDIS_VERSION=6.2.6      0B        
<missing>      5 months ago   /bin/sh -c apk add --no-cache   'su-exec>=0.…   1.34MB    
<missing>      5 months ago   /bin/sh -c addgroup -S -g 1000 redis && addu…   4.7kB     
<missing>      5 months ago   /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      5 months ago   /bin/sh -c #(nop) ADD file:9233f6f2237d79659…   5.58MB    

说明:如上面示例,ADD, apk 命令会带来体积增长,CMD 命令并不占空间。

体积压缩方式

了解了镜像构建中体积增大的原因,那么就可以对症下药**:精简层数 精简每一层大小**。

精简层数的方法有如下几种:

1. RUN 指令合并 :指令合并是最简单也是最方便的降低镜像层数的方式。该操作节省空间的原理是在同一层中清理“缓存”和工具软件。

2. 多阶段构建 : 多阶段构建方法是官方打包镜像的最佳实践,它是将精简层数做到极致的方法。通俗点讲它是将打包镜像分成两个阶段,一个阶段用于开发,打包,该阶段包含构建 应用程序所需的所有内容;一个用于生产运行,该阶段只包含你的应用程序以及运行它所需的内容。这被称为“建造者模式”。两个阶段的关系有点像 JDK 和 JRE 的关系。使用多阶段构建肯定会降低镜像大小,但是瘦身的粒度和编程语言有关系,对编译型语言效果比较好,因为它去掉了编译环境中多余的依赖,直接使 用编译后的二进制文件或 jar 包。而对于解释型语言效果就不那么明显了。

精简每一层的方法有如下几种:

  • 使用合适的基础镜像 (首 选 alpine,体积通常较小)Alpine 是一个高度精简又包含了基本工具的轻量级 Linux 发行版,基础镜像只有 4.41M,各开发语言和框架都有基于 Alpine 制作的基础镜像,强烈推荐使用它。进阶可以尝试使用 scratch 和 busybox 镜像进行基础镜像的构建。
  • 删除 RUN 的缓存文件

Dockfile 最佳实践

  • 编写.dockerignore 文件
  • 一个容器只运行单个应用
  • 基础镜像和生产镜像的标签不要使用 latest
  • 设置 WORKDIR 和 CMD
  • 使用 ENTRYPOINT,并用 exec 启动命令(可选)
  • 相比 ADD,优先使用 COPY
  • 设置默认的环境变量,映射端口和数据卷
  • 使用 LABEL 设置镜像元数据
  • 添加 HEALTHCHECK

小结

  • 多使用 Dockerfile 生成新镜像,减少 commit 方式生成的镜像。每 commit 一次相当于在原有基础镜像上再增加内容(因为 docker 文件系统为 overlay,删除的文件目录仍会占用存储空间)。

本章参考

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文