当前位置: 首页 > news >正文

【Docker知识】Docker进阶-容器镜像深度解读

文章目录

    • 概述
    • 底层工作原理
    • 🔍 如何查看Docker镜像的层次结构?
    • 🤔 如何优化Docker镜像以减少镜像大小?
    • 相关命令行
    • 相关文献

概述

Docker 镜像(Image)是 Docker 容器(Container)运行的基础,它包含了运行容器所需的所有内容——代码、运行时、库、环境变量和配置文件。以下是 Docker 镜像的详细说明:

docker-layers

  1. 镜像层(Image Layers)
    Docker 镜像由多个层组成,每一层代表 Dockerfile 中的一个指令。这些层是只读的,并且当多个镜像共享相同的底层时,Docker 会共享这些层以节省空间。

  2. 镜像大小
    由于镜像由多个层组成,可以使用 docker history 命令来查看每一层的大小,从而优化 Dockerfile 以减小镜像大小。

  3. 基础镜像(Base Image)
    基础镜像是构建新镜像的起点。通常,基础镜像包含操作系统和必要的运行时环境。例如,ubuntualpinenginx 等都是常见的基础镜像。

  4. Dockerfile
    Dockerfile 是一个文本文件,包含了一条条指令,每条指令都会创建一个新的镜像层。通过 docker build 命令根据 Dockerfile 创建新的镜像。

  5. 标签(Tags)
    镜像可以通过标签(tag)来标识不同的版本或环境。如果不指定标签,Docker 会默认使用 latest 标签。标签可以帮助用户区分和管理不同版本的镜像。

  6. 仓库(Repository)
    Docker 镜像通常存储在仓库中,可以是 Docker Hub、GitHub Container Registry、Google Container Registry 或私有仓库。仓库中可以包含多个具有不同标签的镜像。

  7. 推送和拉取镜像
    使用 docker push 命令将本地镜像推送到远程仓库,使用 docker pull 命令从远程仓库拉取镜像到本地。

  8. 轻量级镜像
    轻量级镜像(如基于 Alpine Linux)通常更小,启动更快,但可能不包含某些依赖或工具。选择合适的基础镜像对于优化容器的性能和安全性至关重要。

  9. 多阶段构建
    Dockerfile 支持多阶段构建,允许在构建过程中使用多个 FROM 指令。这有助于减小最终镜像的大小,因为只有最终阶段的Artifacts会被保留在最终镜像中。

  10. 镜像构建上下文(Build Context)
    在构建镜像时,Docker 需要一个上下文(Context),通常是包含 Dockerfile 的目录。上下文中的所有文件都可以通过 Dockerfile 中的 COPY 指令被复制到镜像中。

  11. 缓存
    Docker 镜像构建过程中,每条指令都会检查是否有可用的缓存层。如果上一层的指令没有变化,Docker 会重用之前的缓存层,这可以显著加快构建速度。

  12. 安全
    镜像应该尽可能安全,避免包含不必要的软件包或依赖,以减少潜在的安全风险。定期更新和扫描镜像以确保没有已知的漏洞。

  13. 镜像签名
    为了确保镜像的完整性和来源,可以使用 Docker Content Trust(DCT)对镜像进行签名。这允许在部署容器之前验证镜像的签名。

  14. 自定义镜像
    用户可以根据自己的需求创建自定义镜像,例如,包含特定的应用程序、服务或工具集。

Docker 镜像是容器化技术的核心,理解镜像的构建、存储和分发对于有效地使用 Docker 至关重要。

底层工作原理

Docker 镜像的底层原理主要基于联合文件系统(Union File System)和镜像分层(Layered Image)的概念。以下是 Docker 镜像底层原理的详细说明:

  1. 联合文件系统(UnionFS)
    Docker 使用联合文件系统来构建镜像。UnionFS 允许将多个文件系统叠加在一起,对外表现为一个统一的文件系统。这意味着可以创建一个轻量级的、可写的文件系统,它包含了来自不同层的文件和目录。在 Docker 中,每个镜像层都是只读的,而容器层是可写的,位于所有只读镜像层的顶部。这种设计使得多个容器可以共享相同的镜像层,同时拥有自己的可写层,实现资源的高度共享和隔离 。

  2. 镜像分层(Layered Image)
    Docker 镜像由一系列层组成,每一层代表 Dockerfile 中的一个指令。这些层是只读的,并且当多个镜像共享相同的底层时,Docker 会共享这些层以节省空间。当对镜像进行修改或增加新的内容时,就会在当前镜像层上创建新的镜像层。这种分层结构不仅使得镜像轻量级,而且启动容器时非常快速,因为只需加载少量的增量层即可 。

  3. Copy-on-Write(COW)机制
    Docker 镜像采用 Copy-on-Write 机制,这意味着当需要修改文件时,才会将文件从只读层复制到可写层(容器层),并进行修改。这种机制最大限度地减少了 I/O 和每个后续层的大小。删除操作则通过创建一个特殊的 whiteout 文件来实现,这个 whiteout 文件覆盖的文件即表示删除了 。

  4. 基础镜像(Base Image)
    基础镜像是不依赖其他任何镜像,完全从零开始构建的镜像。其他镜像都建立在基础镜像之上,可以比喻为大楼的地基。基础镜像通常包含操作系统的最小安装,如 Ubuntu、Debian、CentOS 等 。

  5. BootFS 和 RootFS
    Docker 镜像包含两个重要的文件系统:BootFS 和 RootFS。BootFS 包含 bootloader 和 kernel,负责系统的启动。RootFS 则是操作系统的根文件系统,包含典型的 Linux 系统目录,如 /dev、/proc、/bin 等 。

  6. 容器层(Container Layer)
    当创建一个新的容器时,Docker 会在镜像层之上添加一个新的可写层,称为容器层。对容器所做的所有更改,如添加、修改或删除文件,都发生在这个可写层上 。

  7. 镜像的不可变性
    Docker 镜像是不可变的,这意味着一旦创建,它们的文件和设置就不能被更改。当需要更新镜像时,必须创建一个新的镜像层,这有助于保持容器的一致性和可预测性 。

通过这些底层原理,Docker 镜像能够实现高效的资源共享、快速的容器启动和灵活的容器管理。这些特性使得 Docker 成为容器化应用部署和管理的强大工具。

🔍 如何查看Docker镜像的层次结构?

要查看 Docker 镜像的层次结构,可以使用以下几种方法:

  1. Docker History 命令
    docker history 命令可以显示镜像的构建历史,包括每一层的元数据和大小。每一层代表了 Dockerfile 中的一个指令。

    docker history [OPTIONS] IMAGE
    

    例如,查看名为 myimage 的镜像的层次结构:

    docker history myimage
    
  2. Docker Inspect 命令
    docker inspect 命令可以显示镜像或容器的详细配置信息,包括其层次结构。

    docker inspect [OPTIONS] NAME|ID
    

    要查看镜像的层次结构,可以查找 RootFS 部分中的 Layers 数组,它包含了镜像中所有层的列表。

    docker inspect myimage
    

    然后,你可以使用 jq 工具或其他方法来解析 JSON 输出,并提取 Layers 部分。

  3. Dockerfile
    如果你有 Dockerfile,可以通过查看 Dockerfile 中的指令来理解镜像的层次结构。每个指令通常对应于一个层。

  4. 图形化工具
    有些图形化 Docker 管理工具,如 Portainer、Docker UI 等,提供了可视化界面来展示镜像的层次结构。

  5. Docker Layers 命令(不推荐)
    在旧版本的 Docker 中,有一个 docker layers 命令可以直接查看镜像的层。但这个命令在 Docker 19.03 之后的版本中被移除了,取而代之的是 docker history

请注意,镜像的层次结构是由其构建过程决定的,每个层都是只读的,并且当镜像被分发到不同的 Docker 主机时,这些层会被共享。

🤔 如何优化Docker镜像以减少镜像大小?

要优化 Docker 镜像以减少其大小,可以采用以下方法:

  1. 多阶段构建(Multi-stage builds)
    在 Docker 17.05 版本之后引入的功能,允许在一个 Dockerfile 中使用多个 FROM 语句,每个 FROM 可以看作是新阶段的开始。这样可以在最终镜像中只包含必要的构建产物,从而减小镜像大小。例如,在构建 Java 应用时,可以使用 Maven 构建应用,但最终运行时只需要 JRE 环境,多阶段构建可以在最终镜像中排除 Maven 相关的层 。

  2. 优化 Dockerfile
    使用更小的基础镜像,如 Alpine Linux,它通常只有几兆大小。合并 RUN 命令以减少层的数量,并在构建过程结束后清理不必要的缓存和文件 。

  3. 使用 .dockerignore 文件
    类似于 .gitignore.dockerignore 文件可以指定在构建镜像时不需要添加到上下文的文件和目录,从而避免不必要的文件被复制到镜像中,减少镜像大小 。

  4. 使用 squash 参数
    Docker build 命令的 squash 选项可以将所有的 Docker 层合并为一个层,从而创建一个更小的镜像。需要注意的是,这个选项需要 Docker daemon 开启 experimental 特性才可使用 。

  5. 使用 docker-squash 工具
    docker-squash 是一个工具,可以压缩镜像的最后 n 层,从而减小镜像大小 。

  6. 使用 docker-slim 工具
    docker-slim 是一个可以帮助自动优化和减小 Docker 镜像的工具。它通过分析 Docker 镜像,自动压缩和优化,使镜像更小更安全 。

  7. 使用 docker export/import
    docker exportdocker import 命令可以用来备份和恢复容器,但也可以用来进行镜像压缩,因为导出再导入后,相当于删除了镜像中的所有叠加层,只保留最后的效果 。

  8. 最小化镜像层
    在 Dockerfile 中,每个 FROMRUNCOPY 命令都会创建一个单独的层。通过在单个 RUNCOPY 指令中执行多个命令来最小化 Dockerfile 中的层数,可以减少镜像的整体大小和构建时间 。

  9. 使用较小的基础镜像
    选择较小的基础镜像,如 python:3.9-slimalpine 版本,可以显著减小最终镜像的大小 。

  10. 安装后删除软件包
    如果需要在 Docker 镜像中安装一些包,并且在安装后不再需要这些包,那么最好在安装后删除这些包,以减少镜像大小 。

通过这些方法,可以有效地减小 Docker 镜像的大小,提高部署速度和运行效率。

相关命令行

Docker 提供了一系列命令行工具来管理和操作镜像。以下是一些常用的 Docker 镜像相关命令:

  1. 构建镜像

    docker build [OPTIONS] PATH | URL | -
    

    例如,从当前目录下的 Dockerfile 构建镜像:

    docker build -t myimage .
    
  2. 列出镜像

    docker image ls [OPTIONS]
    

    或者使用 docker images

    docker images
    
  3. 搜索镜像

    docker search [OPTIONS] TERM
    

    例如,在 Docker Hub 上搜索 nginx 镜像:

    docker search nginx
    
  4. 拉取镜像

    docker pull [OPTIONS] NAME[:TAG|@DIGEST]
    

    例如,拉取 nginx 的最新版本镜像:

    docker pull nginx:latest
    
  5. 推送镜像

    docker push [OPTIONS] NAME[:TAG]
    

    例如,推送一个标记为 latest 的镜像到 Docker Hub:

    docker push myimage:latest
    
  6. 运行镜像

    docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
    

    例如,运行一个 nginx 容器:

    docker run -d -p 80:80 nginx
    
  7. 停止容器

    docker stop [OPTIONS] CONTAINER [CONTAINER...]
    

    例如,停止一个 nginx 容器:

    docker stop mynginx
    
  8. 删除镜像

    docker rmi [OPTIONS] IMAGE [IMAGE...]
    

    例如,删除一个名为 myimage 的镜像:

    docker rmi myimage
    
  9. 清理镜像

    docker image prune [OPTIONS]
    

    例如,清理所有未使用的镜像:

    docker image prune -a
    
  10. 检查镜像信息

    docker inspect [OPTIONS] NAME|ID [NAME|ID...]
    

    例如,检查一个 nginx 镜像的详细信息:

    docker inspect nginx
    
  11. 导出镜像

    docker save [OPTIONS] NAME[:TAG|@DIGEST]
    

    例如,导出一个 nginx 镜像为 tar 文件:

    docker save -o nginx.tar nginx:latest
    
  12. 导入镜像

    docker load [OPTIONS]
    

    例如,从 tar 文件导入镜像:

    docker load -i nginx.tar
    
  13. 登录到仓库

    docker login [OPTIONS] [SERVER]
    

    例如,登录到 Docker Hub:

    docker login
    
  14. 注销仓库

    docker logout [SERVER]
    

    例如,从 Docker Hub 注销:

    docker logout
    
  15. 创建镜像仓库的镜像列表

    docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
    

    例如,创建一个 nginx 容器但不启动它:

    docker create --name mynginx nginx
    

这些命令是 Docker 镜像管理的基础,通过它们可以完成镜像的构建、推送、拉取、运行、停止、删除等操作。

相关文献

【云原生技术】Docker原理以及常用命令行
【云原生技术】Docker基础知识-docker0网桥
【云原生技术】Docker容器进阶知识


http://www.mrgr.cn/news/62394.html

相关文章:

  • 江协科技STM32学习- P25 UART串口协议
  • 泷羽sec-安全见闻(9)
  • python的lambda实用技巧
  • 江协科技STM32学习- P24 DMA数据转运DMA+AD多通道
  • VMware USB服务导致主机USB设备加载驱动异常
  • 爬虫利器playwright
  • AIGC学习笔记(4)——AI大模型开发工程师
  • 高效集成:SQLServer对接MySQL的实战案例
  • NR 5G 系统信息深度解析
  • 使用python提取日志里面的role_id、vip字段的值,(vip字段可能为空或者缺失,此时需要给默认值0):
  • 个人在ssm框架整合时犯的错误
  • 只尊重不教育,只筛选不改变
  • Threejs渲染3D字体介绍
  • gradio RuntimeError: async generator raised StopAsyncIteration
  • 阿里巴巴API返回值全解析:轻松掌握1688店铺商品信息
  • 【系统设计】高效的分布式系统:使用 Spring Boot 和 Kafka 实现 Saga 模式
  • SAP ABAP开发学习——第一代增强(包含增强演示)
  • BOE(京东方)2024年前三季度净利润三位数增长 “屏之物联”引领企业高质发展
  • java-数据结构
  • C++学习:类和对象(二)
  • AI时代,哪种人更被需要?
  • 【传知代码】自动化细胞核分割与特征分析
  • flowable7.1.0功能
  • 单例 C++ 懒汉+恶汉
  • 前端面试题21 | 了解过媒体查询吗?它有哪些应用场景?
  • 《JVM第4课》程序计数器