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

【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.kler.cn/a/372796.html

相关文章:

  • 电科金仓(人大金仓)更新授权文件(致命错误: XX000: License file expired.)
  • HT7178 带输出关断的20V,14A全集成同步升压转换器
  • 【商汤科技-注册/登录安全分析报告】
  • Linux——— 信号
  • CSP/信奥赛C++刷题训练:经典前缀和例题(4):洛谷P3662:Why Did the Cow Cross the Road II S
  • 在IDEA中运行Mybatis后发现取出的password值为null
  • SQL 高级技巧
  • BERT的中文问答系统23
  • 使用Virtual Audio Cable捕获系统音频输出并使用Python处理
  • pc电脑屏幕分辨率尺寸
  • MetaArena推出《Final Glory》:引领Web3游戏技术新风向
  • Flutter鸿蒙next 封装对话框详解
  • 实现链式结构的二叉树
  • C++ 之 VS2010 和MySQL数据库的链接问题
  • 【K8S系列】Kubernetes 中 Service 无法访问及解决方案【已解决】
  • 单片机如何入门?
  • Android adb命令获取设备id
  • CentOS 9 Stream 上安装 Visual Studio Code
  • Go语言八股(Ⅲ)
  • C#与C++交互开发系列(十四):C++中STL容器与C#集合传递的形式
  • lvm故障小贴士
  • 响应报文时间
  • CPB数据集:由斯坦福大学发布,一个新的视频问题回答任务基准,能够连续且全面处理视频数据
  • Golang | Leetcode Golang题解之第521题最长特殊序列I
  • C#与C++交互开发系列(十七):线程安全
  • 查询windows或者linux上 支持的所有字体